From 5f5d2b059dfde2f49cb8339909a649321b235a7c Mon Sep 17 00:00:00 2001 From: Tomas Dado <tomas.dado@cern.ch> Date: Mon, 26 Oct 2020 10:23:12 +0100 Subject: [PATCH 01/12] Removed TopFakes --- .../TopPhys/xAOD/TopFakes/CMakeLists.txt | 35 - .../xAOD/TopFakes/Root/FakesWeights.cxx | 596 ------------ .../TopPhys/xAOD/TopFakes/Root/LinkDef.h | 37 - .../TopPhys/xAOD/TopFakes/Root/MMEffSet.cxx | 508 ---------- .../xAOD/TopFakes/Root/MMEfficiency.cxx | 313 ------- .../xAOD/TopFakes/Root/MatrixUtils.cxx | 486 ---------- .../Root/TopFakesMMWeightCalculator.cxx | 864 ------------------ .../xAOD/TopFakes/Root/TopFakesxAODUtils.cxx | 363 -------- .../xAOD/TopFakes/TopFakes/FakesWeights.h | 169 ---- .../TopPhys/xAOD/TopFakes/TopFakes/MMEffSet.h | 181 ---- .../xAOD/TopFakes/TopFakes/MMEfficiency.h | 67 -- .../xAOD/TopFakes/TopFakes/MatrixUtils.h | 71 -- .../TopFakes/TopFakesMMWeightCalculator.h | 88 -- .../TopFakes/TopFakes/TopFakesxAODUtils.h | 105 --- .../xAOD/TopFakes/cmt/Makefile.Standalone | 129 --- .../data/20p1/Standard/F_el_Default.root | Bin 65386 -> 0 bytes .../20p1/Standard/F_el_Default_CRfake.root | Bin 65796 -> 0 bytes .../20p1/Standard/F_el_Default_MCdown.root | Bin 65296 -> 0 bytes .../data/20p1/Standard/F_el_Default_MCup.root | Bin 65382 -> 0 bytes .../data/20p1/Standard/F_el_Default_WZMG.root | Bin 65394 -> 0 bytes .../20p1/Standard/F_el_Default_WZPowheg.root | Bin 65343 -> 0 bytes .../data/20p1/Standard/R_el_Default.root | Bin 24217 -> 0 bytes .../20p1/Standard/R_el_Default_CRreal.root | Bin 66481 -> 0 bytes .../20p1/Standard/R_el_Default_TPNoCorr.root | Bin 24246 -> 0 bytes .../data/20p1/Standard/R_mu_Default.root | Bin 67144 -> 0 bytes .../data/20p7/2015/F_el_2015Test.root | Bin 11087 -> 0 bytes .../data/20p7/2015/F_mu_2015Test.root | Bin 11085 -> 0 bytes .../data/20p7/2015/R_el_2015Test.root | Bin 12737 -> 0 bytes .../data/20p7/2015/R_mu_2015Test.root | Bin 12727 -> 0 bytes .../data/20p7/2016/F_el_2016Test.root | Bin 11092 -> 0 bytes .../data/20p7/2016/F_mu_2016Test.root | Bin 11103 -> 0 bytes .../data/20p7/2016/R_el_2016Test.root | Bin 12747 -> 0 bytes .../data/20p7/2016/R_mu_2016Test.root | Bin 12765 -> 0 bytes .../data/20p7/PS2016/F_el_2016PSTest.root | Bin 11102 -> 0 bytes .../data/20p7/PS2016/F_mu_2016PSTest.root | Bin 11117 -> 0 bytes .../data/20p7/PS2016/R_el_2016PSTest.root | Bin 12784 -> 0 bytes .../data/20p7/PS2016/R_mu_2016PSTest.root | Bin 12770 -> 0 bytes .../F_el_Nedaa2015_2412-fakesStd.root | Bin 76239 -> 0 bytes .../Standard/R_el_Fred2015_2412-fakesStd.root | Bin 92915 -> 0 bytes .../R_el_Fred2016_2412-fakesStdNoTTVA.root | Bin 98333 -> 0 bytes .../R_el_Nedaa2015_2412-fakesStd.root | Bin 92968 -> 0 bytes .../R_el_Nedaa2016_2412-fakesStd.root | Bin 98356 -> 0 bytes .../Standard/R_mu_Fred2015_2412-fakesStd.root | Bin 70352 -> 0 bytes .../R_mu_Fred2016_2412-fakesStdNoTTVA.root | Bin 64571 -> 0 bytes .../R_mu_Nedaa2015_2412-fakesStd.root | Bin 70490 -> 0 bytes .../R_mu_Nedaa2016_2412-fakesStd.root | Bin 69012 -> 0 bytes .../F_el_Fred2015_AT2414-fakesOldOR_MCup.root | Bin 438 -> 0 bytes .../R_el_Fred2015_AT2414-fakesOldOR.root | Bin 92945 -> 0 bytes .../R_el_Fred2016_AT2414-fakesOldOR.root | Bin 98221 -> 0 bytes .../R_mu_Fred2015_AT2414-fakesOldOR.root | Bin 70402 -> 0 bytes .../R_mu_Fred2016_AT2414-fakesOldOR.root | Bin 68930 -> 0 bytes .../TopPhys/xAOD/TopFakes/data/mainpage.h | 25 - .../xAOD/TopFakes/macros/AtlasExample.C | 224 ----- .../xAOD/TopFakes/macros/AtlasLabels.C | 129 --- .../xAOD/TopFakes/macros/AtlasLabels.h | 32 - .../TopPhys/xAOD/TopFakes/macros/AtlasStyle.C | 98 -- .../TopPhys/xAOD/TopFakes/macros/AtlasStyle.h | 25 - .../xAOD/TopFakes/macros/AtlasStyle.py | 5 - .../TopPhys/xAOD/TopFakes/macros/AtlasUtils.C | 330 ------- .../TopPhys/xAOD/TopFakes/macros/AtlasUtils.h | 42 - .../xAOD/TopFakes/macros/AtlasUtils.py | 5 - .../TopPhys/xAOD/TopFakes/macros/EffSummary.C | 595 ------------ .../xAOD/TopFakes/macros/FakeEffElec.C | 501 ---------- .../xAOD/TopFakes/macros/FakeEffMuon.C | 564 ------------ .../TopFakes/macros/RealEffElecHighEtmiss.C | 281 ------ .../xAOD/TopFakes/macros/RealEffElecTP.C | 246 ----- .../TopFakes/macros/RealEffElecTPHighETmiss.C | 243 ----- .../xAOD/TopFakes/macros/RealEffMuonHighMTW.C | 386 -------- .../xAOD/TopFakes/macros/RealEffMuonTP.C | 272 ------ .../TopFakes/macros/RealEffMuonTPHighMTW.C | 506 ---------- 70 files changed, 8521 deletions(-) delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/CMakeLists.txt delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/FakesWeights.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/LinkDef.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MMEffSet.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MMEfficiency.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MatrixUtils.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/TopFakesMMWeightCalculator.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/TopFakesxAODUtils.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/FakesWeights.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MMEffSet.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MMEfficiency.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MatrixUtils.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/TopFakesMMWeightCalculator.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/TopFakesxAODUtils.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/cmt/Makefile.Standalone delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_CRfake.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_MCdown.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_MCup.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_WZMG.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_WZPowheg.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default_CRreal.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default_TPNoCorr.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_mu_Default.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/F_el_2015Test.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/F_mu_2015Test.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/R_el_2015Test.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/R_mu_2015Test.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/F_el_2016Test.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/F_mu_2016Test.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/R_el_2016Test.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/R_mu_2016Test.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/F_el_2016PSTest.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/F_mu_2016PSTest.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/R_el_2016PSTest.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/R_mu_2016PSTest.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/F_el_Nedaa2015_2412-fakesStd.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Fred2015_2412-fakesStd.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Fred2016_2412-fakesStdNoTTVA.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Nedaa2015_2412-fakesStd.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Nedaa2016_2412-fakesStd.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Fred2015_2412-fakesStd.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Fred2016_2412-fakesStdNoTTVA.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Nedaa2015_2412-fakesStd.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Nedaa2016_2412-fakesStd.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/F_el_Fred2015_AT2414-fakesOldOR_MCup.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_el_Fred2015_AT2414-fakesOldOR.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_el_Fred2016_AT2414-fakesOldOR.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_mu_Fred2015_AT2414-fakesOldOR.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_mu_Fred2016_AT2414-fakesOldOR.root delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/mainpage.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasExample.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasLabels.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasLabels.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.py delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.py delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/EffSummary.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/FakeEffElec.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/FakeEffMuon.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecHighEtmiss.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecTP.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecTPHighETmiss.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonHighMTW.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonTP.C delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonTPHighMTW.C diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/CMakeLists.txt deleted file mode 100644 index 18c2a2477a83..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ - -# Declare the name of this package: -atlas_subdir( TopFakes ) - -# This package depends on other packages: -atlas_depends_on_subdirs( PUBLIC - TopEvent - TopConfiguration ) - -# This package uses ROOT: -find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO Math MathCore MathMore Graf Matrix ) - -# Generate a CINT dictionary source file: -set( _extraHeader ) -if( XAOD_STANDALONE ) - set( _extraHeader TopFakes/TopFakesMMWeightCalculator.h ) -endif() -atlas_add_root_dictionary( TopFakes _cintDictSource - ROOT_HEADERS ${_extraHeader} TopFakes/FakesWeights.h TopFakes/MMEffSet.h - TopFakes/MMEfficiency.h TopFakes/MatrixUtils.h Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) - -# Build a library that other components can link against: -atlas_add_library( TopFakes Root/*.cxx Root/*.h Root/*.icc - TopFakes/*.h TopFakes/*.icc TopFakes/*/*.h - TopFakes/*/*.icc ${_cintDictSource} - PUBLIC_HEADERS TopFakes - LINK_LIBRARIES TopEvent - TopConfiguration - ${ROOT_LIBRARIES} - INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) - -# Install data files from the package: -atlas_install_data( data/* ) - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/FakesWeights.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/FakesWeights.cxx deleted file mode 100644 index 5d5a3222c876..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/FakesWeights.cxx +++ /dev/null @@ -1,596 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -////////////////////////////////////////////////////////////////////// -// -// Author : -// Anna Henrichs <anna.henrichs@cern.ch> -// Michele Pinamonti <michele.pinamonti@cern.ch> -// Creation : -// Purpose : main method to retrieve event-by-event weights -// from the Matrix Method -// Updated : -// 2016-07-14 : TTP: replace _isRun1 by _period -// 2016-01-29 : FD: set _isRun1 = false -// set default weighter -// remove pt/dR variable, never used -// 2016-02-02 : FD update SetupWeighterDefault -// 2016-02-12 : SetupWeighterDefault : default do not use dPhi -////////////////////////////////////////////////////////////////////// - -#include "TopFakes/FakesWeights.h" -#include "TopFakes/MMEffSet.h" -#include "TopFakes/MMEfficiency.h" -#include "TopFakes/MatrixUtils.h" - -#include "TH1F.h" -#include "TH2F.h" -#include "TFile.h" -#include "TString.h" -#include "TObjString.h" -#include <cmath> -#include <iostream> - - -using namespace std; - -// CONSTRUCTOR -FakesWeights::FakesWeights() : _mmUtil(0) { - _channel = EJETS; - _dataPath = "data"; - _dataPathIsSet = false; - _isInitialized = false; - _debug = false; - - _period = MMEffSet::Period::Year2015; - _trig1_el = ""; - _trig2_el = ""; - _trig3_el = ""; - _trig1_mu = ""; - _trig2_mu = ""; - _trig3_mu = ""; - _ps1_el = 1; - _ps2_el = 1; - _ps3_el = 1; - _ps1_mu = 1; - _ps2_mu = 1; - _ps3_mu = 1; - _ptTres_el = 0; - _ptTres_mu = 0; - - for (int i = 0; i < 4; ++i) - _EffSet[i] = 0; -} - -// DESTRUCTOR -FakesWeights::~FakesWeights(){ - delete _mmUtil; - - for (int i = 0; i < 4; ++i) - delete _EffSet[i]; -} - -// =============================================== -void FakesWeights::SetDataPath(std::string path) { - // method to set the path were efficiencies are - _dataPath = path; - if(_isInitialized) for(int i=0;i<4;i++) _EffSet[i]->SetDataPath(path); - _dataPathIsSet = true; -} - -// =============================================== -void FakesWeights::SetDebug(bool debug){ - _debug = debug; -} - -// =============================================== -void FakesWeights::SetPeriod(int period){ - _period = period; -} - -// =============================================== -void FakesWeights::SetTriggerNamesEl(std::string trig1,std::string trig2,std::string trig3){ - _trig1_el = trig1; - _trig2_el = trig2; - _trig3_el = trig3; -} - -// =============================================== -void FakesWeights::SetTriggerNamesMu(std::string trig1,std::string trig2,std::string trig3){ - _trig1_mu = trig1; - _trig2_mu = trig2; - _trig3_mu = trig3; -} - -// =============================================== -void FakesWeights::SetTriggerPrescalesEl(float ps1,float ps2,float ps3){ - _ps1_el = ps1; - _ps2_el = ps2; - _ps3_el = ps3; -} - -// =============================================== -void FakesWeights::SetTriggerPrescalesMu(float ps1,float ps2,float ps3){ - _ps1_mu = ps1; - _ps2_mu = ps2; - _ps3_mu = ps3; -} - -// =============================================== -void FakesWeights::SetTriggerThresholdEl(float thres){ - _ptTres_el = thres; -} - -// =============================================== -void FakesWeights::SetTriggerThresholdMu(float thres){ - _ptTres_mu = thres; -} - -// =============================================== -void FakesWeights::SetupWeighter(int channel, std::string aReal, std::string aFake, std::string aReal2, std::string aFake2) { - // method to set up tools which calculate the weights - - std::cout << "--------------------------------------------------------" << std::endl; - std::cout << " FakesWeights::INFO: Setting-up Matrix Method Weighter." << std::endl; - if(channel==EJETS) std::cout << " channel: e+jets" << std::endl; - if(channel==MUJETS) std::cout << " channel: µ+jets" << std::endl; - if(channel==EE) std::cout << " channel: ee" << std::endl; - if(channel==MUMU) std::cout << " channel: µµ" << std::endl; - if(channel==EMU) std::cout << " channel: eµ" << std::endl; - if(channel==EMU){ - std::cout << " real eff(e): " << aReal << std::endl; - std::cout << " fake eff(e): " << aFake << std::endl; - std::cout << " real eff(µ): " << aReal2 << std::endl; - std::cout << " fake eff(µ): " << aFake2 << std::endl; - } - else{ - std::cout << " real eff: " << aReal << std::endl; - std::cout << " fake eff: " << aFake << std::endl; - } - std::cout << "--------------------------------------------------------" << std::endl; - _channel = channel; - _mmUtil = new MatrixUtils(); - _EffSet[0] = new MMEffSet(channel==EJETS || channel==EE || channel==EMU, true, _debug); // isEle, isReal - _EffSet[1] = new MMEffSet(channel==EJETS || channel==EE || channel==EMU, false, _debug); - _EffSet[2] = new MMEffSet(channel==EE, true, _debug); - _EffSet[3] = new MMEffSet(channel==EE, false, _debug); - for(int i=0;i<4;i++){ - _EffSet[i]->SetPeriod(_period); - } - if(_period!=MMEffSet::Period::Year2012){ - if(channel==EJETS || channel==EE || channel==EMU){ - _EffSet[0]->SetTriggerNames(_trig1_el,_trig2_el,_trig3_el); - _EffSet[1]->SetTriggerNames(_trig1_el,_trig2_el,_trig3_el); - _EffSet[0]->SetTriggerPrescales(_ps1_el,_ps2_el,_ps3_el); - _EffSet[1]->SetTriggerPrescales(_ps1_el,_ps2_el,_ps3_el); - _EffSet[0]->SetTriggerThreshold(_ptTres_el); - _EffSet[1]->SetTriggerThreshold(_ptTres_el); - } - else if(channel==MUJETS || channel==MUMU){ - _EffSet[0]->SetTriggerNames(_trig1_mu,_trig2_mu,_trig3_mu); - _EffSet[1]->SetTriggerNames(_trig1_mu,_trig2_mu,_trig3_mu); - _EffSet[0]->SetTriggerPrescales(_ps1_mu,_ps2_mu,_ps3_mu); - _EffSet[1]->SetTriggerPrescales(_ps1_mu,_ps2_mu,_ps3_mu); - _EffSet[0]->SetTriggerThreshold(_ptTres_mu); - _EffSet[1]->SetTriggerThreshold(_ptTres_mu); - } - if(channel==EE){ - _EffSet[2]->SetTriggerNames(_trig1_el,_trig2_el,_trig3_el); - _EffSet[3]->SetTriggerNames(_trig1_el,_trig2_el,_trig3_el); - _EffSet[2]->SetTriggerPrescales(_ps1_el,_ps2_el,_ps3_el); - _EffSet[3]->SetTriggerPrescales(_ps1_el,_ps2_el,_ps3_el); - _EffSet[2]->SetTriggerThreshold(_ptTres_el); - _EffSet[3]->SetTriggerThreshold(_ptTres_el); - } - else if(channel==MUMU || channel==EMU){ - _EffSet[2]->SetTriggerNames(_trig1_mu,_trig2_mu,_trig3_mu); - _EffSet[3]->SetTriggerNames(_trig1_mu,_trig2_mu,_trig3_mu); - _EffSet[2]->SetTriggerPrescales(_ps1_mu,_ps2_mu,_ps3_mu); - _EffSet[3]->SetTriggerPrescales(_ps1_mu,_ps2_mu,_ps3_mu); - _EffSet[2]->SetTriggerThreshold(_ptTres_mu); - _EffSet[3]->SetTriggerThreshold(_ptTres_mu); - } - } - _isInitialized = true; - // setup data path if already specified - if(_dataPathIsSet){ - if(_debug) std::cout << " --> Setting-up data-path = " << _dataPath << std::endl; - SetDataPath(_dataPath); - } - // setup firt lepton, for all the channels - _EffSet[0]->SetupEff(aReal); - _EffSet[1]->SetupEff(aFake); - // setup the second lepton in the same way as the first one for ee and µµ, but following aReal2/aFake2 for eµ - if(channel==EE || channel==EMU || channel==MUMU){ - if(aReal2!="") _EffSet[2]->SetupEff(aReal2); - else _EffSet[2]->SetupEff(aReal); - if(aFake2!="") _EffSet[3]->SetupEff(aFake2); - else _EffSet[3]->SetupEff(aFake); - } -} - -// ======================================================= -float FakesWeights::GetFakesWeightLJets(bool tight){ - // retrieve MM weight for semileptonic events - - float f = GetFakeEff(); // fake efficiency of lepton - float r = GetRealEff(); // real efficiency of lepton - if(f<0 || r<0) return 0.; // added for events which are neglected by trigger splitting - - double nf, nr; - // - float weight = _mmUtil->lepton_weight(!tight, r, f, (double&)nf, (double&)nr); - // protection against too large weights : this should not happen - // and is due in general to histo bins with large statistical fluctuations - if( weight > 5 || weight < -5 ){ - r = _EffSet[0]->GetEff(true); - f = _EffSet[1]->GetEff(true); - weight = _mmUtil->lepton_weight(!tight, r, f, (double&)nf, (double&)nr); - } - - // scale by prescales! FIXME - if(_EffSet[0]->GetPrescale()!=1) weight *= _EffSet[0]->GetPrescale(); - - return weight; -} - -// ======================================================= -float FakesWeights::GetFakesWeightDilep(bool tight1,bool tight2){ - // retrieve MM weight for dilepton events - - float f1 = GetFakeEff(); // fake efficiency of 1st lepton - float r1 = GetRealEff(); // real efficiency of 1st lepton - float f2 = GetFakeEff2(); // fake efficiency of 2nd lepton - float r2 = GetRealEff2(); // real efficiency of 2nd lepton - if(f1<0 || f2<0 || r1<0 || r2<0) return 0.; // added for events which are neglected by trigger splitting - - double nrf, nfr, nff; - // fill the 4*4 matrix with efficiencies - _mmUtil->fill_matrix(r1,f1,r2,f2); - // retrieve the weights - return _mmUtil->dilepton_weight(!tight1, r1, f1, !tight2, r2, f2, (double&)nrf, (double&)nfr, (double&)nff); -} - -// ======================================================= -float FakesWeights::GetFakesWeightDilepLL(bool tight1,bool tight2){ - // retrieve MM weight for dilepton events (loose-loose) - return _mmUtil->dilepton_LL_weight(!tight1,!tight2); -} - -// ======================================================= -float FakesWeights::GetFakesWeightDilepLT(bool tight1,bool tight2){ - // retrieve MM weight for dilepton events (loose-tight) - return _mmUtil->dilepton_LT_weight(!tight1,!tight2); -} - -// ======================================================= -float FakesWeights::GetFakesWeightDilepTL(bool tight1,bool tight2){ - // retrieve MM weight for dilepton events (tight-loose) - return _mmUtil->dilepton_TL_weight(!tight1,!tight2); -} - -// ======================================================= -float FakesWeights::GetFakesWeightDilepTT(bool tight1,bool tight2){ - // retrieve MM weight for dilepton events (tight-tight) - return _mmUtil->dilepton_TT_weight(!tight1,!tight2); -} - -// ======================================================= -float FakesWeights::GetRealEff(){ - // method to get the real efficiency - float R = _EffSet[0]->GetEff(); - return R; -} - -// ======================================================= -float FakesWeights::GetFakeEff(){ - // method to get the fake efficiency - float F = _EffSet[1]->GetEff(); - return F; -} - -// ======================================================= -float FakesWeights::GetRealEff2(){ - // method to get the real efficiency (of 2nd lepton) - float R = _EffSet[2]->GetEff(); - return R; -} - -// ======================================================= -float FakesWeights::GetFakeEff2(){ - // method to get the real efficiency (of 2nd lepton) - float F = _EffSet[3]->GetEff(); - return F; -} - -// ======================================================= -void FakesWeights::SetLepton(MMEvent event,MMLepton lepton){ - // set the MMEvent and MMLepton objects for l+jet case - _EffSet[0]->SetLepton(event,lepton); - _EffSet[1]->SetLepton(event,lepton); -} - -// ======================================================= -void FakesWeights::SetLeptons(MMEvent event,MMLepton lepton1,MMLepton lepton2){ - // set the MMEvent and MMLepton objects for dilepton case - - // hack by Finn & Xiaowen to treat the trigger bias in the correct way - // a. if any lepton in the event matches the high pt trigger - if( (lepton1.trigger&2)>0 || (lepton2.trigger&2)>0 ){ - // -- > apply pt dependent nonbiased efficiencies ( e.g. e24vh if pt<61 and e60 if pt>61 ) - // ~~ > hack: switch the biased trigger off ;) - if( (lepton1.trigger&1)>0 ) { - lepton1.trigger -= 1; - if( (lepton1.trigger&4)==0 ) lepton1.trigger += (1 << 2); - } - if( (lepton2.trigger&1)>0 ){ - lepton2.trigger -= 1; - if( (lepton2.trigger&4)==0 ) lepton2.trigger += (1 << 2); - } - } - // b. if no lepton in the event matches this trigger - else{ - // -- > apply the low pt biased trigger efficiency ( e24vhi ) to one lepton that matches this trigger and pt dependent unbiased efficiencies to the others ( e.g. e24vh if pt<61 and e60 if pt>61 ) - // -- > if more than one lepton matches e24vhi than apply that efficiency to the highest pt one and the unbiased e24vh to the other(s). - // ~~ > hack: if both leptons are matched to the biased trigger, switch off the trigger for the lowest pt one - if( (lepton1.trigger&1)>0 && (lepton2.trigger&1)>0 ){ - if( lepton1.pt > lepton2.pt ) lepton2.trigger -= 1; - if( lepton2.pt > lepton1.pt ) lepton1.trigger -= 1; - } - } - - _EffSet[0]->SetLepton(event,lepton1); - _EffSet[1]->SetLepton(event,lepton1); - _EffSet[2]->SetLepton(event,lepton2); - _EffSet[3]->SetLepton(event,lepton2); -} - -// ======================================================= -MatrixUtils* FakesWeights::GetMatrixUtils(){ - // retrieve the matrix - return _mmUtil; -} - -// ======================================================= -void FakesWeights::SetupWeighterDefault(int channel, std::string syst){ - // - // default set up - // - - // default efficiencies - if (syst=="") _syst = NONE; - // fake eff with removal of real lepton contamination from W/Z MC +30% - correlates electron and muon - else if(syst=="MCup") _syst = MCup; - // fake eff with removal of real lepton contamination from W/Z MC -30% - correlates electron and muon - else if(syst=="MCdown") _syst = MCdown; - // fake eff with removal of real lepton contamination from W/Z MC +30% - only for electron - else if(syst=="MCupel") _syst = MCupel; - // fake eff with removal of real lepton contamination from W/Z MC -30% - only for electron - else if(syst=="MCdownel") _syst = MCdownel; - // fake eff with removal of real lepton contamination from W/Z MC +30% - only for muon - else if(syst=="MCupmu") _syst = MCupmu; - // fake eff with removal of real lepton contamination from W/Z MC -30% - only for muon - else if(syst=="MCdownmu") _syst = MCdownmu; - // fake eff from alternative region - returns nominal for emu channel, otherwise equivalent to CRfakeel (CRfakemu) for e+jets and ee (mu+jets and mumu) channels - else if(syst=="CRfake") _syst = CRfake; - // fake eff from alternative region (only for electrons, useful for dilepton) - else if(syst=="CRfakeel") _syst = CRfakeel; - // fake eff from alternative region (only for muons, useful for dilepton) - else if(syst=="CRfakemu") _syst = CRfakemu; - // real eff from alternative region - correlates electron and muon - else if(syst=="CRreal") _syst = CRreal; - // real eff from alternative region - only for electron - else if(syst=="CRrealel") _syst = CRrealel; - // real eff from alternative region - only for muon - else if(syst=="CRrealmu") _syst = CRrealmu; - // efficiencies with alternative parametrisation (only for l+jet) - else if(syst=="EffPar") _syst = EffPar; - else { - std::cout << " FakesWeights::ERROR: Specified systematic NOT supported: " << syst << std::endl; - return; - } - - // E + JETS - if(channel == FakesWeights::EJETS){ - if(_syst==NONE) SetupWeighter( FakesWeights::EJETS, "Default:NS:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR"); - else if(_syst==MCup || _syst==MCupel) SetupWeighter( FakesWeights::EJETS, "Default:NS:eta:pt:jetpt:dR", "Default_MCup:NB/NS:eta:pt:jetpt:dR"); - else if(_syst==MCdown || _syst==MCdownel) SetupWeighter( FakesWeights::EJETS, "Default:NS:eta:pt:jetpt:dR", "Default_MCdown:NB/NS:eta:pt:jetpt:dR"); - else if(_syst==CRreal || _syst==CRrealel) SetupWeighter( FakesWeights::EJETS, "Default_CRreal:NB:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR"); - else if(_syst==CRfake || _syst==CRfakeel) SetupWeighter( FakesWeights::EJETS, "Default:NS:eta:pt:jetpt:dR", "Default_CRfake:NB/NS:eta:pt:jetpt:dR"); - else if(_syst==EffPar) SetupWeighter( FakesWeights::EJETS, "Default:NS:eta:pt:jetpt:dR:dPhi", "Default:NB/NS:eta:pt:jetpt:dR:dPhi"); - else if(_syst==MCupmu || _syst==MCdownmu || _syst==CRrealmu || _syst==CRfakemu ) { - std::cout << " FakesWeights::WARNING: Requested muon-specific systematic "<<syst<<" in e+jets channel - using nominal instead" << std::endl; - SetupWeighterDefault(FakesWeights::EJETS); - } - } - - // MU + JETS - else if(channel == FakesWeights::MUJETS){ - if(_syst==NONE) SetupWeighter( FakesWeights::MUJETS, "Default:NS/TR:eta:pt:jetpt:dR", "Default:NB/NS/TR:eta:pt:jetpt:dR"); - else if(_syst==MCup || _syst==MCupmu) SetupWeighter( FakesWeights::MUJETS, "Default:NS/TR:eta:pt:jetpt:dR", "Default_MCup:NB/NS/TR:eta:pt:jetpt:dR"); - else if(_syst==MCdown || _syst==MCdownmu) SetupWeighter( FakesWeights::MUJETS, "Default:NS/TR:eta:pt:jetpt:dR", "Default_MCdown:NB/NS/TR:eta:pt:jetpt:dR"); - else if(_syst==CRreal || _syst==CRrealmu) SetupWeighter( FakesWeights::MUJETS, "Default_CRreal:NB/TR:eta:pt:jetpt:dR","Default:NB/NS/TR:eta:pt:jetpt:dR"); - else if(_syst==CRfake || _syst==CRfakemu) SetupWeighter( FakesWeights::MUJETS, "Default:NS/TR:eta:pt:jetpt:dR", "Default_CRfake:NB/NS/TR:eta:pt:jetpt:dR"); - else if(_syst==EffPar) SetupWeighter( FakesWeights::MUJETS, "Default:NS/TR:eta:pt:jetpt:dR:dPhi", "Default:NB/NS/TR:eta:pt:jetpt:dR:dPhi"); - else if(_syst==MCupel || _syst==MCdownel || _syst==CRrealel || _syst==CRfakeel ) { - std::cout << " FakesWeights::WARNING: Requested electron-specific systematic "<<syst<<" in mu+jets channel - using nominal instead" << std::endl; - SetupWeighterDefault(FakesWeights::MUJETS); - } - } - - // E E - else if(channel == FakesWeights::EE){ - if(_syst==NONE) SetupWeighter( FakesWeights::EE, "Default:NS:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR"); - else if (_syst==MCup || _syst==MCupel) SetupWeighter( FakesWeights::EE, "Default:NS:eta:pt:jetpt:dR", "Default_MCup:NB/NS:eta:pt:jetpt:dR"); - else if (_syst==MCdown || _syst==MCdownel) SetupWeighter( FakesWeights::EE, "Default:NS:eta:pt:jetpt:dR", "Default_MCdown:NB/NS:eta:pt:jetpt:dR"); - else if (_syst==CRreal || _syst==CRrealel) SetupWeighter( FakesWeights::EE, "Default_CRreal:NB/TR:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR"); - else if (_syst==CRfake || _syst==CRfakeel) SetupWeighter( FakesWeights::EE, "Default:NS:eta:pt:jetpt:dR", "Default_CRfake:NB/NS:eta:pt:jetpt:dR"); - else if(_syst==EffPar) { - std::cout << " FakesWeights::WARNING: Requested systematic "<<syst<<" is not relevant for dilepton channel - using nominal instead" << std::endl; - SetupWeighterDefault(FakesWeights::EE); - } - else if(_syst==MCupmu || _syst==MCdownmu || _syst==CRrealmu || _syst==CRfakemu ) { - std::cout << " FakesWeights::WARNING: Requested muon-specific systematic "<<syst<<" in ee channel - using nominal instead" << std::endl; - SetupWeighterDefault(FakesWeights::EE); - } - } - - // MU MU - else if(channel == FakesWeights::MUMU){ - if(_syst==NONE) SetupWeighter( FakesWeights::MUMU, "Default:NS/TR:eta:pt:jetpt:dR", "Default:NB/NS/TR:eta:pt:jetpt:dR"); - else if (_syst==MCup || _syst==MCupmu) SetupWeighter( FakesWeights::MUMU, "Default:NS/TR:eta:pt:jetpt:dR", "Default_MCup:NB/NS/TR:eta:pt:jetpt:dR"); - else if (_syst==MCdown || _syst==MCdownmu) SetupWeighter( FakesWeights::MUMU, "Default:NS/TR:eta:pt:jetpt:dR", "Default_MCdown:NB/NS/TR:eta:pt:jetpt:dR"); - else if (_syst==CRreal || _syst==CRrealmu) SetupWeighter( FakesWeights::MUMU, "Default_CRreal:NB/TR:eta:pt:jetpt:dR", "Default:NB/NS/TR:eta:pt:jetpt:dR"); - else if (_syst==CRfake || _syst==CRfakemu) SetupWeighter( FakesWeights::MUMU, "Default:NS/TR:eta:pt:jetpt:dR", "Default_CRfake:NB/NS/TR:eta:pt:jetpt:dR"); - else if(_syst==EffPar) { - std::cout << " FakesWeights::WARNING: Requested systematic "<<syst<<" is not relevant for dilepton channel - using nominal instead" << std::endl; - SetupWeighterDefault(FakesWeights::MUMU); - } - else if(_syst==MCupel || _syst==MCdownel || _syst==CRrealel || _syst==CRfakeel ) { - std::cout << " FakesWeights::WARNING: Requested electron-specific systematic "<<syst<<" in mumu channel - using nominal instead" << std::endl; - SetupWeighterDefault(FakesWeights::MUMU); - } - } - - // E MU - else if(channel == FakesWeights::EMU){ - if(_syst==NONE) { - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==MCup) { - std::cout << " FakesWeights::WARNING: Requested systematic MCup in emu channel will consider this variation totally correlated between the electron and the muon" << std::endl; - std::cout << " FakesWeights::WARNING: Please use MCupel and MCupmu to get the systematic variation only for electron and muon, respectively" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default_MCup:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default_MCup:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==MCdown) { - std::cout << " FakesWeights::WARNING: Requested systematic MCdown in emu channel will consider this variation totally correlated between the electron and the muon" << std::endl; - std::cout << " FakesWeights::WARNING: Please use MCdownel and MCdownmu to get the systematic variation only for electron and muon, respectively" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default_MCdown:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default_MCdown:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==MCupel) { - std::cout << " FakesWeights::WARNING: Requested systematic MCupel in emu channel will consider this variation only for the electron" << std::endl; - std::cout << " FakesWeights::WARNING: Please use MCup instead to get this systematic variation for both electron and muon totally correlated" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default_MCup:NB/NS:eta:pt:jetpt:dR", - "Default:NS:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR"); - } - else if (_syst==MCdownel) { - std::cout << " FakesWeights::WARNING: Requested systematic MCdownel in emu channel will consider this variation only for the electron" << std::endl; - std::cout << " FakesWeights::WARNING: Please use MCdown instead to get this systematic variation for both electron and muon totally correlated" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default_MCdown:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==MCupmu) { - std::cout << " FakesWeights::WARNING: Requested systematic MCupmu in emu channel will consider this variation only for the muon" << std::endl; - std::cout << " FakesWeights::WARNING: Please use MCup instead to get this systematic variation for both electron and muon totally correlated" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default_MCup:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==MCdownmu) { - std::cout << " FakesWeights::WARNING: Requested systematic MCdownmu in emu channel will consider this variation only for the muon" << std::endl; - std::cout << " FakesWeights::WARNING: Please use MCdown instead to get this systematic variation for both electron and muon totally correlated" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default_MCdown:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==CRfake) { - std::cout << " FakesWeights::WARNING: Requested systematic CRfake in emu channel is not possible - using nominal instead" << std::endl; - std::cout << " FakesWeights::WARNING: Please use CRfakeel and CRfakemu to get the systematic variation only for electron and muon, respectively" << std::endl; - SetupWeighterDefault(FakesWeights::EMU); - } - else if (_syst==CRfakeel) { - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default_CRfake:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==CRfakemu) { - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default_CRfake:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==CRreal) { - std::cout << " FakesWeights::WARNING: Requested systematic CRreal in emu channel will consider this variation totally correlated between the electron and the muon" << std::endl; - std::cout << " FakesWeights::WARNING: Please use CRrealel and CRrealmu to get the systematic variation only for electron and muon, respectively" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default_CRreal:NB/TR:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR", - "Default_CRreal:NB/TR:eta:pt:jetpt:dR","Default:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==CRrealel) { - std::cout << " FakesWeights::WARNING: Requested systematic CRrealel in emu channel will consider this variation only for the electron" << std::endl; - std::cout << " FakesWeights::WARNING: Please use CRreal instead to get this systematic variation for both electron and muon totally correlated" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default_CRreal:NB/TR:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR", - "Default:NS/TR:eta:pt:jetpt:dR", "Default:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if (_syst==CRrealmu) { - std::cout << " FakesWeights::WARNING: Requested systematic CRrealmu in emu channel will consider this variation only for the muon" << std::endl; - std::cout << " FakesWeights::WARNING: Please use CRreal instead to get this systematic variation for both electron and muon totally correlated" << std::endl; - SetupWeighter( FakesWeights::EMU, - "Default:NS:eta:pt:jetpt:dR", "Default:NB/NS:eta:pt:jetpt:dR", - "Default_CRreal:NB/TR:eta:pt:jetpt:dR","Default:NB/NS/TR:eta:pt:jetpt:dR"); - } - else if(_syst==EffPar) { - std::cout << " FakesWeights::WARNING: Requested systematic "<<syst<<" is not relevant for dilepton channel - using nominal instead" << std::endl; - SetupWeighterDefault(FakesWeights::EMU); - } - } - else std::cout << "ERROR: Unsupported channel number: " << channel << std::endl; -} - -// ======================================================= -// for backward compatibility -void FakesWeights::SetupWeighterDefault(int channel,std::string name,std::string syst){ - std::cout << " FakesWeights::INFO: Specifying " << name << " not needed anymore." << std::endl; - SetupWeighterDefault(channel,syst); -} - -// ======================================================= -void FakesWeights::SetLeptonDefault(float lep_pt, float lep_eta, - float el_cl_eta, float dR_lj_min, - float dPhi_lnu, float jet_pt0, - int jet_n, int nJet_tagged, int trigger) -{ - // - // default method to setup MMLepton and MMEvent objects - // - - // turn eta's into abs value, just to be sure - lep_eta = TMath::Abs(lep_eta); - el_cl_eta = TMath::Abs(el_cl_eta); - // - MMLepton lepton; - lepton.pt = lep_pt; - lepton.eta = lep_eta; - lepton.cleta = el_cl_eta; - lepton.dR = dR_lj_min; - lepton.dPhi = dPhi_lnu; // NEW!! - lepton.trigger = trigger; - MMEvent event; - event.njets = jet_n; - event.ntag = nJet_tagged; - event.jetpt = jet_pt0; - SetLepton(event,lepton); -} - -// ======================================================= -float FakesWeights::GetFakesWeightLJetsDefault(bool tight, float lep_pt, - float lep_eta, float el_cl_eta, - float dR_lj_min, - float dPhi_lnu, // NEW!! - float jet_pt0, int jet_n, - int nJet_tagged, int trigger) -{ - - SetLeptonDefault(lep_pt,lep_eta,el_cl_eta,dR_lj_min,dPhi_lnu, - jet_pt0,jet_n,nJet_tagged,trigger); - return GetFakesWeightLJets(tight); -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/LinkDef.h deleted file mode 100644 index fd03d0685a9a..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/LinkDef.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef STANDALONE//for standalone compilation only -#include "TopFakes/TopFakesMMWeightCalculator.h" -#endif -#include "TopFakes/FakesWeights.h" -#include "TopFakes/MMEffSet.h" -#include "TopFakes/MMEfficiency.h" -#include "TopFakes/MatrixUtils.h" - -#ifdef __CINT__ - -#ifndef STANDALONE//for standalone compilation only -#pragma extra_include "TopFakes/TopFakesMMWeightCalculator.h"; -#endif -#pragma extra_include "TopFakes/FakesWeights.h"; -#pragma extra_include "TopFakes/MMEffSet.h"; -#pragma extra_include "TopFakes/MMEfficiency.h"; -#pragma extra_include "TopFakes/MatrixUtils.h"; - -#pragma link off all globals; -#pragma link off all classes; -#pragma link off all functions; -#pragma link C++ nestedclass; - -//for loading the object selection at run time -#ifndef STANDALONE//for standalone compilation only -#pragma link C++ class top::TopFakesMMWeightCalculator+; -#endif -#pragma link C++ class FakesWeights+; -#pragma link C++ class MMEffSet+; -#pragma link C++ class MMEfficiency+; -#pragma link C++ class MatrixUtils+; - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MMEffSet.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MMEffSet.cxx deleted file mode 100644 index 7f2f01efd5d8..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MMEffSet.cxx +++ /dev/null @@ -1,508 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -////////////////////////////////////////////////////////////////////// -// -// Author : Michele Pinamonti <michele.pinamonti@cern.ch> -// Creation : -// Purpose : base class to set efficiencies for the matrix method -// Updated : -// 2016-01-29 : FD: set _isRun1 = false and set muon triggers for Run2 -////////////////////////////////////////////////////////////////////// - -#include "TopFakes/MMEffSet.h" -#include "TopFakes/MMEfficiency.h" -#include "TopFakes/MatrixUtils.h" - -#include "TH1F.h" -#include "TH2F.h" -#include "TFile.h" -#include "TString.h" -#include "TObjString.h" -#include <cmath> -#include <iostream> - -using namespace std; - -MMEffSet::MMEffSet(bool isEle, bool isReal, bool debug) { - _Estimate = ""; - _dataPath = "data"; - _isEle = isEle; - _isReal = isReal; - _effIsRead = false; - _useCorr = false; - _numCond = 0; - _splitBitMask = 0; - _debug = debug; - _period = Period::Year2015; - _ptTres = 0; - _trig1 = ""; - _trig2 = ""; - _trig3 = ""; - _trigger = -100; - - for (int i = 0; i < 10; ++i) { - _Eff[i] = 0; - _EffCorr[i] = 0; - } -} - -MMEffSet::~MMEffSet(){ - for (int i = 0; i < 10; ++i) { - delete _Eff[i]; - delete _EffCorr[i]; - } -} - -void MMEffSet::SetupEff(std::string aEff){ - _Estimate = aEff; - ParseOptions(_Estimate,&_optMap); - if(_optMap["Conditions"]=="x"){ // if x is there as condition, wait before initializing - if(_debug) std::cout << "Custom conditions. Not setting up efficiencies yet." << std::endl; - return; - } - else if(_optMap["Conditions"].find("NB/NS/TR")!=std::string::npos) AddNumBtagAndNumJetsShortAndTriggerSplit(); - else if(_optMap["Conditions"].find("NB/NJ/TR")!=std::string::npos) AddNumBtagAndNumJetsAndTriggerSplit(); - else if(_optMap["Conditions"].find("NB/NS")!=std::string::npos) AddNumBtagAndNumJetsShortSplit(); - else if(_optMap["Conditions"].find("NB/NJ")!=std::string::npos) AddNumBtagAndNumJetsSplit(); - else if(_optMap["Conditions"].find("NB/TR")!=std::string::npos) AddNumBtagAndTriggerSplit(); - else if(_optMap["Conditions"].find("NS/TR")!=std::string::npos) AddNumJetsShortAndTriggerSplit(); - else if(_optMap["Conditions"].find("NJ/TR")!=std::string::npos) AddNumJetsAndTriggerSplit(); - else if(_optMap["Conditions"].find("NB")!=std::string::npos) AddNumBtagSplit(); - else if(_optMap["Conditions"].find("NS")!=std::string::npos) AddNumJetsShortSplit(); - else if(_optMap["Conditions"].find("NJ")!=std::string::npos) AddNumJetsSplit(); - else if(_optMap["Conditions"].find("TR")!=std::string::npos) AddTriggerSplit(); - else{ - _numCond = 1; - _condVec.push_back(_optMap["Conditions"]); - } - if(_optMap["Conditions"].find("corr")!=std::string::npos) AddCorrection(); - ReadEfficiencies(); -} - -void MMEffSet::SetDataPath(std::string path){ - _dataPath = path; -} - -void MMEffSet::ParseOptions(std::string s,std::map<std::string,std::string> *m){ - TString ss(s); - TObjArray *optArray = ss.Tokenize(":"); - (*m)["Name"] = ((TObjString*)optArray->At(0))->GetString(); - (*m)["Conditions"] = ((TObjString*)optArray->At(1))->GetString(); - for(int i=0;i<(int)optArray->GetEntries()-2;i++){ - (*m)[Form("Histo%d",i)] = ((TObjString*)optArray->At(i+2))->GetString(); - } - delete optArray; -} - -void MMEffSet::AddCustomSplit(std::string config){ - std::vector<std::string> condVec = Tokenize(config,":"); - if(_numCond>0) _condVec = Combine(_condVec,condVec); - else _condVec = condVec; - _numCond = _condVec.size(); -} - -void MMEffSet::ReadEfficiencies(){ - if(_effIsRead) return; - // real - for(int i=0;i<(int)_condVec.size();i++){ - _Eff[i] = new MMEfficiency(); - ReadEfficiency(_Eff[i],_Estimate,_condVec[i]); - if(_useCorr){ - _EffCorr[i] = new MMEfficiency(); - ReadEfficiency(_EffCorr[i],_Estimate,_condVec[i],true); - } - } - _effIsRead = true; -} - -void MMEffSet::AddNumBtagSplit(){ - AddCustomSplit("0b:ge1b"); - _splitBitMask |= (NBTAG_MASK); -} -void MMEffSet::AddNumJetsSplit(){ - AddCustomSplit("1j:2or3j:ge4j"); - _splitBitMask |= (NJETS_MASK); -} -void MMEffSet::AddNumJetsShortSplit(){ - AddCustomSplit("1j:ge2j"); - _splitBitMask |= (NJETSSHORT_MASK); -} -void MMEffSet::AddTriggerSplit(){ - // for Run1 - if(_period == Period::Year2012){ - if(_isEle){ - AddCustomSplit("e24vhi:e60:e24vh"); - _ptTres = 62; - } - else{ - AddCustomSplit("mu24i:mu36:mu24"); - _ptTres = 37; - } - } - else if (_period == Period::Year2015) { // for Run2 - //if(_isEle){ // no trigger splitting for electrons - //} - if(!_isEle) { // for muons - AddCustomSplit("mu20_iloose_L1MU15:mu50:mu20_L1MU15"); - _ptTres = 51; - } - //AddCustomSplit(Form("%s:%s:%s",_trig1.c_str(),_trig2.c_str(),_trig3.c_str())); - } - else if (_period == Period::Year2016) { // for Run2 - if(_isEle){ // no trigger splitting for electrons - AddCustomSplit("e24_lhtight_nod0_ivarloose:e60_lhmedium_nod0:e24_lhmedium_L1EM20VH"); - _ptTres = 62; - } - if(!_isEle) { // for muons - AddCustomSplit("mu24_ivarmedium:mu50:mu24"); - _ptTres = 51; - } - //AddCustomSplit(Form("%s:%s:%s",_trig1.c_str(),_trig2.c_str(),_trig3.c_str())); - } - _splitBitMask |= (TRIGGER_MASK); -} - -// ... and combined -void MMEffSet::AddNumBtagAndTriggerSplit(){ - AddNumBtagSplit(); - AddTriggerSplit(); -} -void MMEffSet::AddNumBtagAndNumJetsSplit(){ - AddNumBtagSplit(); - AddNumJetsSplit(); -} -void MMEffSet::AddNumBtagAndNumJetsShortSplit(){ - AddNumBtagSplit(); - AddNumJetsShortSplit(); -} -void MMEffSet::AddNumJetsAndTriggerSplit(){ - AddNumJetsSplit(); - AddTriggerSplit(); -} -void MMEffSet::AddNumJetsShortAndTriggerSplit(){ - AddNumJetsShortSplit(); - AddTriggerSplit(); -} -void MMEffSet::AddNumBtagAndNumJetsAndTriggerSplit(){ - AddNumBtagSplit(); - AddNumJetsSplit(); - AddTriggerSplit(); -} -void MMEffSet::AddNumBtagAndNumJetsShortAndTriggerSplit(){ - AddNumBtagSplit(); - AddNumJetsShortSplit(); - AddTriggerSplit(); -} - -void MMEffSet::ReadEfficiency(MMEfficiency *eff,std::string aEff,std::string condition,bool isCorrection){ - string effFileName = Form("%s/%s_%s_%s.root", - _dataPath.c_str(), - isCorrection ? (_isReal ? "RCorr" : "FCorr") : (_isReal ? "R" : "F"), - _isEle ? "el" : "mu", - _optMap["Name"].c_str() - ); - if(_debug){ - if(_debug) std::cout << "------------------------------" << std::endl; - if(_isReal) std::cout << " --> Opening file for Real Eff: "; - else std::cout << " --> Opening file for Fake Eff: "; - std::cout << effFileName << std::endl; - } - TFile* effFile = TFile::Open(effFileName.c_str()); - - std::map<std::string,std::string> optMap; - ParseOptions(aEff,&optMap); - - string histoName; - int ndim = 1; - - bool status; - - // take average from histo - histoName = "av"; - if(condition=="") histoName = (string)(isCorrection ? "corr" : "eff")+"_" + histoName + "_" + optMap["Conditions"]; - else histoName = (string)(isCorrection ? "corr" : "eff")+"_" + histoName + "_" + condition; - if(_debug) std::cout << " --> Looking for histogram \"" << histoName << "\" inside file " << effFile->GetName() << std::endl; - eff->SetAverageHist(effFile,histoName); - - for(int i=0;;i++){ - histoName = optMap[Form("Histo%d",i)]; - if(histoName == "") break; - ndim = 1 + CountInString(histoName,'_'); - if(condition=="") histoName = (string)(isCorrection ? "corr" : "eff")+"_" + histoName + "_" + optMap["Conditions"]; - else histoName = (string)(isCorrection ? "corr" : "eff")+"_" + histoName + "_" + condition; - if(_debug){ - std::cout << " --> Looking for histogram \"" << histoName << "\" inside file " << effFile->GetName(); - std::cout << " " << (ndim==1 ?" (1D)" : (ndim==2 ? " (2D)" : " (3D)")); - std::cout << "..... "; - } - status = eff->AddHisto(effFile,histoName,ndim); - if(_debug){ - if(status) std::cout << "OK" << std::endl; - else std::cout << "NO" << std::endl << " MMEfficiency::INFO: Dummy Hstogram added." << std::endl; - } - } - - delete effFile; -} - -void MMEffSet::AddCorrection(){ - _useCorr = true; -} - -void MMEffSet::SetCustom(int value){ - _splitIdx = value; -} - -void MMEffSet::SetNumBtag(int nbtag){ - int value = -100; - value = NumBtagValue(nbtag); - SetCustom(value); -} - -void MMEffSet::SetNumJets(int njets){ - int value = -100; - value = NumJetsValue(njets); - SetCustom(value); -} - -void MMEffSet::SetNumJetsShort(int njets){ - int value = -100; - value = NumJetsShortValue(njets); - SetCustom(value); -} - -void MMEffSet::SetTrigger(int trigger,float pt){ - int value = -100; - value = TriggerValue(trigger, pt); - SetCustom(value); -} - -void MMEffSet::SetNumBtagAndNumJets(int nbtag,int njets){ - int value = -100; - value = NumJetsValue(njets); - value += 3*NumBtagValue(nbtag); - SetCustom(value); -} - -void MMEffSet::SetNumBtagAndNumJetsShort(int nbtag,int njets){ - int value = -100; - value = NumJetsShortValue(njets); - value += 2*NumBtagValue(nbtag); - SetCustom(value); -} - -void MMEffSet::SetNumBtagAndTrigger(int nbtag,int trigger,float pt){ - int value = -100; - value = TriggerValue(trigger, pt); - value += 3*NumBtagValue(nbtag); - SetCustom(value); -} - -void MMEffSet::SetNumJetsAndTrigger(int njets,int trigger,float pt){ - int value = -100; - value = TriggerValue(trigger, pt); - value += 3*NumJetsValue(njets); - SetCustom(value); -} - -void MMEffSet::SetNumJetsShortAndTrigger(int njets,int trigger,float pt){ - int value = -100; - value = TriggerValue(trigger, pt); - value += 3*NumJetsShortValue(njets); - SetCustom(value); -} - -void MMEffSet::SetNumBtagAndNumJetsAndTrigger(int nbtag,int njets,int trigger,float pt){ - int value = -100; - value = TriggerValue(trigger, pt); - value += 3*NumJetsValue(njets); - value += 9*NumBtagValue(nbtag); - SetCustom(value); -} - -void MMEffSet::SetNumBtagAndNumJetsShortAndTrigger(int nbtag,int njets,int trigger,float pt){ - int value = -100; - value = TriggerValue(trigger, pt); - value += 3*NumJetsShortValue(njets); - value += 6*NumBtagValue(nbtag); - SetCustom(value); -} - -void MMEffSet::SetTriggerNames(std::string trig1,std::string trig2,std::string trig3){ - _trig1 = trig1; - _trig2 = trig2; - _trig3 = trig3; -} - -void MMEffSet::SetPeriod(int period){ - _period = period; -} - -void MMEffSet::SetTriggerPrescales(float ps1,float ps2,float ps3){ - _ps1 = ps1; - _ps2 = ps2; - _ps3 = ps3; -} - -void MMEffSet::SetTriggerThreshold(float thres){ - _ptTres = thres; -} - -int MMEffSet::TriggerValue(int trigger,float pt){ - _trigger = -100; - if ((trigger & (1 << 0))>0 && (_ptTres<0 || pt < _ptTres)) _trigger = 0; // if matched to the low-pT isolated trigger - if ((trigger & (1 << 1))>0 && (_ptTres<0 || pt >= _ptTres)) _trigger = 1; // if matched to the high-pT trigger - if ((trigger & (1 << 2))>0 && (_ptTres<0 || pt < _ptTres)) _trigger = 2; // if matched to the low-pT non-iso trigger - if ((trigger & 3)==0) _trigger = 2; // if not matched to any trigger -> assign the low-pt non-iso eff - return _trigger; -} - -int MMEffSet::NumJetsValue(int njets){ - if(njets==1) return 0; - if(njets<=3) return 1; - else return 2; -} - -int MMEffSet::NumJetsShortValue(int njets){ - if(njets==1) return 0; - else return 1; -} - -int MMEffSet::NumBtagValue(int nbtag){ - if(nbtag==0) return 0; - else return 1; -} - -void MMEffSet::SetLepton(float v0,float v1,float v2,float v3,float v4,float v5,float v6,float v7,float v8,float v9){ - for(int i=0;i<_numCond;i++) _Eff[i]->SetParVars(v0,v1,v2,v3,v4,v5,v6,v7,v8,v9); - if(_useCorr) - for(int i=0;i<_numCond;i++) _EffCorr[i]->SetParVars(v0,v1,v2,v3,v4,v5,v6,v7,v8,v9); -} - -float MMEffSet::GetEff(bool isAverage){ - int idx = 0; - if(_numCond>0) idx = _splitIdx; - if(idx<0) return -1.; // added for events which are neglected by trigger splitting - float E; - if(isAverage){ - E = _Eff[idx]->GetAverageEfficiency(); - if(_useCorr) E *= _EffCorr[idx]->GetAverageEfficiency(); - } - else{ - E = _Eff[idx]->GetEfficiency(); - if(_useCorr) E *= _EffCorr[idx]->GetEfficiency(); - } - return E; -} - -// to be called after 'AddTriggerSplit' -void MMEffSet::SetPtThres(int thres){ - _ptTres = thres; -} - -void MMEffSet::SetLepton(MMEvent event,MMLepton lepton){ - _event = event; - _lepton = lepton; - // - int njets = _event.njets; - int ntag = _event.ntag; - float jetpt = _event.jetpt; - float sumet = _event.sumet; - // - float pt = _lepton.pt; - float eta = _lepton.eta; - float dR = _lepton.dR; - float dRpt = _lepton.dRpt; - float dPhi = _lepton.dPhi; - float d0sig = _lepton.d0sig; - int trigger = _lepton.trigger; - // - // set the correct splitting - if((_splitBitMask & NBTAG_MASK) && (_splitBitMask & NJETSSHORT_MASK) && (_splitBitMask & TRIGGER_MASK)) - SetNumBtagAndNumJetsShortAndTrigger(ntag,njets,trigger,pt); - else if((_splitBitMask & NBTAG_MASK) && (_splitBitMask & NJETS_MASK) && (_splitBitMask & TRIGGER_MASK)) - SetNumBtagAndNumJetsAndTrigger(ntag,njets,trigger,pt); - else if((_splitBitMask & NBTAG_MASK) && (_splitBitMask & TRIGGER_MASK)) - SetNumBtagAndTrigger(ntag,trigger,pt); - else if((_splitBitMask & NJETSSHORT_MASK) && (_splitBitMask & TRIGGER_MASK)) - SetNumJetsShortAndTrigger(njets,trigger,pt); - else if((_splitBitMask & NJETS_MASK) && (_splitBitMask & TRIGGER_MASK)) - SetNumJetsAndTrigger(njets,trigger,pt); - else if((_splitBitMask & NBTAG_MASK) && (_splitBitMask & NJETSSHORT_MASK)) - SetNumBtagAndNumJetsShort(ntag,njets); - else if((_splitBitMask & NBTAG_MASK) && (_splitBitMask & NJETS_MASK)) - SetNumBtagAndNumJets(ntag,njets); - else if((_splitBitMask & NBTAG_MASK)) - SetNumBtag(ntag); - else if((_splitBitMask & NJETSSHORT_MASK)) - SetNumJetsShort(njets); - else if((_splitBitMask & NJETS_MASK)) - SetNumJets(njets); - else if((_splitBitMask & TRIGGER_MASK)) - SetTrigger(trigger,pt); - // - // set the used variables - float input[] = {0,0,0,0,0,0,0,0,0,0}; - int k = 0; - if(_Estimate.find(":eta_dR")!=string::npos) { input[k] = eta; k++; input[k] = dR; k++; } - else if(_Estimate.find(":eta")!=string::npos) { input[k] = eta; k++; } - if(_Estimate.find(":pt_dR")!=string::npos) { input[k] = pt; k++; input[k] = dR; k++; } - else if(_Estimate.find(":pt_jetpt")!=string::npos) { input[k] = pt; k++; input[k] = jetpt; k++; } - else if(_Estimate.find(":pt")!=string::npos) { input[k] = pt; k++; } - if(_Estimate.find(":jetpt_dR")!=string::npos) { input[k] = jetpt; k++; input[k] = dR; k++; } - else if(_Estimate.find(":jetpt")!=string::npos){ input[k] = jetpt; k++; } - if(_Estimate.find(":sumet")!=string::npos) { input[k] = sumet; k++; } - if(_Estimate.find(":dR")!=string::npos && _Estimate.find(":dRpt")==string::npos) { input[k] = dR; k++; } - if(_Estimate.find(":dRpt")!=string::npos) { input[k] = dRpt; k++; } - if(_Estimate.find(":dPhi")!=string::npos) { input[k] = dPhi; k++; } - if(_Estimate.find(":d0sig")!=string::npos) { input[k] = d0sig; k++; } - if(_Estimate.find(":nbjets")!=string::npos) { input[k] = ntag; k++; } - - SetLepton(input[0],input[1],input[2],input[3],input[4],input[5],input[6],input[7],input[8],input[9]); -} - -float MMEffSet::GetPrescale(){ - if(_trigger==0) return _ps1; - if(_trigger==1) return _ps2; - if(_trigger==2) return _ps3; - return 1.; -} - - -// ------------------------------ - -// Internal methods / functions: - -int MMEffSet::CountInString(std::string s,char c){ - int n = 0; - for(int i=0;i<(int)s.size();i++){ - if(s[i]==c) n++; - } - return n; -} - -std::vector<std::string> MMEffSet::Tokenize(std::string s, std::string c){ - std::vector<std::string> v; - v.clear(); - std::string new_s; - while(true){ - new_s = s.substr(0,s.find(c)); - v.push_back(new_s); - if(new_s == s) break; - else s = s.substr(s.find(c)+1,s.size()); - } - return v; -} - -std::vector<std::string> MMEffSet::Combine(std::vector<std::string> v1,std::vector<std::string> v2){ - std::vector<std::string> v; - v.clear(); - for(int i=0;i<(int)v1.size();i++){ - for(int j=0;j<(int)v2.size();j++){ - v.push_back(v1[i]+"_"+v2[j]); - } - } - return v; -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MMEfficiency.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MMEfficiency.cxx deleted file mode 100644 index 64bbec0d5847..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MMEfficiency.cxx +++ /dev/null @@ -1,313 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - ** author: Michele Pinamonti <michele.pinamonti@cern.ch> - * * class used by FakesWeights.cxx -*/ - -#include "TopFakes/MMEfficiency.h" - -#define XXX std::cout << "I am here: " << __FILE__ << ":" << __LINE__ << std::endl; - -// ------------------------ Implementation ------------------------ // - -MMEfficiency::MMEfficiency() : - fAverage(-1), - fNvar(0) { - - for (int i = 0; i < MAXvar; ++i) { - fHist[i] = 0; - fHist2D[i] = 0; - fHist3D[i] = 0; - } -} - -MMEfficiency::~MMEfficiency(){ - for (int i = 0; i < MAXvar; ++i) { - delete fHist[i]; - delete fHist2D[i]; - delete fHist3D[i]; - } -} - -// ------------------------ AddHisto ------------------------ // - -bool MMEfficiency::AddHisto(TH1F *h){ - bool isDummy = false; - if(h==0) isDummy = true; - if(isDummy){ -// std::cout << " MMEfficiency::INFO: Dummy Hstogram added." << std::endl; - h = new TH1F("h_dummmy","h_dummy",1,0,1); - h->SetBinContent(1,1); - } - fHist[fNvar] = (TH1F*)h->Clone(); - fHist[fNvar]->SetDirectory(0); - fHist2D[fNvar] = 0; - fHist3D[fNvar] = 0; - if(fNvar>0 && fAverage<=0){ - std::cout << " MMEfficiency::INFO: No average efficiency set so far. Extracting it from current histogram... " << std::endl; - if(!isDummy) SetAverageFromHist((TH1F*)fHist[fNvar]->Clone()); - else fAverage = 1.; - } - fDim[fNvar] = 1; - fNvar += 1; - if(isDummy) delete h; - return !isDummy; -} - -bool MMEfficiency::AddHisto(TH2F *h){ - bool isDummy = false; - if(h==0) isDummy = true; - if(isDummy){ -// std::cout << " MMEfficiency::INFO: Dummy Hstogram added." << std::endl; - h = new TH2F("h_dummmy","h_dummy",1,0,1,1,0,1); - h->SetBinContent(1,1); - } - fHist[fNvar] = 0; - fHist2D[fNvar] = (TH2F*)h->Clone(); - fHist2D[fNvar]->SetDirectory(0); - fHist3D[fNvar] = 0; - if(fNvar>0 && fAverage<=0){ - std::cout << " MMEfficiency::INFO: No average efficiency set so far. Extracting it from current histogram... " << std::endl; - if(!isDummy) SetAverageFromHist((TH2F*)fHist2D[fNvar]->Clone()); - else fAverage = 1.; - } - fDim[fNvar] = 2; - fNvar += 2; - if(isDummy) delete h; - return !isDummy; -} - -bool MMEfficiency::AddHisto(TH3F *h){ - bool isDummy = false; - if(h==0) isDummy = true; - if(isDummy){ -// std::cout << " MMEfficiency::INFO: Dummy Hstogram added." << std::endl; - h = new TH3F("h_dummmy","h_dummy",1,0,1,1,0,1,1,0,1); - h->SetBinContent(1,1); - } - fHist[fNvar] = 0; - fHist2D[fNvar] = 0; - fHist3D[fNvar] = (TH3F*)h->Clone(); - fHist3D[fNvar]->SetDirectory(0); - if(fNvar>0 && fAverage<=0){ - std::cout << " MMEfficiency::INFO: No average efficiency set so far. Extracting it from current histogram... " << std::endl; - if(!isDummy) SetAverageFromHist((TH3F*)fHist3D[fNvar]->Clone()); - else fAverage = 1.; - } - fDim[fNvar] = 3; - fNvar += 3; - if(isDummy) delete h; - return !isDummy; -} - -bool MMEfficiency::AddHisto(TFile *f, std::string histoName, int ndim){ - f->cd(); - bool res = false; - if (ndim==1) res = AddHisto((TH1F*)f->Get(histoName.c_str())); - else if(ndim==2) res = AddHisto((TH2F*)f->Get(histoName.c_str())); - else if(ndim==3) res = AddHisto((TH3F*)f->Get(histoName.c_str())); - else{ - std::cout << " MMEfficiency::ERROR: ndim != 1,2,3" << std::endl; - return false; - } - return res; -} - -bool MMEfficiency::AddHisto(std::string fileName, std::string histoName, int ndim){ - bool res = false; - TFile *f = TFile::Open(fileName.c_str()); - res = AddHisto(f,histoName,ndim); - delete f; - return res; -} - -// ------------------------ SetAverage ------------------------ // - -void MMEfficiency::SetAverage(float value){ - fAverage = value; -} - -void MMEfficiency::SetAverageHist(std::string fileName, std::string histoName){ - TFile *f = TFile::Open(fileName.c_str()); - if(!f) return; - TH1F *h = (TH1F*)f->Get(histoName.c_str()); - if(!h){ - delete f; - return; - } - fAverage = h->GetBinContent(1); -// cout << "Setting Average Efficiency = " << fAverage << endl; - delete f; -} - -void MMEfficiency::SetAverageHist(TFile *f, std::string histoName){ - TH1F *h = (TH1F*)f->Get(histoName.c_str()); - if(!h) return; - fAverage = h->GetBinContent(1); -// cout << "Setting Average Efficiency = " << fAverage << endl; - delete h; -} - -float MMEfficiency::SetAverageFromHist(TH1F *h){ - TF1 *p = new TF1("p","pol0",h->GetXaxis()->GetBinLowEdge(1),h->GetXaxis()->GetBinUpEdge(h->GetNbinsX())); - h->Fit(p,"I0"); - fAverage = p->GetParameter(0); - delete p; - return fAverage; -} - -float MMEfficiency::SetAverageFromHist(TH2F *h){ - TF2 *p = new TF2("p","[0]+0*x+0*y", - h->GetXaxis()->GetBinLowEdge(1),h->GetXaxis()->GetBinUpEdge(h->GetNbinsX()), - h->GetYaxis()->GetBinLowEdge(1),h->GetYaxis()->GetBinUpEdge(h->GetNbinsY()) - ); - h->Fit(p,"I0"); - fAverage = p->GetParameter(0); - delete p; - return fAverage; -} - -float MMEfficiency::SetAverageFromHist(TH3F *h){ - TF3 *p = new TF3("p","[0]+0*x+0*y+0*z", - h->GetXaxis()->GetBinLowEdge(1),h->GetXaxis()->GetBinUpEdge(h->GetNbinsX()), - h->GetYaxis()->GetBinLowEdge(1),h->GetYaxis()->GetBinUpEdge(h->GetNbinsY()), - h->GetZaxis()->GetBinLowEdge(1),h->GetZaxis()->GetBinUpEdge(h->GetNbinsZ()) - ); - h->Fit(p,"I0"); - fAverage = p->GetParameter(0); - delete p; - return fAverage; -} - -float MMEfficiency::SetAverageFromHist(TFile *f, std::string histoName,int ndim){ - float av = -1; - TH1F *h1; - TH2F *h2; - TH3F *h3; - if(ndim==1){ - h1 = (TH1F*)f->Get(histoName.c_str()); - av = SetAverageFromHist(h1); - } - if(ndim==2){ - h2 = (TH2F*)f->Get(histoName.c_str()); - av = SetAverageFromHist(h2); - } - if(ndim==3){ - h3 = (TH3F*)f->Get(histoName.c_str()); - av = SetAverageFromHist(h3); - } - return av; -} - -float MMEfficiency::SetAverageFromHist(std::string fileName, std::string histoName,int ndim){ - float av = -1; - TFile *f = TFile::Open(fileName.c_str()); - av = SetAverageFromHist(f,histoName,ndim); - delete f; - return av; -} - -// ------------------------ GetEfficiency ------------------------ // - -float MMEfficiency::GetEfficiency(){ - float eff = 1; - float eff1 = 0; - float v0, v1, v2; - float xmin, ymin, zmin; - float xmax, ymax, zmax; - for(int i=0;i<fNvar;i+=fDim[i]){ - // ensure that x,y,z are inside hist range - if(fDim[i]==3){ - v0 = fVars[i]; - xmin = fHist3D[i]->GetXaxis()->GetXmin(); - xmax = fHist3D[i]->GetXaxis()->GetXmax(); - if(v0<xmin) v0 = xmin; - if(v0>xmax) v0 = xmax-0.001; - v1 = fVars[i+1]; - ymin = fHist3D[i]->GetYaxis()->GetXmin(); - ymax = fHist3D[i]->GetYaxis()->GetXmax(); - if(v1<ymin) v1 = ymin; - if(v1>ymax) v1 = ymax-0.001; - v2 = fVars[i+2]; - zmin = fHist3D[i]->GetZaxis()->GetXmin(); - zmax = fHist3D[i]->GetZaxis()->GetXmax(); - if(v2<zmin) v2 = zmin; - if(v2>zmax) v2 = zmax-0.001; - eff1 = fHist3D[i]->GetBinContent(fHist3D[i]->FindBin(v0,v1,v2)); - } - if(fDim[i]==2){ - v0 = fVars[i]; - xmin = fHist2D[i]->GetXaxis()->GetXmin(); - xmax = fHist2D[i]->GetXaxis()->GetXmax(); - if(v0<xmin) v0 = xmin; - if(v0>xmax) v0 = xmax-0.001; - v1 = fVars[i+1]; - ymin = fHist2D[i]->GetYaxis()->GetXmin(); - ymax = fHist2D[i]->GetYaxis()->GetXmax(); - if(v1<ymin) v1 = ymin; - if(v1>ymax) v1 = ymax-0.001; - eff1 = fHist2D[i]->GetBinContent(fHist2D[i]->FindBin(v0,v1)); - } - if(fDim[i]==1){ - v0 = fVars[i]; - xmin = fHist[i]->GetXaxis()->GetXmin(); - xmax = fHist[i]->GetXaxis()->GetXmax(); - if(v0<xmin) v0 = xmin; - if(v0>xmax) v0 = xmax-0.001; - // fix by Timothée Theveneaux-Pelzer - if ( fHist[i]->GetXaxis()->FindBin(v0) < fHist[i]->FindFirstBinAbove(0) ) { - int bin=fHist[i]->FindFirstBinAbove(0); - eff1 = fHist[i]->GetBinContent(bin); - } - else if ( fHist[i]->GetXaxis()->FindBin(v0) > fHist[i]->FindLastBinAbove(0) ) { - int bin=fHist[i]->FindLastBinAbove(0); - eff1 = fHist[i]->GetBinContent(bin); - } - else eff1 = fHist[i]->GetBinContent(fHist[i]->FindBin(v0)); -// cout << fHist[i]->GetTitle() << endl; - } - // - if(eff1>0 && eff1<1) eff *= eff1; // this is just to avoid crazy eff values going in - else eff *= fAverage; // ... and if the value is non-physica, just give the average eff - // - if(i>0) eff /= fAverage; // divide by average if it's an additional parametrization - } - return eff; -} - -float MMEfficiency::GetAverageEfficiency(){ - return fAverage; -} - -float MMEfficiency::GetEfficiency(float v0,float v1,float v2,float v3,float v4,float v5,float v6,float v7,float v8,float v9){ - SetParVars(v0,v1,v2,v3,v4,v5,v6,v7,v8,v9); - return GetEfficiency(); -} - -// ------------------------ SetParVar(s) ------------------------ // - -void MMEfficiency::SetParVars(float v0,float v1,float v2,float v3,float v4,float v5,float v6,float v7,float v8,float v9){ - SetParVar(0,v0); - if(fNvar>=2) SetParVar(1,v1); - if(fNvar>=3) SetParVar(2,v2); - if(fNvar>=4) SetParVar(3,v3); - if(fNvar>=5) SetParVar(4,v4); - if(fNvar>=6) SetParVar(5,v5); - if(fNvar>=7) SetParVar(6,v6); - if(fNvar>=8) SetParVar(7,v7); - if(fNvar>=9) SetParVar(8,v8); - if(fNvar>=10) SetParVar(9,v9); -} - -void MMEfficiency::SetParVar(int idx,float value){ - fVars[idx] = value; -} - -// ------------------------ Other ------------------------ // - -int MMEfficiency::GetNvars(){ - return fNvar; -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MatrixUtils.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MatrixUtils.cxx deleted file mode 100644 index d20b2a59d978..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/MatrixUtils.cxx +++ /dev/null @@ -1,486 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// -// Generic matrix methods fake lepton estimates for lepton and dilepton. -// -// Given loose/tight lepton ID, real efficiency r, -// and fake efficiency f builds the fake estimate event weight -// -// Authors: -// Karl Gellerstedt (kargel@fysik.su.se) -// Jorgen Sjolin (sjolin@fysik.su.se) -// - -#include "TopFakes/MatrixUtils.h" -#include <iostream> -using namespace std; - -MatrixUtils::MatrixUtils() : - ljets_matrix(2,2), - ljets_matrix_top_corr(2,2), - ll_matrix(4,4), - ll_matrix_top_corr(4,4), - lll_matrix(8,8), - i_ljets_matrix(2,2), - i_ljets_matrix_top_corr(2,2), - i_ll_matrix(4,4), - i_ll_matrix_top_corr(4,4), - i_lll_matrix(8,8) -{ - -} - -double MatrixUtils::lepton_weight(bool loose, double r, double f, - double &nf, double & /*nr*/) { - // fix to not return NaN - if(r == 0 && f == 0) - return nf; - - double nl=loose ? 1 :0; - double nt=!loose ? 1 :0; - double a=1./(r-f); - nf=a*f*r*nl + a*f*(r - 1.)*nt; - if(nf!=nf) nf = 0.; // protect against "nan" - return nf; -} - -void MatrixUtils::fill_matrix(double r, double f) -{ - ljets_matrix[0][0] = r; - ljets_matrix[0][1] = f; - ljets_matrix[1][0] = (1. - r); - ljets_matrix[1][1] = (1. - f); - i_ljets_matrix = ljets_matrix; - i_ljets_matrix.InvertFast(); - - ljets_matrix_top_corr[0][0] = r; - ljets_matrix_top_corr[0][1] = f; - ljets_matrix_top_corr[1][0] = (1. - r); - ljets_matrix_top_corr[1][1] = (1. - f); - i_ljets_matrix_top_corr = ljets_matrix_top_corr; - i_ljets_matrix_top_corr.InvertFast(); -} - -void MatrixUtils::fill_matrix(double r, double f, double t) -{ - ljets_matrix[0][0] = r; - ljets_matrix[0][1] = f; - ljets_matrix[1][0] = (1. - r); - ljets_matrix[1][1] = (1. - f); - i_ljets_matrix = ljets_matrix; - i_ljets_matrix.InvertFast(); - - ljets_matrix_top_corr[0][0] = r*t; - ljets_matrix_top_corr[0][1] = f; - ljets_matrix_top_corr[1][0] = (1. - r*t); - ljets_matrix_top_corr[1][1] = (1. - f); - i_ljets_matrix_top_corr = ljets_matrix_top_corr; - i_ljets_matrix_top_corr.InvertFast(); -} - -double MatrixUtils::lepton_tight_weight(bool loose) -{ - double nl=loose ? 1 :0; - double nt=!loose ? 1 :0; - double nf=i_ljets_matrix[1][0]*nt + i_ljets_matrix[1][1]*nl; - double nf_tight=ljets_matrix[0][1]*nf; - return nf_tight; -} - -double MatrixUtils::lepton_loose_weight(bool loose) -{ - double nl=loose ? 1 :0; - double nt=!loose ? 1 :0; - double nf=i_ljets_matrix[1][0]*nt + i_ljets_matrix[1][1]*nl; - double nf_loose=ljets_matrix[1][1]*nf; - return nf_loose; -} - -double MatrixUtils::lepton_tight_top_corr_weight(bool loose) -{ - double nl=loose ? 1 :0; - double nt=!loose ? 1 :0; - double nf=i_ljets_matrix_top_corr[1][0]*nt + i_ljets_matrix_top_corr[1][1]*nl; - double nf_tight=ljets_matrix_top_corr[0][1]*nf; - return nf_tight; -} - -double MatrixUtils::lepton_loose_top_corr_weight(bool loose) -{ - double nl=loose ? 1 :0; - double nt=!loose ? 1 :0; - double nf=i_ljets_matrix_top_corr[1][0]*nt + i_ljets_matrix_top_corr[1][1]*nl; - double nf_tight=ljets_matrix_top_corr[0][1]*nf; - return nf_tight; -} - - -double MatrixUtils::dilepton_weight(bool l1, double r1, double f1, - bool l2, double r2, double f2, - double &nrf, double &nfr, - double &nff) { - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double a=1./((r1-f1)*(r2-f2)); - - nrf= a*r1*f2*( -(1.-f1)*(1.-r2)*ntt + (1.-f1)*r2*ntl + f1*(1.-r2)*nlt - f1*r2*nll ); - - nfr= a*f1*r2*( -(1.-r1)*(1.-f2)*ntt + (1.-r1)*f2*ntl + r1*(1.-f2)*nlt - r1*f2*nll ); - - nff= a*f1*f2*( +(1.-r1)*(1.-r2)*ntt - (1.-r1)*r2*ntl - r1*(1.-r2)*nlt + r1*r2*nll ); - - if(nrf!=nrf) nrf = 0.; // protect against "nan" - if(nfr!=nfr) nfr = 0.; // protect against "nan" - if(nff!=nff) nff = 0.; // protect against "nan" - return nrf+nfr+nff; -} - -void MatrixUtils::fill_matrix(double r1, double f1, double r2, double f2) -{ - ll_matrix[0][0] = r1 * r2; - ll_matrix[0][1] = r1 * f2; - ll_matrix[0][2] = f1 * r2; - ll_matrix[0][3] = f1 * f2; - ll_matrix[1][0] = r1 * (1. - r2); - ll_matrix[1][1] = r1 * (1. - f2); - ll_matrix[1][2] = f1 * (1. - r2); - ll_matrix[1][3] = f1 * (1. - f2); - ll_matrix[2][0] = (1. - r1) * r2; - ll_matrix[2][1] = (1. - r1) * f2; - ll_matrix[2][2] = (1. - f1) * r2; - ll_matrix[2][3] = (1. - f1) * f2; - ll_matrix[3][0] = (1. - r1) * (1. - r2); - ll_matrix[3][1] = (1. - r1) * (1. - f2); - ll_matrix[3][2] = (1. - f1) * (1. - r2); - ll_matrix[3][3] = (1. - f1) * (1. - f2); - i_ll_matrix = ll_matrix; - i_ll_matrix.InvertFast(); - - ll_matrix_top_corr[0][0] = r1 * r2; // RR - ll_matrix_top_corr[0][1] = r1 * f2; - ll_matrix_top_corr[0][2] = f1 * r2; - ll_matrix_top_corr[0][3] = f1 * f2; - ll_matrix_top_corr[1][0] = r1 * (1. - r2); // RR - ll_matrix_top_corr[1][1] = r1 * (1. - f2); - ll_matrix_top_corr[1][2] = f1 * (1. - r2); - ll_matrix_top_corr[1][3] = f1 * (1. - f2); - ll_matrix_top_corr[2][0] = (1. - r1) * r2; // RR - ll_matrix_top_corr[2][1] = (1. - r1) * f2; - ll_matrix_top_corr[2][2] = (1. - f1) * r2; - ll_matrix_top_corr[2][3] = (1. - f1) * f2; - ll_matrix_top_corr[3][0] = (1. - r1) * (1. - r2); // RR - ll_matrix_top_corr[3][1] = (1. - r1) * (1. - f2); - ll_matrix_top_corr[3][2] = (1. - f1) * (1. - r2); - ll_matrix_top_corr[3][3] = (1. - f1) * (1. - f2); - i_ll_matrix_top_corr = ll_matrix_top_corr; - i_ll_matrix_top_corr.InvertFast(); -} - -void MatrixUtils::fill_matrix(double r1, double f1, double t1, double r2, double f2, double t2) -{ - ll_matrix[0][0] = r1 * r2; - ll_matrix[0][1] = r1 * f2; - ll_matrix[0][2] = f1 * r2; - ll_matrix[0][3] = f1 * f2; - ll_matrix[1][0] = r1 * (1. - r2); - ll_matrix[1][1] = r1 * (1. - f2); - ll_matrix[1][2] = f1 * (1. - r2); - ll_matrix[1][3] = f1 * (1. - f2); - ll_matrix[2][0] = (1. - r1) * r2; - ll_matrix[2][1] = (1. - r1) * f2; - ll_matrix[2][2] = (1. - f1) * r2; - ll_matrix[2][3] = (1. - f1) * f2; - ll_matrix[3][0] = (1. - r1) * (1. - r2); - ll_matrix[3][1] = (1. - r1) * (1. - f2); - ll_matrix[3][2] = (1. - f1) * (1. - r2); - ll_matrix[3][3] = (1. - f1) * (1. - f2); - i_ll_matrix = ll_matrix; - i_ll_matrix.InvertFast(); - - // This is to fill and invert the matrix using the correction applied only to the real/real column - ll_matrix_top_corr[0][0] = r1 * t1 * r2 * t2; // RR - ll_matrix_top_corr[0][1] = r1 * f2; - ll_matrix_top_corr[0][2] = f1 * r2; - ll_matrix_top_corr[0][3] = f1 * f2; - ll_matrix_top_corr[1][0] = r1 * t1 * (1. - r2 * t2); // RR - ll_matrix_top_corr[1][1] = r1 * (1. - f2); - ll_matrix_top_corr[1][2] = f1 * (1. - r2); - ll_matrix_top_corr[1][3] = f1 * (1. - f2); - ll_matrix_top_corr[2][0] = (1. - r1 * t1) * r2 * t2; // RR - ll_matrix_top_corr[2][1] = (1. - r1) * f2; - ll_matrix_top_corr[2][2] = (1. - f1) * r2; - ll_matrix_top_corr[2][3] = (1. - f1) * f2; - ll_matrix_top_corr[3][0] = (1. - r1 * t1) * (1. - r2 * t2); // RR - ll_matrix_top_corr[3][1] = (1. - r1) * (1. - f2); - ll_matrix_top_corr[3][2] = (1. - f1) * (1. - r2); - ll_matrix_top_corr[3][3] = (1. - f1) * (1. - f2); - i_ll_matrix_top_corr = ll_matrix_top_corr; - i_ll_matrix_top_corr.InvertFast(); -} - -double MatrixUtils::dilepton_TT_weight(bool l1, bool l2) -{ - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double nrf = i_ll_matrix[1][0] * ntt + i_ll_matrix[1][1] * ntl + i_ll_matrix[1][2] * nlt + i_ll_matrix[1][3] * nll; - double nfr = i_ll_matrix[2][0] * ntt + i_ll_matrix[2][1] * ntl + i_ll_matrix[2][2] * nlt + i_ll_matrix[2][3] * nll; - double nff = i_ll_matrix[3][0] * ntt + i_ll_matrix[3][1] * ntl + i_ll_matrix[3][2] * nlt + i_ll_matrix[3][3] * nll; - - double nrf_TT = ll_matrix[0][1] * nrf; - double nfr_TT = ll_matrix[0][2] * nfr; - double nff_TT = ll_matrix[0][3] * nff; - - return nrf_TT + nfr_TT + nff_TT; -} - -double MatrixUtils::dilepton_TL_weight(bool l1, bool l2) -{ - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double nrf = i_ll_matrix[1][0] * ntt + i_ll_matrix[1][1] * ntl + i_ll_matrix[1][2] * nlt + i_ll_matrix[1][3] * nll; - double nfr = i_ll_matrix[2][0] * ntt + i_ll_matrix[2][1] * ntl + i_ll_matrix[2][2] * nlt + i_ll_matrix[2][3] * nll; - double nff = i_ll_matrix[3][0] * ntt + i_ll_matrix[3][1] * ntl + i_ll_matrix[3][2] * nlt + i_ll_matrix[3][3] * nll; - - double nrf_TL = ll_matrix[1][1] * nrf; - double nfr_TL = ll_matrix[1][2] * nfr; - double nff_TL = ll_matrix[1][3] * nff; - - return nrf_TL + nfr_TL + nff_TL; -} - -double MatrixUtils::dilepton_LT_weight(bool l1, bool l2) -{ - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double nrf = i_ll_matrix[1][0] * ntt + i_ll_matrix[1][1] * ntl + i_ll_matrix[1][2] * nlt + i_ll_matrix[1][3] * nll; - double nfr = i_ll_matrix[2][0] * ntt + i_ll_matrix[2][1] * ntl + i_ll_matrix[2][2] * nlt + i_ll_matrix[2][3] * nll; - double nff = i_ll_matrix[3][0] * ntt + i_ll_matrix[3][1] * ntl + i_ll_matrix[3][2] * nlt + i_ll_matrix[3][3] * nll; - - double nrf_LT = ll_matrix[2][1] * nrf; - double nfr_LT = ll_matrix[2][2] * nfr; - double nff_LT = ll_matrix[2][3] * nff; - - return nrf_LT + nfr_LT + nff_LT; -} - -double MatrixUtils::dilepton_LL_weight(bool l1, bool l2) -{ - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double nrf = i_ll_matrix[1][0] * ntt + i_ll_matrix[1][1] * ntl + i_ll_matrix[1][2] * nlt + i_ll_matrix[1][3] * nll; - double nfr = i_ll_matrix[2][0] * ntt + i_ll_matrix[2][1] * ntl + i_ll_matrix[2][2] * nlt + i_ll_matrix[2][3] * nll; - double nff = i_ll_matrix[3][0] * ntt + i_ll_matrix[3][1] * ntl + i_ll_matrix[3][2] * nlt + i_ll_matrix[3][3] * nll; - - double nrf_LL = ll_matrix[3][1] * nrf; - double nfr_LL = ll_matrix[3][2] * nfr; - double nff_LL = ll_matrix[3][3] * nff; - - return nrf_LL + nfr_LL + nff_LL; -} - -double MatrixUtils::dilepton_TT_top_corr_weight(bool l1, bool l2) -{ - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double nrf = i_ll_matrix_top_corr[1][0] * ntt + i_ll_matrix_top_corr[1][1] * ntl + i_ll_matrix_top_corr[1][2] * nlt + i_ll_matrix_top_corr[1][3] * nll; - double nfr = i_ll_matrix_top_corr[2][0] * ntt + i_ll_matrix_top_corr[2][1] * ntl + i_ll_matrix_top_corr[2][2] * nlt + i_ll_matrix_top_corr[2][3] * nll; - double nff = i_ll_matrix_top_corr[3][0] * ntt + i_ll_matrix_top_corr[3][1] * ntl + i_ll_matrix_top_corr[3][2] * nlt + i_ll_matrix_top_corr[3][3] * nll; - - double nrf_TT = ll_matrix_top_corr[0][1] * nrf; - double nfr_TT = ll_matrix_top_corr[0][2] * nfr; - double nff_TT = ll_matrix_top_corr[0][3] * nff; - - return nrf_TT + nfr_TT + nff_TT; -} - -double MatrixUtils::dilepton_TL_top_corr_weight(bool l1, bool l2) -{ - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double nrf = i_ll_matrix_top_corr[1][0] * ntt + i_ll_matrix_top_corr[1][1] * ntl + i_ll_matrix_top_corr[1][2] * nlt + i_ll_matrix_top_corr[1][3] * nll; - double nfr = i_ll_matrix_top_corr[2][0] * ntt + i_ll_matrix_top_corr[2][1] * ntl + i_ll_matrix_top_corr[2][2] * nlt + i_ll_matrix_top_corr[2][3] * nll; - double nff = i_ll_matrix_top_corr[3][0] * ntt + i_ll_matrix_top_corr[3][1] * ntl + i_ll_matrix_top_corr[3][2] * nlt + i_ll_matrix_top_corr[3][3] * nll; - - double nrf_TL = ll_matrix_top_corr[1][1] * nrf; - double nfr_TL = ll_matrix_top_corr[1][2] * nfr; - double nff_TL = ll_matrix_top_corr[1][3] * nff; - - return nrf_TL + nfr_TL + nff_TL; -} - -double MatrixUtils::dilepton_LT_top_corr_weight(bool l1, bool l2) -{ - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double nrf = i_ll_matrix_top_corr[1][0] * ntt + i_ll_matrix_top_corr[1][1] * ntl + i_ll_matrix_top_corr[1][2] * nlt + i_ll_matrix_top_corr[1][3] * nll; - double nfr = i_ll_matrix_top_corr[2][0] * ntt + i_ll_matrix_top_corr[2][1] * ntl + i_ll_matrix_top_corr[2][2] * nlt + i_ll_matrix_top_corr[2][3] * nll; - double nff = i_ll_matrix_top_corr[3][0] * ntt + i_ll_matrix_top_corr[3][1] * ntl + i_ll_matrix_top_corr[3][2] * nlt + i_ll_matrix_top_corr[3][3] * nll; - - double nrf_LT = ll_matrix_top_corr[2][1] * nrf; - double nfr_LT = ll_matrix_top_corr[2][2] * nfr; - double nff_LT = ll_matrix_top_corr[2][3] * nff; - - return nrf_LT + nfr_LT + nff_LT; -} - -double MatrixUtils::dilepton_LL_top_corr_weight(bool l1, bool l2) -{ - double ntt=((!l1)&&(!l2)?1.:0.); - double ntl=((!l1)&&( l2)?1.:0.); - double nlt=(( l1)&&(!l2)?1.:0.); - double nll=(( l1)&&( l2)?1.:0.); - - double nrf = i_ll_matrix_top_corr[1][0] * ntt + i_ll_matrix_top_corr[1][1] * ntl + i_ll_matrix_top_corr[1][2] * nlt + i_ll_matrix_top_corr[1][3] * nll; - double nfr = i_ll_matrix_top_corr[2][0] * ntt + i_ll_matrix_top_corr[2][1] * ntl + i_ll_matrix_top_corr[2][2] * nlt + i_ll_matrix_top_corr[2][3] * nll; - double nff = i_ll_matrix_top_corr[3][0] * ntt + i_ll_matrix_top_corr[3][1] * ntl + i_ll_matrix_top_corr[3][2] * nlt + i_ll_matrix_top_corr[3][3] * nll; - - double nrf_LL = ll_matrix_top_corr[3][1] * nrf; - double nfr_LL = ll_matrix_top_corr[3][2] * nfr; - double nff_LL = ll_matrix_top_corr[3][3] * nff; - - return nrf_LL + nfr_LL + nff_LL; -} - -void MatrixUtils::fill_lll_matrix(double r1, double f1, double r2, double f2, double r3, double f3) -{ - - lll_matrix[0][0] = r1 * r2 * r3; - lll_matrix[0][1] = r1 * r2 * f3; - lll_matrix[0][2] = r1 * f2 * r3; - lll_matrix[0][3] = r1 * f2 * f3; - lll_matrix[0][4] = f1 * r2 * r3; - lll_matrix[0][5] = f1 * r2 * f3; - lll_matrix[0][6] = f1 * f2 * r3; - lll_matrix[0][7] = f1 * f2 * f3; - - lll_matrix[1][0] = r1 * r2 * (1. - r3); - lll_matrix[1][1] = r1 * r2 * (1. - f3); - lll_matrix[1][2] = r1 * f2 * (1. - r3); - lll_matrix[1][3] = r1 * f2 * (1. - f3); - lll_matrix[1][4] = f1 * r2 * (1. - r3); - lll_matrix[1][5] = f1 * r2 * (1. - f3); - lll_matrix[1][6] = f1 * f2 * (1. - r3); - lll_matrix[1][7] = f1 * f2 * (1. - f3); - - lll_matrix[2][0] = r1 * (1. - r2) * r3; - lll_matrix[2][1] = r1 * (1. - r2) * f3; - lll_matrix[2][2] = r1 * (1. - f2) * r3; - lll_matrix[2][3] = r1 * (1. - f2) * f3; - lll_matrix[2][4] = f1 * (1. - r2) * r3; - lll_matrix[2][5] = f1 * (1. - r2) * f3; - lll_matrix[2][6] = f1 * (1. - f2) * r3; - lll_matrix[2][7] = f1 * (1. - f2) * f3; - - lll_matrix[3][0] = r1 * (1. - r2) * (1. - r3); - lll_matrix[3][1] = r1 * (1. - r2) * (1. - f3); - lll_matrix[3][2] = r1 * (1. - f2) * (1. - r3); - lll_matrix[3][3] = r1 * (1. - f2) * (1. - f3); - lll_matrix[3][4] = f1 * (1. - r2) * (1. - r3); - lll_matrix[3][5] = f1 * (1. - r2) * (1. - f3); - lll_matrix[3][6] = f1 * (1. - f2) * (1. - r3); - lll_matrix[3][7] = f1 * (1. - f2) * (1. - f3); - - lll_matrix[4][0] = (1. - r1) * r2 * r3; - lll_matrix[4][1] = (1. - r1) * r2 * f3; - lll_matrix[4][2] = (1. - r1) * f2 * r3; - lll_matrix[4][3] = (1. - r1) * f2 * f3; - lll_matrix[4][4] = (1. - f1) * r2 * r3; - lll_matrix[4][5] = (1. - f1) * r2 * f3; - lll_matrix[4][6] = (1. - f1) * f2 * r3; - lll_matrix[4][7] = (1. - f1) * f2 * f3; - - lll_matrix[5][0] = (1. - r1) * r2 * (1. - r3); - lll_matrix[5][1] = (1. - r1) * r2 * (1. - f3); - lll_matrix[5][2] = (1. - r1) * f2 * (1. - r3); - lll_matrix[5][3] = (1. - r1) * f2 * (1. - f3); - lll_matrix[5][4] = (1. - f1) * r2 * (1. - r3); - lll_matrix[5][5] = (1. - f1) * r2 * (1. - f3); - lll_matrix[5][6] = (1. - f1) * f2 * (1. - r3); - lll_matrix[5][7] = (1. - f1) * f2 * (1. - f3); - - lll_matrix[6][0] = (1. - r1) * (1. - r2) * r3; - lll_matrix[6][1] = (1. - r1) * (1. - r2) * f3; - lll_matrix[6][2] = (1. - r1) * (1. - f2) * r3; - lll_matrix[6][3] = (1. - r1) * (1. - f2) * f3; - lll_matrix[6][4] = (1. - f1) * (1. - r2) * r3; - lll_matrix[6][5] = (1. - f1) * (1. - r2) * f3; - lll_matrix[6][6] = (1. - f1) * (1. - f2) * r3; - lll_matrix[6][7] = (1. - f1) * (1. - f2) * f3; - - lll_matrix[7][0] = (1. - r1) * (1. - r2) * (1. - r3); - lll_matrix[7][1] = (1. - r1) * (1. - r2) * (1. - f3); - lll_matrix[7][2] = (1. - r1) * (1. - f2) * (1. - r3); - lll_matrix[7][3] = (1. - r1) * (1. - f2) * (1. - f3); - lll_matrix[7][4] = (1. - f1) * (1. - r2) * (1. - r3); - lll_matrix[7][5] = (1. - f1) * (1. - r2) * (1. - f3); - lll_matrix[7][6] = (1. - f1) * (1. - f2) * (1. - r3); - lll_matrix[7][7] = (1. - f1) * (1. - f2) * (1. - f3); - - i_lll_matrix = lll_matrix; - i_lll_matrix.InvertFast(); - -} - -double MatrixUtils::trilepton_weight(bool l1, bool l2, bool l3){ - - double nttt=(((!l1)&&(!l2)&&(!l3))?1.:0.); - double nttl=(((!l1)&&(!l2)&&( l3))?1.:0.); - double ntlt=(((!l1)&&( l2)&&(!l3))?1.:0.); - double ntll=(((!l1)&&( l2)&&( l3))?1.:0.); - double nltt=((( l1)&&(!l2)&&(!l3))?1.:0.); - double nltl=((( l1)&&(!l2)&&( l3))?1.:0.); - double nllt=((( l1)&&( l2)&&(!l3))?1.:0.); - double nlll=((( l1)&&( l2)&&( l3))?1.:0.); - - double nrrf = i_lll_matrix[1][0] * nttt + i_lll_matrix[1][1] * nttl + i_lll_matrix[1][2] * ntlt + i_lll_matrix[1][3] * ntll - + i_lll_matrix[1][4] * nltt + i_lll_matrix[1][5] * nltl + i_lll_matrix[1][6] * nllt + i_lll_matrix[1][7] * nlll; - double nrfr = i_lll_matrix[2][0] * nttt + i_lll_matrix[2][1] * nttl + i_lll_matrix[2][2] * ntlt + i_lll_matrix[2][3] * ntll - + i_lll_matrix[2][4] * nltt + i_lll_matrix[2][5] * nltl + i_lll_matrix[2][6] * nllt + i_lll_matrix[2][7] * nlll; - double nrff = i_lll_matrix[3][0] * nttt + i_lll_matrix[3][1] * nttl + i_lll_matrix[3][2] * ntlt + i_lll_matrix[3][3] * ntll - + i_lll_matrix[3][4] * nltt + i_lll_matrix[3][5] * nltl + i_lll_matrix[3][6] * nllt + i_lll_matrix[3][7] * nlll; - double nfrr = i_lll_matrix[4][0] * nttt + i_lll_matrix[4][1] * nttl + i_lll_matrix[4][2] * ntlt + i_lll_matrix[4][3] * ntll - + i_lll_matrix[4][4] * nltt + i_lll_matrix[4][5] * nltl + i_lll_matrix[4][6] * nllt + i_lll_matrix[4][7] * nlll; - double nfrf = i_lll_matrix[5][0] * nttt + i_lll_matrix[5][1] * nttl + i_lll_matrix[5][2] * ntlt + i_lll_matrix[5][3] * ntll - + i_lll_matrix[5][4] * nltt + i_lll_matrix[5][5] * nltl + i_lll_matrix[5][6] * nllt + i_lll_matrix[5][7] * nlll; - double nffr = i_lll_matrix[6][0] * nttt + i_lll_matrix[6][1] * nttl + i_lll_matrix[6][2] * ntlt + i_lll_matrix[6][3] * ntll - + i_lll_matrix[6][4] * nltt + i_lll_matrix[6][5] * nltl + i_lll_matrix[6][6] * nllt + i_lll_matrix[6][7] * nlll; - double nfff = i_lll_matrix[7][0] * nttt + i_lll_matrix[7][1] * nttl + i_lll_matrix[7][2] * ntlt + i_lll_matrix[7][3] * ntll - + i_lll_matrix[7][4] * nltt + i_lll_matrix[7][5] * nltl + i_lll_matrix[7][6] * nllt + i_lll_matrix[7][7] * nlll; - - double nrrf_TT = lll_matrix[0][1] * nrrf; - double nrfr_TT = lll_matrix[0][2] * nrfr; - double nrff_TT = lll_matrix[0][3] * nrff; - double nfrr_TT = lll_matrix[0][4] * nfrr; - double nfrf_TT = lll_matrix[0][5] * nfrf; - double nffr_TT = lll_matrix[0][6] * nffr; - double nfff_TT = lll_matrix[0][6] * nfff; - - return nrrf_TT + nrfr_TT + nrff_TT + nfrr_TT + nfrf_TT + nffr_TT + nfff_TT; - -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/TopFakesMMWeightCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/TopFakesMMWeightCalculator.cxx deleted file mode 100644 index 3612d0842b56..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/TopFakesMMWeightCalculator.cxx +++ /dev/null @@ -1,864 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -////////////////////////////////////////////////////////////////////// -// -// Author : -// Timothée Theveneaux-Pelzer -// Creation : -// Purpose : helper to be used in analyses -// -// Updated : -// 2016-01-29 : FD: set default values for Run2 and 1st efficiencies -////////////////////////////////////////////////////////////////////// - -#include "TopFakes/TopFakesMMWeightCalculator.h" -#include "TopFakes/TopFakesxAODUtils.h" -#include "TopConfiguration/TopConfig.h" -#include "TopConfiguration/ConfigurationSettings.h" -// #include "TopEvent/Event.h" -#include "TopEvent/EventTools.h" -#include "TopEvent/TopEventMaker.h" -#include "TopFakes/FakesWeights.h" -#include "TopFakes/MMEfficiency.h" -#include "TopFakes/MatrixUtils.h" -#include "TopFakes/MMEffSet.h" -#define XXX std::cout << "I am here: " << __FILE__ << ":" << __LINE__ << std::endl; - -namespace top{ - - TopFakesMMWeightCalculator::TopFakesMMWeightCalculator( const std::string& name ) : - asg::AsgTool( name ), - m_config(nullptr), - m_dir(""), - m_debug(false)//, -// m_leptonDefs(fakes::LeptonDefinitions::Standard) - { - ATH_MSG_INFO(" constructor of top::TopFakesMMWeightCalculator "+name ); - declareProperty( "config" , m_config ); - } - - TopFakesMMWeightCalculator::~TopFakesMMWeightCalculator() - { - } - - // ============================================================= - StatusCode TopFakesMMWeightCalculator::initialize() - { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator initialize" ); - - m_dir = m_config->FakesMMDir(); - m_debug = m_config->FakesMMDebug(); - ATH_MSG_INFO(" Directory for efficiencies: "+m_dir ); - if (std::find(m_config->bTagWP_available().begin(), m_config->bTagWP_available().end(), "FixedCutBEff_77") == m_config->bTagWP_available().end()) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator initialize" ); - std::cout<<"B-tagging WP FixedCutBEff_77 is needed to parametrise efficiencies."<<std::endl; - std::cout<<"Please set it up by writing \"BTaggingWP FixedCutBEff_77\" or \"BTaggingWP %77\" in your configuration file."<<std::endl; - return StatusCode::FAILURE; - } - - return StatusCode::SUCCESS; - } - - StatusCode TopFakesMMWeightCalculator::setSelectionConfigs(std::string selection, std::vector<std::string> configs) - { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - - auto* const settings = top::ConfigurationSettings::get(); - const std::vector<top::SelectionConfigurationData> selections = settings->selections(); - for(std::string config : configs){ - std::istringstream ss(config); - std::vector<std::string> listofkeys; - std::string token; - while(std::getline(ss, token, ',')) {//parameters are separated by commas - listofkeys.push_back(token); - } - // check if number of parameters is ok - if (listofkeys.size()<3 || listofkeys.size()>7) {//need at least 3 and no more than 7 parameters - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - return StatusCode::FAILURE; - } - - // check if configuration already defined for another selection - if (m_fakesWeightTools.count(selection) !=0) { - if (m_fakesWeightTools[selection].count(listofkeys.at(0)) !=0) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The configuration "<<listofkeys.at(0)<<"is already defined for selection "<<selection<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - } - - // first argument must define the period - check if it's valid - int period = getPeriod(listofkeys.at(1)); - if (period == -1) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"Can't recognise period "<<listofkeys.at(1)<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - } - - // second argument is the channel - if (listofkeys.at(2)=="EJETS") { - if (listofkeys.size()<3 || listofkeys.size()>5) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(2)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Correct syntax (1): <config name>,EJETS"<<std::endl; - std::cout<<"Correct syntax (2): <config name>,EJETS,<systematic variation>"<<std::endl; - std::cout<<"Correct syntax (3): <config name>,EJETS,<real eff configuration>,<fake eff configuration>"<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)] = std::shared_ptr<FakesWeights>(new FakesWeights()); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDebug(m_debug); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDataPath(m_dir); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetPeriod(period); - if (listofkeys.size()==3) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::EJETS); - } - else if (listofkeys.size()==4) { - if (listofkeys.at(3)!="MCup" && listofkeys.at(3)!="MCdown" && listofkeys.at(3)!="MCupel" && listofkeys.at(3)!="MCdownel" && listofkeys.at(3)!="CRfake" && listofkeys.at(3)!="CRfakeel" && listofkeys.at(3)!="CRreal" && listofkeys.at(3)!="CRrealel" && listofkeys.at(3)!="EffPar") { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Systematic variation "<<listofkeys.at(2)<<" not recognised."<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::EJETS,listofkeys.at(3)); - } - } - else if (listofkeys.size()==5) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighter(FakesWeights::EJETS,listofkeys.at(3),listofkeys.at(4)); - } - } - } - else if (listofkeys.at(2)=="MUJETS") { - if (listofkeys.size()<3 || listofkeys.size()>5) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Correct syntax (1): <config name>,MUJETS"<<std::endl; - std::cout<<"Correct syntax (2): <config name>,MUJETS,<systematic variation>"<<std::endl; - std::cout<<"Correct syntax (3): <config name>,MUJETS,<real eff configuration>,<fake eff configuration>"<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)] = std::shared_ptr<FakesWeights>(new FakesWeights()); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDebug(m_debug); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDataPath(m_dir); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetPeriod(period); - if (listofkeys.size()==3) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::MUJETS); - } - else if (listofkeys.size()==4) { - if (listofkeys.at(3)!="MCup" && listofkeys.at(3)!="MCdown" && listofkeys.at(3)!="MCupmu" && listofkeys.at(3)!="MCdownmu" && listofkeys.at(3)!="CRfake" && listofkeys.at(3)!="CRfakemu" && listofkeys.at(3)!="CRreal" && listofkeys.at(3)!="CRrealmu" && listofkeys.at(3)!="EffPar") { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Systematic variation "<<listofkeys.at(3)<<" not recognised."<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::MUJETS,listofkeys.at(3)); - } - } - else if (listofkeys.size()==5) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighter(FakesWeights::MUJETS,listofkeys.at(3),listofkeys.at(4)); - } - } - } - else if (listofkeys.at(2)=="EE") { - if (listofkeys.size()<3 || listofkeys.size()>5) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Correct syntax (1): <config name>,EE"<<std::endl; - std::cout<<"Correct syntax (2): <config name>,EE,<systematic variation>"<<std::endl; - std::cout<<"Correct syntax (3): <config name>,EE,<real eff configuration>,<fake eff configuration>"<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)] = std::shared_ptr<FakesWeights>(new FakesWeights()); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDebug(m_debug); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDataPath(m_dir); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetPeriod(period); - if (listofkeys.size()==3) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::EE); - } - else if (listofkeys.size()==4) { - if (listofkeys.at(3)!="MCup" && listofkeys.at(3)!="MCdown" && listofkeys.at(3)!="MCupel" && listofkeys.at(3)!="MCdownel" && listofkeys.at(3)!="CRfake" && listofkeys.at(3)!="CRfakeel" && listofkeys.at(3)!="CRreal" && listofkeys.at(3)!="CRrealel" && listofkeys.at(3)!="EffPar") { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Systematic variation "<<listofkeys.at(3)<<" not recognised."<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::EE,listofkeys.at(3)); - } - } - else if (listofkeys.size()==4) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighter(FakesWeights::EE,listofkeys.at(3),listofkeys.at(4)); - } - } - } - else if (listofkeys.at(2)=="EMU") { - if (listofkeys.size()!=3 && listofkeys.size()!=4 && listofkeys.size()!=7) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Correct syntax (1): <config name>,EMU"<<std::endl; - std::cout<<"Correct syntax (2): <config name>,EMU,<systematic variation>"<<std::endl; - std::cout<<"Correct syntax (3): <config name>,EMU,<electron real eff configuration>,<electron fake eff configuration>,<muon real eff configuration>,<muon fake eff configuration>"<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)] = std::shared_ptr<FakesWeights>(new FakesWeights()); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDebug(m_debug); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDataPath(m_dir); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetPeriod(period); - if (listofkeys.size()==3) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::EMU); - } - else if (listofkeys.size()==4) { - if (listofkeys.at(3)!="MCup" && listofkeys.at(3)!="MCdown" && listofkeys.at(3)!="MCupel" && listofkeys.at(3)!="MCdownel" && listofkeys.at(3)!="MCupmu" && listofkeys.at(3)!="MCdownmu" && listofkeys.at(3)!="CRfake" && listofkeys.at(3)!="CRfakeel" && listofkeys.at(3)!="CRfakemu" && listofkeys.at(3)!="CRreal" && listofkeys.at(3)!="CRrealel" && listofkeys.at(3)!="CRrealmu" && listofkeys.at(3)!="EffPar") { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Systematic variation "<<listofkeys.at(3)<<" not recognised."<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::EMU,listofkeys.at(3)); - } - } - else if (listofkeys.size()==7) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighter(FakesWeights::EMU,listofkeys.at(3),listofkeys.at(4),listofkeys.at(5),listofkeys.at(6)); - } - } - } - else if (listofkeys.at(2)=="MUMU") { - if (listofkeys.size()<3 || listofkeys.size()>5) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Correct syntax (1): <config name>,MUMU"<<std::endl; - std::cout<<"Correct syntax (2): <config name>,MUMU,<systematic variation>"<<std::endl; - std::cout<<"Correct syntax (3): <config name>,MUMU,<real eff configuration>,<fake eff configuration>"<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)] = std::shared_ptr<FakesWeights>(new FakesWeights()); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDebug(m_debug); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetDataPath(m_dir); - m_fakesWeightTools[selection][listofkeys.at(0)]->SetPeriod(period); - if (listofkeys.size()==3) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::MUMU); - } - else if (listofkeys.size()==4) { - if (listofkeys.at(3)!="MCup" && listofkeys.at(3)!="MCdown" && listofkeys.at(3)!="MCupmu" && listofkeys.at(3)!="MCdownmu" && listofkeys.at(3)!="CRfake" && listofkeys.at(3)!="CRfakemu" && listofkeys.at(3)!="CRreal" && listofkeys.at(3)!="CRrealmu" && listofkeys.at(3)!="EffPar") { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"The following "<<listofkeys.at(1)<<" configuration is ill-defined:"<<std::endl; - std::cout<<config<<std::endl; - std::cout<<"Systematic variation "<<listofkeys.at(3)<<" not recognised."<<std::endl; - std::cout<<"Exiting.... "<<std::endl; - return StatusCode::FAILURE; - } - else { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighterDefault(FakesWeights::MUMU,listofkeys.at(3)); - } - } - else if (listofkeys.size()==5) { - m_fakesWeightTools[selection][listofkeys.at(0)]->SetupWeighter(FakesWeights::MUMU,listofkeys.at(3),listofkeys.at(4)); - } - } - } - else { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator setSelectionConfigs" ); - std::cout<<"Unknown configuration type "<<listofkeys.at(1)<<" of configuration "<<listofkeys.at(0)<<" for selection "<<selection<<std::endl; - return StatusCode::FAILURE; - } - } - return StatusCode::SUCCESS; - } - - // =========================================================== - StatusCode TopFakesMMWeightCalculator::execute(top::Event* topEvent) - { - const xAOD::EventInfo* event_info = topEvent->m_info; - const xAOD::ElectronContainer* electrons = &topEvent->m_electrons; - const xAOD::MuonContainer* muons = &topEvent->m_muons; - const xAOD::JetContainer* jets = &topEvent->m_jets; - const xAOD::MissingET* MET = topEvent->m_met; - - if (event_info->eventType(xAOD::EventInfo::IS_SIMULATION)) {// no MM weight to be calculated for MC events - return StatusCode::SUCCESS; - } - else { - auto* const settings = top::ConfigurationSettings::get(); - const std::vector<top::SelectionConfigurationData> selections = settings->selections(); - for(auto scd : selections){//loop on selections - bool pass = false; - if (event_info->isAvailable<int>(scd.m_name)) - pass = event_info->auxdataConst<int>(scd.m_name); - if (!pass) - continue;// if the selection is not passed, don't decorate the event with MM weight - for(auto configs : m_fakesWeightTools[scd.m_name]) {// loop on the configurations associated to this selection - std::string config_name = configs.first; - std::string decorName = "MMWeight_"; decorName += scd.m_name; decorName += "_"; decorName += config_name; - if (event_info->isAvailable<float>(decorName)) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator execute" ); - std::cout<<"Current event already decorated with "<<decorName<<std::endl; - std::cout<<"Don't want to re-calculate it. Exiting... "<<std::endl; - return StatusCode::FAILURE; - } - float mmweight = -999.; - auto weighter = m_fakesWeightTools[scd.m_name][config_name]; - if (weighter==nullptr) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator execute" ); - std::cout<<"Weighter is not defined for "<<scd.m_name<<" "<<config_name<<std::endl; - std::cout<<"Exiting... "<<std::endl; - return StatusCode::FAILURE; - } - if (m_debug) { - std::cout<<"=====================================>Selection: "<<scd.m_name<<" Configuration: "<<config_name<<std::endl; - } - if (weighter->Channel()==FakesWeights::EJETS) { - try { - mmweight = getMMweightE(weighter, *MET, *electrons, *jets, event_info); - } - catch(std::exception& e) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator execute" ); - std::cout<<"Could not calculate EJETS MM weight for "<<decorName<<std::endl; - std::cout<<"Exiting... "<<std::endl; - return StatusCode::FAILURE; - } - } - else if (weighter->Channel()==FakesWeights::MUJETS) { - try { - mmweight = getMMweightM(weighter, *MET, *muons, *jets, event_info); - } - catch(std::exception& e) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator execute" ); - std::cout<<"Could not calculate MUJETS weight for "<<decorName<<std::endl; - std::cout<<"Exiting... "<<std::endl; - return StatusCode::FAILURE; - } - } - else if (weighter->Channel()==FakesWeights::EE) { - try { - mmweight = getMMweightEE(weighter, *MET, *electrons, *jets, event_info); - } - catch(std::exception& e) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator execute" ); - std::cout<<"Could not calculate EE weight for "<<decorName<<std::endl; - std::cout<<"Exiting... "<<std::endl; - return StatusCode::FAILURE; - } - } - else if (weighter->Channel()==FakesWeights::MUMU) { - try { - mmweight = getMMweightMM(weighter, *MET, *muons, *jets, event_info); - } - catch(std::exception& e) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator execute" ); - std::cout<<"Could not calculate MUMU weight for "<<decorName<<std::endl; - std::cout<<"Exiting... "<<std::endl; - return StatusCode::FAILURE; - } - } - else if (weighter->Channel()==FakesWeights::EMU) { - try { - mmweight = getMMweightEM(weighter, *MET, *electrons, *muons, *jets, event_info); - } - catch(std::exception& e) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator execute" ); - std::cout<<"Could not calculate EMU weight for "<<decorName<<std::endl; - std::cout<<"Exiting... "<<std::endl; - return StatusCode::FAILURE; - } - } - else { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator execute" ); - std::cout<<"Unable to retrieve the channel of FakesWeights object while calculating weight "<<decorName<<std::endl; - std::cout<<"Exiting... "<<std::endl; - return StatusCode::FAILURE; - } - event_info->auxdecor<float>(decorName) = mmweight; - } - } - } - return StatusCode::SUCCESS; - } - - // ================================================================== - float TopFakesMMWeightCalculator::getMMweightE(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::ElectronContainer& els, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info) - { - // - // Compute weight for e+jets channel - // - float mmWeightE = 0; - - /// not used for the moment -// std::vector<unsigned int> good_els_index = fakes::GetGoodHighPtLeptons(els); - - if (els.size()<1) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator::getMMweightE" ); - throw std::runtime_error("Need at least one electron to calculate EJETS matrix-method weight"); - } - - // if more than 1 electron, just take the leading one (i.e. the first in the container) - MMLepton *lept = getLeptonMMInfo(*els[0], jets, met, event_info); - MMEvent *evt = getEventMMInfo(jets, met); - - if (lept==0 || evt==0) { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator::getMMweightE" ); - ATH_MSG_INFO(" Unable to define MMLepton or MMEvent object" ); - mmWeightE = -999.; - } - else { - weighter->SetLepton(*evt,*lept); - mmWeightE = weighter->GetFakesWeightLJets(els[0]->auxdataConst<char>("passPreORSelection")); - } - - delete lept; - delete evt; - - if (m_debug) { - std::cout<<"==============>mmWeightE="<<mmWeightE<<std::endl; - std::cout<<"====>r1="<<weighter->GetRealEff()<<" f1="<<weighter->GetFakeEff()<<std::endl; - } - - return mmWeightE; - } - - // ================================================================== - float TopFakesMMWeightCalculator::getMMweightM(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::MuonContainer& mus, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info) - { - // - // Compute weight for m+jets channel - // - float mmWeightM = 0; - - /// not used for the moment -// std::vector<unsigned int> good_mus_index = fakes::GetGoodHighPtLeptons(mus); - - if (mus.size()<1) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator::getMMweightM" ); - throw std::runtime_error("Need at least one muon to calculate MUJETS matrix-method weight"); - } - - // if more than 1 muon, just take the leading one (i.e. the first in the container) - MMLepton *lept = getLeptonMMInfo(*mus[0], jets, met, event_info); - MMEvent *evt = getEventMMInfo(jets, met); - - if (lept==0 || evt==0) { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator::getMMweightM" ); - ATH_MSG_INFO(" Unable to define MMLepton or MMEvent object" ); - mmWeightM = -999.; - } - else { - weighter->SetLepton(*evt,*lept); - mmWeightM = weighter->GetFakesWeightLJets(mus[0]->auxdataConst<char>("passPreORSelection")); - } - - delete lept; - delete evt; - - if (m_debug) { - std::cout<<"==============>mmWeightM="<<mmWeightM<<std::endl; - std::cout<<"====>r1="<<weighter->GetRealEff()<<" f1="<<weighter->GetFakeEff()<<std::endl; - } - - return mmWeightM; - } - - // ================================================================== - float TopFakesMMWeightCalculator::getMMweightEE(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::ElectronContainer& els, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info) - { - // - // Compute weight for ee channel - // - float mmWeightEE = 0; - - /// not used for the moment -// std::vector<unsigned int> good_els_index = fakes::GetGoodHighPtLeptons(els); - - if (els.size()<2) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator::getMMweightEE" ); - throw std::runtime_error("Need at least two electrons to calculate EE matrix-method weight"); - } - - // if more than 2 electrons, just take the two leading ones (i.e. the first in the container) - MMLepton *lept_e1 = getLeptonMMInfo(*els[0], jets, met, event_info); - MMLepton *lept_e2 = getLeptonMMInfo(*els[1], jets, met, event_info); - MMEvent *evt = getEventMMInfo(jets, met); - - if (lept_e1==0 || lept_e2==0 || evt==0) { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator::getMMweightEE" ); - ATH_MSG_INFO(" Unable to define MMLepton or MMEvent object" ); - mmWeightEE = 0.; - } - else { - weighter->SetLeptons(*evt,*lept_e1,*lept_e2); - mmWeightEE = weighter->GetFakesWeightDilep(els[0]->auxdataConst<char>("passPreORSelection"),els[1]->auxdataConst<char>("passPreORSelection")); - } - - delete lept_e1; - delete lept_e2; - delete evt; - - if (m_debug) { - std::cout<<"==============>mmWeightEE="<<mmWeightEE<<std::endl; - std::cout<<"====>r1="<<weighter->GetRealEff()<<" f1="<<weighter->GetFakeEff()<<" r2="<<weighter->GetRealEff2()<<" f2="<<weighter->GetFakeEff2()<<std::endl; - } - - return mmWeightEE; - } - - // ================================================================== - float TopFakesMMWeightCalculator::getMMweightMM(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::MuonContainer& mus, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info) - { - // - // Compute weight for mm channel - // - float mmWeightMM = 0; - - /// not used for the moment -// std::vector<unsigned int> good_mus_index = fakes::GetGoodHighPtLeptons(mus); - - if (mus.size()<2) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator::getMMweightMM" ); - throw std::runtime_error("Need at least two muons to calculate MUMU matrix-method weight"); - } - - // if more than 2 muons, just take the two leading ones (i.e. the first in the container) - MMLepton *lept_m1 = getLeptonMMInfo(*mus[0], jets, met, event_info); - MMLepton *lept_m2 = getLeptonMMInfo(*mus[1], jets, met, event_info); - MMEvent *evt = getEventMMInfo(jets, met); - - if (lept_m1==0 || lept_m2==0 || evt==0) { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator::getMMweightMM" ); - ATH_MSG_INFO(" Unable to define MMLepton or MMEvent object" ); - mmWeightMM = 0.; - } - else { - weighter->SetLeptons(*evt,*lept_m1,*lept_m2); - mmWeightMM = weighter->GetFakesWeightDilep(mus[0]->auxdataConst<char>("passPreORSelection"),mus[1]->auxdataConst<char>("passPreORSelection")); - } - - delete lept_m1; - delete lept_m2; - delete evt; - - if (m_debug) { - std::cout<<"==============>mmWeightMM="<<mmWeightMM<<std::endl; - std::cout<<"====>r1="<<weighter->GetRealEff()<<" f1="<<weighter->GetFakeEff()<<" r2="<<weighter->GetRealEff2()<<" f2="<<weighter->GetFakeEff2()<<std::endl; - } - - return mmWeightMM; - } - - // ================================================================== - float TopFakesMMWeightCalculator::getMMweightEM(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::ElectronContainer& els, const xAOD::MuonContainer& mus, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info) - { - // - // Compute weight for em channel - // - float mmWeightEM = 0; - - /// not used for the moment -// std::vector<unsigned int> good_els_index = fakes::GetGoodHighPtLeptons(els); -// std::vector<unsigned int> good_mus_index = fakes::GetGoodHighPtLeptons(mus); - - if (els.size()<1) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator::getMMweightEM" ); - throw std::runtime_error("Need at least one electron to calculate EMU matrix-method weight"); - } - if (mus.size()<1) { - ATH_MSG_ERROR(" top::TopFakesMMWeightCalculator::getMMweightEM" ); - throw std::runtime_error("Need at least one muon to calculate EMU matrix-method weight"); - } - - // if more than 1 electron or 1 muon, just take the two leading ones (i.e. the first in the container) - MMLepton *lept_e = getLeptonMMInfo(*els[0], jets, met, event_info); - MMLepton *lept_m = getLeptonMMInfo(*mus[0], jets, met, event_info); - MMEvent *evt = getEventMMInfo(jets, met); - - if (lept_e==0 || lept_m==0 || evt==0) { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator::getMMweightEMU" ); - ATH_MSG_INFO(" Unable to define MMLepton or MMEvent object" ); - mmWeightEM = 0.; - } - else { - weighter->SetLeptons(*evt,*lept_e,*lept_m); - mmWeightEM = weighter->GetFakesWeightDilep(els[0]->auxdataConst<char>("passPreORSelection"),mus[0]->auxdataConst<char>("passPreORSelection")); - } - - delete lept_e; - delete lept_m; - delete evt; - - if (m_debug) { - std::cout<<"==============>mmWeightEM="<<mmWeightEM<<std::endl; - std::cout<<"====>r1="<<weighter->GetRealEff()<<" f1="<<weighter->GetFakeEff()<<" r2="<<weighter->GetRealEff2()<<" f2="<<weighter->GetFakeEff2()<<std::endl; - } - - return mmWeightEM; - } - - // =============================================================== - MMLepton* TopFakesMMWeightCalculator::getLeptonMMInfo(const xAOD::Electron& el, const xAOD::JetContainer& jets, const xAOD::MissingET& met, const xAOD::EventInfo* event_info) - { - float eta_cl = el.caloCluster()->etaBE(2); -// float eta = el.eta(); -// float phi = el.phi(); - float pt = el.pt()/1.e3; // tool needs GeV - unsigned int runNumber = event_info -> runNumber(); - if (m_config->isMC() && m_config->doPileupReweighting()) { - if (event_info->isAvailable<unsigned int>("RandomRunNumber")) - runNumber = event_info->auxdataConst<unsigned int>("RandomRunNumber"); - } - int trigger = 0.; - top::fakes::GetTrigMatchVariable(el, trigger, runNumber); - - const xAOD::TrackParticle* eltrack = el.trackParticle(); - float d0 = eltrack->d0(); - const xAOD::ParametersCovMatrix_t elcov = eltrack->definingParametersCovMatrix(); - float d0signif = d0/sqrt(elcov(0,0)); - - float dR; - float pTj; - float dRCentral; - float pTjCentral; - float dRpt; - float dRptCentral; - fakes::GetClosestJet (el, jets, dR, pTj, dRpt, dRCentral, pTjCentral, dRptCentral); - - float dphilmet; - fakes::GetdPhiLepMET (el, met, dphilmet); - - MMLepton* lept = new MMLepton(); - lept->pt = pt; - lept->eta = std::fabs(eta_cl); - lept->dR = dR; - lept->dPhi = dphilmet; - lept->trigger = trigger; - lept->d0sig = d0signif; - - if (m_debug) { - std::cout<<"Electron"; - std::cout<<" pt="<<pt; - std::cout<<" eta="<<std::fabs(eta_cl); - std::cout<<" dR="<<dR; - std::cout<<" dPhi="<<dphilmet; - std::cout<<" trigger="<<trigger; - std::cout<<" d0sig="<<d0signif; - std::cout<<std::endl; - } - - return lept; - } - - // =========================================================== - MMLepton* TopFakesMMWeightCalculator::getLeptonMMInfo(const xAOD::Muon& mu, const xAOD::JetContainer& jets, const xAOD::MissingET& met, const xAOD::EventInfo* event_info) - { - float eta = mu.eta(); -// float phi = mu.phi(); - float pt = mu.pt()/1.e3; // tool needs GeV - unsigned int runNumber = event_info -> runNumber(); - if (m_config->isMC() && m_config->doPileupReweighting()) { - if (event_info->isAvailable<unsigned int>("RandomRunNumber")) - runNumber = event_info->auxdataConst<unsigned int>("RandomRunNumber"); - } - int trigger = 0.; - top::fakes::GetTrigMatchVariable(mu, trigger, runNumber); - - const xAOD::TrackParticle* mutrack = mu.primaryTrackParticle(); - float d0 = mutrack->d0(); - const xAOD::ParametersCovMatrix_t mucov=mutrack->definingParametersCovMatrix(); - float d0signif = d0/sqrt(mucov(0,0)); - - float dR; - float pTj; - float dRCentral; - float pTjCentral; - float dRpt; - float dRptCentral; - fakes::GetClosestJet (mu, jets, dR, pTj, dRpt, dRCentral, pTjCentral, dRptCentral); - - float dphilmet; - fakes::GetdPhiLepMET (mu, met, dphilmet); - - MMLepton* lept = new MMLepton(); - lept->pt = pt; - lept->eta = std::fabs(eta); - lept->dR = dR; - lept->dPhi = dphilmet; - lept->trigger = trigger; - lept->d0sig = d0signif; - - if (m_debug) { - std::cout<<"Muon"; - std::cout<<" pt="<<pt; - std::cout<<" eta="<<std::fabs(eta); - std::cout<<" dR="<<dR; - std::cout<<" dRpt="<<dRpt; - std::cout<<" dPhi="<<dphilmet; - std::cout<<" trigger="<<trigger; - std::cout<<" d0sig="<<d0signif; - std::cout<<std::endl; - } - - return lept; - } - - // ============================================================ - MMEvent* TopFakesMMWeightCalculator::getEventMMInfo(const xAOD::JetContainer& jets, const xAOD::MissingET& met) - { - float leadingJetpT = -999.; - float leadingCentralJetpT = -999.; - unsigned int Njets = 0; - unsigned int NCentraljets = 0; - unsigned int nbtag = 0; - for (const auto* const jetPtr : jets) { - if (jetPtr->pt()<25000.) continue; - Njets++; - if (jetPtr->pt()>leadingJetpT) leadingJetpT = jetPtr->pt(); - if (jetPtr->eta()<2.5) { - NCentraljets++; - if (jetPtr->pt()>leadingCentralJetpT) leadingCentralJetpT = jetPtr->pt()/1000.; - } - - if (jetPtr->isAvailable<char>("isbtagged_FixedCutBEff_77")) { - if (jetPtr->auxdataConst<char>("isbtagged_FixedCutBEff_77")) nbtag++; - } - } - - MMEvent* evnt = new MMEvent(); - evnt->njets = NCentraljets; - evnt->ntag = nbtag; - evnt->jetpt = leadingCentralJetpT; - evnt->sumet = met.sumet()/1e3;//tool needs GeV - - if (m_debug) { - std::cout<<"Event"; - std::cout<<" njets="<<NCentraljets; - std::cout<<" ntag="<<nbtag; - std::cout<<" jetpt="<<leadingCentralJetpT; - std::cout<<" sumet="<<met.sumet()/1e3;//tool needs GeV - std::cout<<" met="<<met.met()/1e3;//tool needs GeV - std::cout<<" metx="<<met.mpx()/1e3;//tool needs GeV - std::cout<<" mety="<<met.mpy()/1e3;//tool needs GeV - std::cout<<" metphi="<<met.phi(); - std::cout<<std::endl; - } - - return evnt; - } - - std::vector<std::string> TopFakesMMWeightCalculator::GetFakesMMConfigNames(std::string selection) const - { - std::vector<std::string> configs; - if (m_fakesWeightTools.count(selection) !=0) { - for (auto config : m_fakesWeightTools.at(selection)) - configs.push_back(config.first); - } - return configs; - } - - int TopFakesMMWeightCalculator::getPeriod( const std::string& period_string ) - { - if (period_string == "2012") { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator getPeriod: can't use 2012 fakes in xAOD framework - returning -1" ); - return -1; - } - else if (period_string == "2015") { - return MMEffSet::Period::Year2015; - } - else if (period_string == "2016") { - return MMEffSet::Period::Year2016; - } - else { - ATH_MSG_INFO(" top::TopFakesMMWeightCalculator getPeriod: can't recognise any valid period - returning -1" ); - return -1; - } - } - - // ============================================================= - ///This function checks if the lepton ID, isolation, etc... match one of those supported by Top-Fakes - ///Currently only the "standard" definition is supported - ///The list of definitions could be expanded in TopFakesxAODUtils (the top::fakes::LeptonDefinitions enum class) - ///The function also checks the pT range of the leptons - this allows users to have leptons with pT<25GeV (they are ignored) - and the eta range of the jets - this allows users to have forward jets (they are ignored too) -// void TopFakesMMWeightCalculator::CheckConfiguration() -// { -// if (m_config == nullptr) { -// m_leptonDefs = fakes::LeptonDefinitions::Other; -// std::cout<<"Warning: TopFakesMMWeightCalculator::CheckLeptonDefs() was unable to assess the configuration; therefore dummy matrix-method weights will be returned"<<std::endl; -// } -// else { -// if ( m_config->electronID() == "TightLH" -// && m_config->electronIDLoose() == "MediumLH" -// && m_config->electronIsolation() == "Gradient" -// && m_config->electronIsolationLoose() == "None" -// && m_config->muonQuality() == "Medium" -// && m_config->muonQualityLoose() == "Loose" -// && m_config->muonIsolation() == "Gradient" -// && m_config->muonIsolationLoose() == "None" ) { -// m_leptonDefs = fakes::LeptonDefinitions::Standard; -// //now do checks on object definitions -// //electrons -// if (m_config->electronPtcut() < 25000.) { -// std::cout<<"Warning: electrons below pT=25GeV are used (pT cut is at "<<m_config->electronPtcut()/1000.<<"GeV). This is non-standard and not yet supported by TopFakes; therefore all electrons below this threshold will be ignored in the calculation of matrix-method weights."<<std::endl; -// } -// else if (m_config->electronPtcut() != 25000.) { -// std::cout<<"Warning: non-standard electron pT cut of "<<m_config->electronPtcut()/1000.<<"GeV is used (standard is 25GeV). It may have unexpected behaviour for the calculation of matrix-method weights."<<std::endl; -// } -// if (!m_config->electronVetoLArCrack()) { -// std::cout<<"Warning: veto of electrons on LAr crack was disabled; this is non-standard and not yet supported by TopFakes"<<std::endl; -// } -// -// //muons -// if (m_config->muonPtcut() < 25000.) { -// std::cout<<"Warning: muons below pT=25GeV are used (pT cut is at "<<m_config->muonPtcut()/1000.<<"GeV). This is non-standard and not yet supported by TopFakes; therefore all muons below this threshold will be ignored in the calculation of matrix-method weights."<<std::endl; -// } -// else if (m_config->muonPtcut() != 25000.) { -// std::cout<<"Warning: non-standard muon pT cut of "<<m_config->muonPtcut()/1000.<<"GeV is used (standard is 25GeV). It may have unexpected behaviour for the calculation of matrix-method weights."<<std::endl; -// } -// if (m_config->muonEtacut() != 2.5) { -// std::cout<<"Warning: non-standard muon eta cut of "<<m_config->jetEtacut()<<" is used (standard is 2.5). It may have unexpected behaviour for the calculation of matrix-method weights."<<std::endl; -// } -// -// //jets -// if (m_config->jetEtacut() > 2.5) { -// std::cout<<"Warning: forward jets are used (eta cut is at "<<m_config->jetEtacut()<<"). This is non-standard and not yet supported by TopFakes; therefore all jets above |eta|=2.5 will be ignored in the calculation of matrix-method weights."<<std::endl; -// } -// else if (m_config->jetEtacut() != 2.5) { -// std::cout<<"Warning: non-standard jet eta cut of "<<m_config->jetEtacut()<<" is used (standard is 2.5). It may have unexpected behaviour for the calculation of matrix-method weights."<<std::endl; -// } -// if (m_config->jetPtcut() != 25000.) { -// std::cout<<"Warning: non-standard jet pT cut of "<<m_config->jetPtcut()/1000.<<"GeV is used (standard is 25GeV). It may have unexpected behaviour for the calculation of matrix-method weights."<<std::endl; -// } -// } -// else { -// std::cout<<"Warning: the used lepton definitions are not yet supported by TopFakes; therefore dummy matrix-method weights will be returned"<<std::endl; -// } -// -// -// } -// -// } -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/TopFakesxAODUtils.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/TopFakesxAODUtils.cxx deleted file mode 100644 index 3b897b603175..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/Root/TopFakesxAODUtils.cxx +++ /dev/null @@ -1,363 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -////////////////////////////////////////////////////////////////////// -// -// Author : -// Timothée Theveneaux-Pelzer -// Creation : -// Purpose : helper to be used in analyses -// -// Updated : -// 2016-02-12 : fixes for muon trigger splitting -// -////////////////////////////////////////////////////////////////////// -#include "TopFakes/TopFakesxAODUtils.h" - -#include "TopEvent/EventTools.h" -#include "TopFakes/FakesWeights.h" - - -void top::fakes::GetClosestJet (const xAOD::Electron& el, - const xAOD::JetContainer& jets, - float& dRClosetJet, - float& PtClosetJet, - float& dROverPtClosetJet, - float& dRClosetCentralJet, - float& PtClosetCentralJet, - float& dROverPtClosetCentralJet) -{ - //the dRs are initialised to a very high positive value - dRClosetJet = 999.; - dRClosetCentralJet = 999.; - //the pTs are initialised to a negative value - PtClosetJet = -999.; - PtClosetCentralJet = -999.; - // these variables are not used in fact! - dROverPtClosetJet = -999.; - dROverPtClosetCentralJet = -999.; - - for (const auto* const jetPtr : jets) { - if (jetPtr->pt()<25000.) continue; - double newdR = top::deltaR(*jetPtr,el); - if (jetPtr->eta()<2.5) { - if (newdR<dRClosetCentralJet) { - dRClosetCentralJet = newdR; - PtClosetCentralJet = jetPtr->pt()/1000.; // tool needs GeV - } - } - if (newdR<dRClosetJet) { - dRClosetJet = newdR; - PtClosetJet = jetPtr->pt()/1000.; // tool needs GeV - } - } - - // these variables are not used ! - if ((dRClosetJet!=999.) && (PtClosetJet!=-999.)) dROverPtClosetJet = dRClosetJet/PtClosetJet; - if ((dRClosetCentralJet!=999.) && (PtClosetCentralJet!=-999.)) dROverPtClosetCentralJet = dRClosetCentralJet/PtClosetCentralJet; - - //if the dRs are at their default value, give them a negative value - if (dRClosetJet == 999.) dRClosetJet = -999.; - if (dRClosetCentralJet == 999.) dRClosetCentralJet = -999.; -} - -// ============================================================ -void top::fakes::GetClosestJet (const xAOD::Muon& mu, - const xAOD::JetContainer& jets, - float& dRClosetJet, - float& PtClosetJet, - float& dROverPtClosetJet, - float& dRClosetCentralJet, - float& PtClosetCentralJet, - float& dROverPtClosetCentralJet) -{ - //the dRs are initialised to a very high positive value - dRClosetJet = 999.; - dRClosetCentralJet = 999.; - //the pTs are initialised to a negative value - PtClosetJet = -999.; - PtClosetCentralJet = -999.; - // these variables are not used - dROverPtClosetJet = -999.; - dROverPtClosetCentralJet = -999.; - - for (const auto* const jetPtr : jets) { - if (jetPtr->pt()<25000.) continue; - double newdR = top::deltaR(*jetPtr,mu); - double newdRCentral = newdR; - if (jetPtr->eta()<2.5) { - if (newdRCentral<dRClosetCentralJet) { - dRClosetCentralJet = newdRCentral; - PtClosetCentralJet = jetPtr->pt()/1000.; // tool needs GeV - } - } - if (newdR<dRClosetJet) { - dRClosetJet = newdR; - PtClosetJet = jetPtr->pt()/1000.; // tool needs GeV - } - } - - // these variables are not used - if ((dRClosetJet!=999.) && (PtClosetJet!=-999.)) dROverPtClosetJet = dRClosetJet/PtClosetJet; - if ((dRClosetCentralJet!=999.) && (PtClosetCentralJet!=-999.)) dROverPtClosetCentralJet = dRClosetCentralJet/PtClosetCentralJet; - - //if the dRs are at their default value, give them a negative value - if (dRClosetJet == 999.) dRClosetJet = -999.; - if (dRClosetCentralJet == 999.) dRClosetCentralJet = -999.; -} - -// ================================================= -void top::fakes::GetdPhiLepMET (const xAOD::Electron& el, const xAOD::MissingET& met, float& dPhi) -{ - dPhi = -999.; - if (met.mpx()!=0. && met.mpx()!=0.) { - TLorentzVector met_4vect; - met_4vect.SetPxPyPzE(met.mpx(),met.mpx(),0.,0.); - dPhi = el.p4().DeltaPhi(met_4vect); - } -} - -// ================================================== -void top::fakes::GetdPhiLepMET (const xAOD::Muon& mu, const xAOD::MissingET& met, float& dPhi) -{ - dPhi = -999.; - if (met.mpx()!=0. && met.mpx()!=0.) { - TLorentzVector met_4vect; - met_4vect.SetPxPyPzE(met.mpx(),met.mpx(),0.,0.); - dPhi = mu.p4().DeltaPhi(met_4vect); - } -} - -// ========================================================= -void top::fakes::GetTrigMatchVariable(const xAOD::Electron& el, int& trigmatch, const unsigned int runNumber) -{ - std::string release_series = ""; - const char* rel_temp = std::getenv("ROOTCORE_RELEASE_SERIES"); - if (rel_temp) { - release_series = std::string(rel_temp); - } else { - std::cerr<<"Can not access ROOTCORE_RELEASE_SERIES - exiting..."<<std::endl; - exit(1); - } - - trigmatch = 0; - bool trig_lowpTIso,trig_hightpTNoIso,trig_veryhightpTNoIso,trig_lowpTNoIso; - - if (release_series == "23") {// for 20.1 samples - try {//not really used - trig_lowpTIso is overriden below - trig_lowpTIso = el.auxdataConst<char>("TRIGMATCH_HLT_e24_lhmedium_iloose_L1EM20VH"); - } catch (std::exception& e) { - trig_lowpTIso = false; - } - try { - trig_hightpTNoIso = el.auxdataConst<char>("TRIGMATCH_HLT_e60_lhmedium"); - } catch (std::exception& e) { - trig_hightpTNoIso = false; - } - try { - trig_veryhightpTNoIso = el.auxdataConst<char>("TRIGMATCH_HLT_e120_lhloose"); - } catch (std::exception& e) { - trig_veryhightpTNoIso = false; - } - try { - trig_lowpTIso = trig_lowpTNoIso = ( el.auxdataConst<char>("TRIGMATCH_HLT_e24_lhmedium_L1EM18VH") || el.auxdataConst<char>("TRIGMATCH_HLT_e24_lhmedium_L1EM20VH") ); - } catch (std::exception& e) { - trig_lowpTIso = trig_lowpTNoIso = false; - } - } - else if (release_series == "24") {// for 20.7 samples - if (runNumber>=276262 && runNumber<=284484) { - try {//not really used - trig_lowpTIso is overriden below - trig_lowpTIso = el.auxdataConst<char>("TRIGMATCH_HLT_e24_lhmedium_iloose_L1EM20VH"); - } catch (std::exception& e) { - trig_lowpTIso = false; - } - try { - trig_hightpTNoIso = el.auxdataConst<char>("TRIGMATCH_HLT_e60_lhmedium"); - } catch (std::exception& e) { - trig_hightpTNoIso = false; - } - try { - trig_veryhightpTNoIso = el.auxdataConst<char>("TRIGMATCH_HLT_e120_lhloose"); - } catch (std::exception& e) { - trig_veryhightpTNoIso = false; - } - try { - trig_lowpTNoIso = trig_lowpTIso = el.auxdataConst<char>("TRIGMATCH_HLT_e24_lhmedium_L1EM20VH"); - } catch (std::exception& e) { - trig_lowpTNoIso = false; - } - } - else if (runNumber>=297730) { - try { - trig_lowpTIso = el.auxdataConst<char>("TRIGMATCH_HLT_HLT_e24_lhtight_nod0_ivarloose"); - } catch (std::exception& e) { - trig_lowpTIso = false; - } - try { - trig_hightpTNoIso = el.auxdataConst<char>("TRIGMATCH_HLT_HLT_e60_lhmedium_nod0"); - } catch (std::exception& e) { - trig_hightpTNoIso = false; - } - try { - trig_veryhightpTNoIso = el.auxdataConst<char>("TRIGMATCH_HLT_e140_lhloose_nod0"); - } catch (std::exception& e) { - trig_veryhightpTNoIso = false; - } - try { - trig_lowpTNoIso = ( el.auxdataConst<char>("TRIGMATCH_HLT_e24_lhmedium_L1EM20VH") ); - } catch (std::exception& e) { - trig_lowpTNoIso = false; - } - } - else { - std::cerr<<"Nothing is well-defined for runNumber "<<runNumber<<" - exiting..."<<std::endl; - exit(1); - } - } - else { - std::cerr<<"Unknown release series - exiting..."<<std::endl; - exit(1); - } - - //if (trig_lowpTIso) trigmatch |= 0x1 << 0; - //if (trig_hightpTNoIso || trig_veryhightpTNoIso) trigmatch |= 0x1 << 1; - - // NB note used for Run2 2015 as there is no trigger splitting - if (trig_lowpTIso) trigmatch |= 0x1 << 0; - if (trig_hightpTNoIso || trig_veryhightpTNoIso) trigmatch |= 0x1 << 1; - if (trig_lowpTNoIso) trigmatch |= 0x1 << 2; -} - -// =========================================================== -void top::fakes::GetTrigMatchVariable(const xAOD::Muon& mu, int& trigmatch, const unsigned int runNumber) -{ - std::string release_series = ""; - const char* rel_temp = std::getenv("ROOTCORE_RELEASE_SERIES"); - if (rel_temp) { - release_series = std::string(rel_temp); - } else { - std::cerr<<"Can not access ROOTCORE_RELEASE_SERIES - exiting..."<<std::endl; - exit(1); - } - - trigmatch = 0; - bool trig_lowpTIso,trig_hightpTNoIso,trig_lowpTNoIso; - - if (release_series == "23") {// for 20.1 samples - try { - trig_lowpTIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu20_iloose_L1MU15"); - } catch (std::exception& e) { - trig_lowpTIso = false; - } - try { - trig_hightpTNoIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu50"); - } catch (std::exception& e) { - trig_hightpTNoIso = false; - } - try { - trig_lowpTNoIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu20_L1MU15"); - } catch (std::exception& e) { - trig_lowpTNoIso = false; - } - } - else if (release_series == "24") {// for 20.7 samples - if (runNumber>=276262 && runNumber<=284484) { - try { - trig_lowpTIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu20_iloose_L1MU15"); - } catch (std::exception& e) { - trig_lowpTIso = false; - } - try { - trig_hightpTNoIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu50"); - } catch (std::exception& e) { - trig_hightpTNoIso = false; - } - try { - trig_lowpTNoIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu20_L1MU15"); - } catch (std::exception& e) { - trig_lowpTNoIso = false; - } - } - else if (runNumber>=297730) { - try { - trig_lowpTIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu24_ivarmedium"); - } catch (std::exception& e) { - trig_lowpTIso = false; - } - try { - trig_hightpTNoIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu50"); - } catch (std::exception& e) { - trig_hightpTNoIso = false; - } - try { - trig_lowpTNoIso = mu.auxdataConst<char>("TRIGMATCH_HLT_mu24"); - } catch (std::exception& e) { - trig_lowpTNoIso = false; - } - } - else { - std::cerr<<"Nothing is well-defined for runNumber "<<runNumber<<" - exiting..."<<std::endl; - exit(1); - } - } - else { - std::cerr<<"Unknown release series - exiting..."<<std::endl; - exit(1); - } - - //if (trig_lowpTIso) trigmatch |= 0x1 << 0; - //if (trig_hightpTNoIso) trigmatch |= 0x1 << 1; - - if (trig_lowpTIso) trigmatch |= 0x1 << 0; // mu20i - if (trig_hightpTNoIso) trigmatch |= 0x1 << 1; // mu50 - if (trig_lowpTNoIso) trigmatch |= 0x1 << 2; // mu20 - -} - -// ============================================================= -std::vector<unsigned int> top::fakes::GetGoodHighPtLeptons(const xAOD::ElectronContainer& els) -{ - unsigned int i(0); - std::vector<unsigned int> good_els_index; - for (const auto* const elPtr : els) {//loop on electrons - if ( elPtr->isAvailable<char>("passPreORSelectionLoose") ) {//count only leptons wigth pT>25GeV that pass selection - if ( elPtr->pt()> 25000. && (elPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) ) good_els_index.push_back(i); - } - i++; - }//loop on electrons - return good_els_index; -} - -// ============================================================= -std::vector<unsigned int> top::fakes::GetGoodHighPtLeptons(const xAOD::MuonContainer& mus) -{ - unsigned int i(0); - std::vector<unsigned int> good_mus_index; - for (const auto* const muPtr : mus) {//loop on muons - if ( muPtr->isAvailable<char>("passPreORSelectionLoose") ) {//count only leptons wigth pT>25GeV that pass selection - if ( muPtr->pt()> 25000. && (muPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) ) good_mus_index.push_back(i); - } - i++; - }//loop on muons - return good_mus_index; -} - -// ============================================================ -int top::fakes::GetChannel(const xAOD::ElectronContainer& els, - const xAOD::MuonContainer& mus) -{ - // - // - // - - unsigned int iels = GetGoodHighPtLeptons(els).size(); - unsigned int imus = GetGoodHighPtLeptons(mus).size(); - if (iels==1 && imus==0) return FakesWeights::EJETS; - else if (iels==0 && imus==1) return FakesWeights::MUJETS; - else if (iels==2 && imus==0) return FakesWeights::EE; - else if (iels==0 && imus==2) return FakesWeights::MUMU; - else if (iels==1 && imus==1) return FakesWeights::EMU; - else return -1; -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/FakesWeights.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/FakesWeights.h deleted file mode 100644 index 589036ddcd0b..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/FakesWeights.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -////////////////////////////////////////////////////////////////////// -// -// Author : -// Anna Henrichs <anna.henrichs@cern.ch> -// Michele Pinamonti <michele.pinamonti@cern.ch> -// Creation : -// Purpose : main method to retrieve event-by-event weights -// from the Matrix Method -// Updated : -// 2016-01-29 : FD: set _isRun1 = false -// set default weighter -// remove pt/dR variable, never used -////////////////////////////////////////////////////////////////////// - -#ifndef FAKESWEIGHTS_h -#define FAKESWEIGHTS_h - -#include <string> -#include <vector> -#include <map> - -#include "TopFakes/MMEffSet.h" - -class TFile; -class TH1F; -class TH2F; -class TH3F; -class MMEfficiency; -class MMEffSet; -class MatrixUtils; -class MMEvent; -class MMLepton; - -class FakesWeights{ - -public: - // CONSTRUCTOR - FakesWeights(); - // DESTRUCTOR - ~FakesWeights(); - - // channels - enum { - EJETS, // 0 - MUJETS, // 1 - EE, // 2 - MUMU, // 3 - EMU // 4 - }; - -// // estimates -// enum{ -// PARIS, // 0 -// UPPSALA -// }; - - // systematics - enum{ - NONE, // 0 - MCup, // fake eff with removal of real lepton contamination from W/Z MC +30% - totally correlated between electron and muon - MCdown, // fake eff with removal of real lepton contamination from W/Z MC -30% - totally correlated between electron and muon - MCupel, // fake eff with removal of real lepton contamination from W/Z MC +30% - only for electron - MCdownel, // fake eff with removal of real lepton contamination from W/Z MC -30% - only for electron - MCupmu, // fake eff with removal of real lepton contamination from W/Z MC +30% - only for muon - MCdownmu, // fake eff with removal of real lepton contamination from W/Z MC -30% - only for muon - CRfake, // fake eff from alternative region - returns nominal for emu channel, otherwise equivalent to CRfakeel (CRfakemu) for e+jets and ee (mu+jets and mumu) channels - CRfakeel, // fake eff from alternative region - only for electron - CRfakemu, // fake eff from alternative region - only for muon - CRreal, // real eff from alternative region - totally correlated between electron and muon - CRrealel, // real eff from alternative region - only for electron - CRrealmu, // real eff from alternative region - only for muon - EffPar //efficiencies with alternative parametrisation (only for l+jet) - }; - - //void SetProtection(bool protection); - - void SetDataPath(std::string path); - void SetDebug(bool debug); - - void SetPeriod(int period); - void SetTriggerNamesEl(std::string trig1,std::string trig2,std::string trig3); - void SetTriggerNamesMu(std::string trig1,std::string trig2,std::string trig3); - void SetTriggerPrescalesEl(float ps1,float ps2,float ps3); - void SetTriggerPrescalesMu(float ps1,float ps2,float ps3); - void SetTriggerThresholdEl(float thres); - void SetTriggerThresholdMu(float thres); - - // method to set up all tools (Weighters) - void SetupWeighter(int channel, std::string aReal, std::string aFake, std::string aReal2="", std::string aFake2=""); - - // method to set the MMEvent and MMLepton objects for l+jets - void SetLepton(MMEvent event, MMLepton lepton); - // method to set the MMEvent and MMLepton objects for dilepton - void SetLeptons(MMEvent event,MMLepton lep1, MMLepton lep2); - // method to get the weight for l+jets - float GetFakesWeightLJets(bool tight); - // method to get the weight for dilepton - float GetFakesWeightDilep(bool tight1,bool tight2); - - // methods to retrieve dilepton weight for loose-loose (LL), loose-tight (LT) - // tigh-loose (TL) and tight-tight (TT) events - float GetFakesWeightDilepLL(bool tight1,bool tight2); - float GetFakesWeightDilepLT(bool tight1,bool tight2); - float GetFakesWeightDilepTL(bool tight1,bool tight2); - float GetFakesWeightDilepTT(bool tight1,bool tight2); - - // method to set up the weighters by default - void SetupWeighterDefault(int channel, std::string name, std::string syst); - // method to set up the weighters by default - void SetupWeighterDefault(int channel, std::string syst=""); - - void SetLeptonDefault(float lep_pt, float lep_eta, float el_cl_eta, - float dR_lj_min, float dPhi_lnu, - float jet_pt0, int jet_n, int nJet_tagged, int trigger); - float GetFakesWeightLJetsDefault(bool tight, float lep_pt, float lep_eta, - float el_cl_eta, float dR_lj_min, - float dPhi_lnu, float jet_pt0, - int jet_n, int nJet_tagged, int trigger); - - // methods to get the real and fake efficiencies - float GetRealEff(); - float GetFakeEff(); - float GetRealEff2(); - float GetFakeEff2(); - - // method to retrieve the matrix - MatrixUtils* GetMatrixUtils(); - - // method to access the channel - int Channel() const {return _channel;}; - -private: - int _channel; - int _syst; - - bool _dataPathIsSet; - bool _isInitialized; - //bool _protection; - - bool _debug; - std::string _dataPath; - - MatrixUtils *_mmUtil; - - MMEffSet *_EffSet[4]; // real, fake, real2, fake2 - - int _period; - std::string _trig1_el; - std::string _trig2_el; - std::string _trig3_el; - std::string _trig1_mu; - std::string _trig2_mu; - std::string _trig3_mu; - float _ps1_el; - float _ps2_el; - float _ps3_el; - float _ps1_mu; - float _ps2_mu; - float _ps3_mu; - float _ptTres_el; - float _ptTres_mu; -}; - -#endif - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MMEffSet.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MMEffSet.h deleted file mode 100644 index 1cbbbbf70135..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MMEffSet.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - ** authors: - ** Michele Pinamonti <michele.pinamonti@cern.ch> -*/ - -#ifndef MMEFFSET_h -#define MMEFFSET_h - -#include <string> -#include <vector> -#include <map> - -class TFile; -class TH1F; -class TH2F; -class TH3F; -class MMEfficiency; -class MatrixUtils; - - -//---- -class MMLepton{ -public: - float pt; - float eta; - float cleta; - float dR; // min dR(jet-lepton) - float dRpt; // pT/dR (lepton-closest jet) - float dPhi; // dPhi(MET-lepton) - float d0sig; // d0 significance - int trigger; // trigger matching the lepton -}; - -class MMEvent{ -public: - float jetpt; // pT of the leading jet - float sumet; // met_sumet - float hthad; // sum of pT's of jets - float met; // met_et in the event - int njets; // number of jets - int ntag; // number of b-tagged jets (MV1 70%) -}; -//---- - - - -class MMEffSet{ - -public: - - enum{ - TRIGGER_MASK =1, - NJETSSHORT_MASK=2, - NJETS_MASK =4, - NBTAG_MASK =8 - }; - - // "period" - enum Period { - Year2012, // 0 - Year2015, - Year2016 - }; - - MMEffSet(bool isEle,bool isReal,bool debug=false); - ~MMEffSet(); - - void SetDataPath(std::string path="data"); - - void SetupEff(std::string aEff); - - void AddCustomSplit(std::string config); // config = "condition1:condition2:condition3_..." -> value = 0,1,2,... - void AddNumBtagSplit(); - void AddNumJetsSplit(); - void AddNumJetsShortSplit(); - void AddTriggerSplit(); - void AddNumBtagAndTriggerSplit(); - void AddNumBtagAndNumJetsSplit(); - void AddNumBtagAndNumJetsShortSplit(); - void AddNumJetsAndTriggerSplit(); - void AddNumJetsShortAndTriggerSplit(); - void AddNumBtagAndNumJetsAndTriggerSplit(); - void AddNumBtagAndNumJetsShortAndTriggerSplit(); - void ReadEfficiencies(); // to call after having set up and added splittings - - void AddCorrection(); - - void SetLepton(float v0,float v1=0,float v2=0,float v3=0,float v4=0,float v5=0,float v6=0,float v7=0,float v8=0,float v9=0); - - void SetCustom(int value); - void SetNumBtag(int nbtag); - void SetNumJets(int njets); - void SetNumJetsShort(int njets); - void SetTrigger(int trigger,float pt); // pT in GeV - - void SetNumBtagAndNumJets(int ntag,int njets); - void SetNumBtagAndNumJetsShort(int ntag,int njets); - void SetNumBtagAndTrigger(int nbtag,int trigger,float pt); - void SetNumJetsAndTrigger(int njets,int trigger,float pt); - void SetNumJetsShortAndTrigger(int njets,int trigger,float pt); - void SetNumBtagAndNumJetsAndTrigger(int nbtag,int njets,int trigger,float pt); - void SetNumBtagAndNumJetsShortAndTrigger(int nbtag,int njets,int trigger,float pt); - - void SetPtThres(int thres); // set the pT-threshold for trigger splitting (in GeV); set it to -1 to ignore it - void SetTriggerNames(std::string trig1,std::string trig2,std::string trig3); - - int TriggerValue(int trigger,float pt); - - int NumJetsValue(int njets); - int NumJetsShortValue(int njets); - int NumBtagValue(int nbtag); - - void SetLepton(MMEvent event,MMLepton lepton); - float GetEff(bool isAverage=false); - - void SetPeriod(int period); - void SetTriggerPrescales(float ps1,float ps2,float ps3); - void SetTriggerThreshold(float thres); - - float GetPrescale(); - -private: - void ReadEfficiency(MMEfficiency *eff,std::string aEff,std::string condition="",bool isCorrection=false); - void ParseOptions(std::string s,std::map<std::string,std::string> *m); - - MMEvent _event; - MMLepton _lepton; - - std::string _Estimate; - - std::string _dataPath; - - std::map<std::string,std::string> _optMap; - - int _numCond; - - int _splitIdx; - - int _splitBitMask; // nbtag-njet-njetshort-trigger (eg. 1000, 1010, 0011..) - - float _ptTres; - - std::vector<std::string> _condVec; - - // separate class for efficiencies - MMEfficiency *_Eff[10]; - MMEfficiency *_EffCorr[10]; - - bool _useCorr; - - bool _effIsRead; - - //int _estimate; - //int _syst; - - bool _isEle; - bool _isReal; - bool _debug; - - int _period; - std::string _trig1; - std::string _trig2; - std::string _trig3; - float _ps1; - float _ps2; - float _ps3; - int _trigger; - - // Internal methods / functions - int CountInString(std::string s,char c); - std::vector<std::string> Tokenize(std::string s, std::string c); - std::vector<std::string> Combine(std::vector<std::string> v1,std::vector<std::string> v2); -}; - -#endif - - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MMEfficiency.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MMEfficiency.h deleted file mode 100644 index 053c147d35c5..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MMEfficiency.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/* - ** author: Michele Pinamonti <michele.pinamonti@cern.ch> - ** version: v1 - 23aug2013 -*/ - -#ifndef MMEfficiency_H_ -#define MMEfficiency_H_ - -#include "TFile.h" -#include "TH1F.h" -#include "TH2F.h" -#include "TH3F.h" -#include "TF1.h" -#include "TF2.h" -#include "TF3.h" - -#include <string> -#include <iostream> - - -const int MAXvar = 10; - - -class MMEfficiency{ - public: - MMEfficiency(); - ~MMEfficiency(); - - bool AddHisto(TH1F *h); - bool AddHisto(TH2F *h); - bool AddHisto(TH3F *h); - bool AddHisto(TFile *f, std::string histoName, int ndim=1); - bool AddHisto(std::string fileName, std::string histoName, int ndim=1); - - void SetAverage(float value); - void SetAverageHist(TFile* f, std::string histoName); // this should be a 1-D & 1-bin histogram - void SetAverageHist(std::string fileName, std::string histoName); // this should be a 1-D & 1-bin histogram - float SetAverageFromHist(TH1F *h); - float SetAverageFromHist(TH2F *h); - float SetAverageFromHist(TH3F *h); - float SetAverageFromHist(TFile *f, std::string histoName,int ndim=1); - float SetAverageFromHist(std::string fileName, std::string histoName,int ndim=1); - - float GetEfficiency(); - float GetAverageEfficiency(); - float GetEfficiency(float v0,float v1=0,float v2=0,float v3=0,float v4=0,float v5=0,float v6=0,float v7=0,float v8=0,float v9=0); - void SetParVar(int idx,float value); - void SetParVars(float v0,float v1=0,float v2=0,float v3=0,float v4=0,float v5=0,float v6=0,float v7=0,float v8=0,float v9=0); - - // control methods - int GetNvars(); - - private: - TH1F* fHist[MAXvar]; - TH2F* fHist2D[MAXvar]; - TH3F* fHist3D[MAXvar]; - float fAverage; - float fVars[MAXvar]; - int fNvar; - int fDim[MAXvar]; -}; - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MatrixUtils.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MatrixUtils.h deleted file mode 100644 index ad5721f03818..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/MatrixUtils.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// -// Generic matrix methods fake lepton estimates for lepton and dilepton. -// -// Given loose/tight lepton ID, real efficiency r, -// and fake efficiency f builds the fake estimate event weight -// -// Authors: -// Karl Gellerstedt (kargel@fysik.su.se) -// Jorgen Sjolin (sjolin@fysik.su.se) -// - -#ifndef MATRIX_UTILS_H -#define MATRIX_UTILS_H - -#include "TMatrixD.h" - -class MatrixUtils { - - public: - MatrixUtils(); - - double lepton_weight(bool loose, double r, double f, - double &nf, double &nr); - - void fill_matrix(double r, double f); - void fill_matrix(double r, double f, double t); - - double lepton_tight_weight(bool loose); - double lepton_loose_weight(bool loose); - double lepton_tight_top_corr_weight(bool loose); - double lepton_loose_top_corr_weight(bool loose); - - double dilepton_weight(bool l1, double r1, double f1, - bool l2, double r2, double f2, - double &nrf, double &nfr, double &nff); - - void fill_matrix(double r1, double f1, double r2, double f2); - void fill_matrix(double r1, double f1, double t1, double r2, double f2, double t2); - - double dilepton_TT_weight(bool l1, bool l2); - double dilepton_TL_weight(bool l1, bool l2); - double dilepton_LT_weight(bool l1, bool l2); - double dilepton_LL_weight(bool l1, bool l2); - double dilepton_TT_top_corr_weight(bool l1, bool l2); - double dilepton_TL_top_corr_weight(bool l1, bool l2); - double dilepton_LT_top_corr_weight(bool l1, bool l2); - double dilepton_LL_top_corr_weight(bool l1, bool l2); - - void fill_lll_matrix(double r1, double f1, double r2, double f2, double r3, double f3); - double trilepton_weight(bool l1, bool l2, bool l3); - - private: - - TMatrixD ljets_matrix; - TMatrixD ljets_matrix_top_corr; - TMatrixD ll_matrix; - TMatrixD ll_matrix_top_corr; - TMatrixD lll_matrix; - - TMatrixD i_ljets_matrix; - TMatrixD i_ljets_matrix_top_corr; - TMatrixD i_ll_matrix; - TMatrixD i_ll_matrix_top_corr; - TMatrixD i_lll_matrix; -}; - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/TopFakesMMWeightCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/TopFakesMMWeightCalculator.h deleted file mode 100644 index 6bef6366541a..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/TopFakesMMWeightCalculator.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// $Id: TopFakesMMWeightCalculator.h 762053 2016-07-15 04:39:49Z tpelzer $ -#ifndef TOPFAKESMMWEIGHTCALCULATOR_H -#define TOPFAKESMMWEIGHTCALCULATOR_H - -/** - * @author Timothée Theveneaux-Pelzer <tpelzer@cern.ch> - * - * @brief TopFakesMMWeightCalculator - * Calculate Matrix-Method Weights for fake prompt lepton background estimates - **/ - -// Framework include(s): -#include "AsgTools/AsgTool.h" -#include "AsgTools/ToolHandle.h" - -// For Object containers -#include "TopEvent/Event.h" - -#include <map> - -// Classes from fakesWeight framework -class FakesWeights; -class MMLepton; -class MMEvent; - -// Forward declaration(s): -namespace top{ - class TopConfig; - class Event; - namespace fakes { - enum class LeptonDefinitions; - } -} - -namespace top{ - - class TopFakesMMWeightCalculator final : public asg::AsgTool { - public: - explicit TopFakesMMWeightCalculator( const std::string& name = "MMWeightCalculator" ); - virtual ~TopFakesMMWeightCalculator(); - - // Delete Standard constructors - TopFakesMMWeightCalculator(const TopFakesMMWeightCalculator& rhs) = delete; - TopFakesMMWeightCalculator(TopFakesMMWeightCalculator&& rhs) = delete; - TopFakesMMWeightCalculator& operator=(const TopFakesMMWeightCalculator& rhs) = delete; - - StatusCode initialize(); - StatusCode setSelectionConfigs(std::string selection, std::vector<std::string> configs); - StatusCode execute(top::Event* topEvent); - - std::vector<std::string> GetFakesMMConfigNames(std::string selection) const; - - private: - std::shared_ptr<top::TopConfig> m_config; - - std::string m_dir; - - bool m_debug; - - // unordered_map of FakesWeight objects - // m_fakesWeightTools[selection][configuration] - std::unordered_map<std::string,std::unordered_map<std::string,std::shared_ptr<FakesWeights>>> m_fakesWeightTools; - - float getMMweightE(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::ElectronContainer& els, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info); - float getMMweightM(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::MuonContainer& mus, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info); - float getMMweightEE(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::ElectronContainer& els, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info); - float getMMweightMM(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::MuonContainer& mus, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info); - float getMMweightEM(std::shared_ptr<FakesWeights> weighter, const xAOD::MissingET& met, const xAOD::ElectronContainer& els, const xAOD::MuonContainer& mus, const xAOD::JetContainer jets, const xAOD::EventInfo* event_info); - - MMLepton* getLeptonMMInfo(const xAOD::Electron& el, const xAOD::JetContainer& jets, const xAOD::MissingET& met, const xAOD::EventInfo* event_info); - MMLepton* getLeptonMMInfo(const xAOD::Muon& mu, const xAOD::JetContainer& jets, const xAOD::MissingET& met, const xAOD::EventInfo* event_info); - MMEvent* getEventMMInfo( const xAOD::JetContainer& jets, const xAOD::MissingET& met); - - int getPeriod ( const std::string& period_string ); - -// fakes::LeptonDefinitions m_leptonDefs; -// void CheckConfiguration(); - - ///-- Tell RootCore to build a dictionary (we need this) --/// - ClassDef(top::TopFakesMMWeightCalculator, 0); - - }; -} // namespace -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/TopFakesxAODUtils.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/TopFakesxAODUtils.h deleted file mode 100644 index c975f6a9a703..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/TopFakes/TopFakesxAODUtils.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef TOPFAKESXAODUTILS_H -#define TOPFAKESXAODUTILS_H - -#include "TopEvent/Event.h" - -#include <vector> - -namespace top { - /** @namespace fakes - * @brief namespace containing usefull functions for matrix-method fakes estimates - **/ - namespace fakes { - /** @brief calculates the jet-environment-related quantities for a given electron - * quantities are calculated with and without taking into account the forward jets - * default values are -999. - it can occur in 0-jet cases - * @param el the selected electron (const) - * @param jets the whole jet container (const) - * @param dRClosetJet reference to the deltaR(electron, closest jet), including forward jets (i.e. jets can have |eta|>2.5) - * @param PtClosetJet reference to the pT of the closest Jet, including forward jets (i.e. jets can have |eta|>2.5) - * @param dRClosetCentralJet reference to the deltaR(electron, closest jet), excluding forward jets (i.e. considering only jets with |eta|<2.5) - * @param PtClosetCentralJet reference to the pT of the closest Jet, excluding forward jets (i.e. considering only jets with |eta|<2.5) - **/ - void GetClosestJet (const xAOD::Electron& el, - const xAOD::JetContainer& jets, - float& dRClosetJet, - float& PtClosetJet, - float& dROverPtClosetJet, - float& dRClosetCentralJet, - float& PtClosetCentralJet, - float& dROverPtClosetCentralJet); - - /** @brief calculates the jet-enrivronment-related quantities for a given muon - * quantities are calculated with and without taking into account the forward jets - * default values are -999. - it can occur in 0-jet cases - * @param mu the selected muon (const) - * @param jets the whole jet container (const) - * @param dRClosetJet reference to the deltaR(muon, closest jet), including forward jets (i.e. jets can have |eta|>2.5) - * @param PtClosetJet reference to the pT of the closest Jet, including forward jets (i.e. jets can have |eta|>2.5) - * @param dRClosetCentralJet reference to the deltaR(muon, closest jet), excluding forward jets (i.e. considering only jets with |eta|<2.5) - * @param PtClosetCentralJet reference to the pT of the closest Jet, excluding forward jets (i.e. considering only jets with |eta|<2.5) - **/ - void GetClosestJet (const xAOD::Muon& mu, const xAOD::JetContainer& jets, - float& dRClosetJet, - float& PtClosetJet, - float& dROverPtClosetJet, - float& dRClosetCentralJet, - float& PtClosetCentralJet, - float& dROverPtClosetCentralJet); - - /** @brief calculates the deltaPhi between an electron and the MET - * @param el reference to the selected electron (const) - * @param met reference to the MET (const) - * @param dPhi reference to the deltaPhi - **/ - void GetdPhiLepMET (const xAOD::Electron& el, - const xAOD::MissingET& met, float& dPhi); - - /** @brief calculates the deltaPhi between a muon and the MET - * @param mu reference to the selected muon (const) - * @param met reference to the MET (const) - * @param dPhi reference to the deltaPhi - **/ - void GetdPhiLepMET (const xAOD::Muon& mu, - const xAOD::MissingET& met, float& dPhi); - - /** @brief calculates the trigger-matching variable of an electron - * FIXME convention could be updated with new trigger recommendations - * @param runNumber allows to distinguish 2015 and 2016 data for triggers - default is 2015 - **/ - void GetTrigMatchVariable(const xAOD::Electron& el, int& trigmatch, const unsigned int runNumber=276262); - - /** @brief calculates the trigger-matching variable of a muon - * FIXME convention could be updated with new trigger recommendations - * @param runNumber allows to distinguish 2015 and 2016 data for triggers - default is 2015 - **/ - void GetTrigMatchVariable(const xAOD::Muon& mu, int& trigmatch, const unsigned int runNumber=276262); - - /** @brief get the indexes of the good high pT electrons - * FIXME may not be needed - **/ - std::vector<unsigned int> GetGoodHighPtLeptons(const xAOD::ElectronContainer& els); - - /** @brief get the indexes of the good high pT muons - * FIXME may not be needed - **/ - std::vector<unsigned int> GetGoodHighPtLeptons(const xAOD::MuonContainer& mus); - - - /** @brief get the channel of the event, based on the good high pT electrons and muons - * FIXME may not be needed - **/ - int GetChannel(const xAOD::ElectronContainer& els, const xAOD::MuonContainer& mus); - - /** @brief enum class listing the possible lepton definitions supported by the TopFakes package - * FIXME need to add more definitions (e.g. SSDilepton, TTbarResonance) - **/ - enum class LeptonDefinitions { Standard, Other }; - } -} - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/cmt/Makefile.Standalone b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/cmt/Makefile.Standalone deleted file mode 100644 index b6a05f39b3aa..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/cmt/Makefile.Standalone +++ /dev/null @@ -1,129 +0,0 @@ -# This make file is for building a standalone version of the -# FakesMacros package. -# (The make file is a modified version of the GoodRunsLists Makefile.) -# - -# --- External configuration ---------------------------------- -#include $(ROOTSYS)/test/Makefile.arch -include $(ROOTSYS)/etc/Makefile.arch - -# ------------------------------------------------------------- -# General flags -# ------------------------------------------------------------- -PACKAGE = TopFakes -OUTPUTDIR = ../lib - -MFLAGS = -MM -Wall -W -Woverloaded-virtual -DSTANDALONE -INCLUDES += -I$(shell root-config --incdir) -I.. - -# For debugging -CXXFLAGS += -g -DSTANDALONE - -# Need these to avoid loading dependent libraries when ROOT starts -LINKLIBS = -L$(shell root-config --libdir) -lHist - -# Library list for applications -#EXELIBS = -L../lib -l$(PACKAGE) -#EXELIBS += $(shell root-config --libs) -lTreePlayer -lHistPainter - -# ------------------------------------------------------------- -# ROOT CINT files -# ------------------------------------------------------------- -LDEFFILE = ../Root/LinkDef.h -CINTFILE = ../Root/$(PACKAGE)Dict.cxx -CINTFILEH = ../Root/$(PACKAGE)Dict.h -CINTOBJ = ../Root/$(PACKAGE)Dict.o - -# ------------------------------------------------------------- -# C++ source and header files -# ------------------------------------------------------------- -CCXAOD = ../Root/TopFakesMMWeightCalculator.cxx ../Root/TopFakesxAODUtils.cxx -HHXAOD = ../$(PACKAGE)/TopFakesMMWeightCalculator.h ../$(PACKAGE)/TopFakesxAODUtils.h - -CCLIST = $(patsubst ../Root/%cxx, %cxx, $(filter-out $(CINTFILE) $(CCXAOD), $(wildcard ../Root/*.cxx))) -CCLISTC = $(addprefix ../Root/,$(CCLIST)) $(CINTFILE) -HHEXCLUDE = $(CINTFILEH) $(LDEFFILE) -HHLIST = $(patsubst ../$(PACKAGE)/%h, %h, $(filter-out $(HHEXCLUDE) $(HHXAOD), $(wildcard ../$(PACKAGE)/*.h))) -HHLISTC = $(addprefix ../$(PACKAGE)/,$(HHLIST)) -OLISTC = $(patsubst %.cxx,%.o,$(CCLISTC)) - -#APPCCLIST = $(patsubst ../src/apps/%cxx, %cxx, $(wildcard ../src/apps/*.cxx)) -#APPCCLISTC = $(addprefix ../src/apps/,$(APPCCLIST)) -#APPOLISTC = $(patsubst %.cxx,%.o,$(APPCCLISTC)) -#APPEXELIST = $(addprefix ../bin/, $(patsubst %cxx, %exe, $(APPCCLIST))) - -# ------------------------------------------------------------- -# Libraries -# ------------------------------------------------------------- -SHLIBFILE = $(OUTPUTDIR)/lib$(PACKAGE).so - -ifeq ($(PLATFORM),macosx) -EXTRALDFLAGS = -install_name @rpath/$(SHLIBFILE) -endif - -# get libraries of ROOT -define ldlinksuffixROOT - $(addsuffix $(LDLINKSUFFIX),$(Lib)) $(shell if [ "$(findstring -Ldlink2,$(OPTIONS))" ]; then echo $(addsuffix _pkgid_$(ROOTVER),$(Lib)); fi) -endef - -# ------------------------------------------------------------- -# Compilation -# ------------------------------------------------------------- - -#all: shlib apps -all: shlib - -# Implicit rule making all dependency Makefiles included at the end of this makefile -%.d: %.cxx $(HLIST) - @echo "Making $@" - @set -e; $(CC) $(MFLAGS) $(CXXFLAGS) $< \ - | awk '{ sub("^$(notdir $*).o:","$*.o $@:") ; print }' > $@ ;\ - [ -s $@ ] || rm -f $@ - -# Implicit rule to compile all classes -%.o : %.cxx - @echo "Compiling $<" - @$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $*.o - -# Rule to make ROOTCINT output file -$(CINTOBJ) : $(HHLISTC) $(LDEFFILE) - @echo "Running rootcint" - @$(ROOTSYS)/bin/rootcint -f $(CINTFILE) -c -p $(CXXFLAGS) $(INCLUDES) $(HHLISTC) $(LDEFFILE) - @echo "Compiling $(CINTFILE)" - @$(CXX) $(CXXFLAGS) $(INCLUDES) -c $(CINTFILE) -o $@ - -rootcint : $(HHLISTC) $(LDEFFILE) - @echo "Running rootcint" - $(ROOTSYS)/bin/rootcint -f $(CINTFILE) -c -p $(CXXFLAGS) $(INCLUDES) $(HHLISTC) $(LDEFFILE) - -# Rule to combine objects into a shared library -$(SHLIBFILE): $(OLISTC) - @echo "Linking $(SHLIBFILE)" - @mkdir -p $(OUTPUTDIR) - @rm -f $(SHLIBFILE) - @$(LD) $(CXXFLAGS) $(SOFLAGS) $(LINKLIBS) $(EXTRALDFLAGS) $(OLISTC) -o $(SHLIBFILE) - -# Rule to build test applications -#../bin/test.exe : ../src/apps/test.o -# @echo "Building $@" -# @$(LD) $(CXXFLAGS) $(EXELIBS) $< -o ../bin/test.exe -# -#../bin: -# @mkdir -p ../bin - --include $(DLIST) - -cint: $(CINTOBJ) -shlib: $(SHLIBFILE) - -#apps: shlib ../bin $(APPEXELIST) - -clean: - @rm -f ../*/*~ - @rm -f ../*/*.o ../*/*.d ../*/*.pcm - @rm -f ../*/*/*.o ../*/*/*.d ../*/*/*.pcm - -veryclean: clean - @rm -f ../Root/$(CINTFILE) ../Root/$(CINTFILEH) - @rm -rf $(OUTPUTDIR) - @rm -rf ../bin diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default.root deleted file mode 100644 index aa8ed4a17e833e3220ba22092c1ba743d72df808..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65386 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 Of;a3jzevraO#cVYj1gx5 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_CRfake.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_CRfake.root deleted file mode 100644 index 1d60d363b5fc6e32cf74a03379b1591da5e9e639..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65796 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 Fe*wTzN?ZT{ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_MCdown.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_MCdown.root deleted file mode 100644 index 01e8465945b5e98542abfc97ac6220a1f8f33f6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65296 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 YUs^}*6Pv}~`O*qrXMfHJUv!A=|JjDlWdHyG diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_MCup.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_MCup.root deleted file mode 100644 index 0b7eb759f7aebba9f4ca4dade7c25e20cc7cd945..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65382 zcmdpf30RHm*Z#ZP&85<yQYnNejVRJ&NRlKWY1qxtDC}t7k|`=FDwWKXp}9zDP(npW zlZ0eQJ4A(4|L1-7yWhQwkL|nu=R2I=b@`ohUFSL-?)AKDt^2vxx*uO}?=1*&?<9gC zP6#sW0)9;df4>;~B7k3O*lB<BXbFPw`67hJvD1YgJB;l(BF+(?va9$V_@^xWF9tz> z&{~U}BV33!{K??Ih9Ddkh8sMbB@OMIJ?sp9ot^BKFWl;5M^@LErKaqQ{?2~#kHEhS zej512jUX~^;D@aNzu-?rkY`tZ^;;$IqrW4zx$t*11OATs(0`xZ!br`K)7izv&YnyJ zf3Y&*ZbFc`Y{)jkW)ex=nY4vOig6|Rkw`+WB=!YzBp1?C(z4~tB339la+>Q;7vMBJ zqYynSx`xyI#y8=r=ME&cy-k{`p-487xNr(_TC^zV-W}ng?Cy&l7Q3hs%`C$y;S|aT zSxfUf{vWm~uOE_Fe)RJ0uLhi<jrx)^Qw1{C$kjZ(_YOIsAIh`f_@2_8B{|>+O&xbf z@mAjBA>zI-3ewVtSJ&N8Csh@fypnJ_A`>q`d|Bq^G*?baB2$QT#Hy*kD)lCBCD-C8 zIiljEM^A-SIW5zZ4<yJLAxPW8xhp`R_dqO~7+A2ejl{xd3x>sN0@8$GarJh|>ynaL z$0)57ia`=(EH@=IfkFwJIeX^J;?$jzMugK^5)ug~^zZA>kun<lahY611cgW5rL6>E zdn~}uuPv!XIi+eOD$hP^4<&a}=A`U+g2IKelCqML&w@(lor^xtJ2Eq5|CySGg@bZL zeUH@r<IK3uhE0iPXWM;>NE&bCQ(Dm_w?H6r3~5&wU+g>1j(`PUo|qNO#>%pt9_zAz zJ@pg>>gL**&TSdj4P2T-LKF9g`<8gE6I-rCG%V-inxb^6WYQLr1HYxH;mPUGc734E zm?hAqcr>8oQf}6}g9cG?ts7gV8m##gsiq6x?2cIMdi92TlTP6ym$H-RNd3<m`#ILP z^)>5+r-hg)#HXdpaA^p}&S#gj9DANqncx_DF>iCVYesfjRi;K?P1d1Vjjq$S6gAfN z<Ygrfr)?&mR-DwO-Y_q07J^vL_oxPONPuzZhH+3t&m?gl9tSS;Oge9|#{%I@K)SI& z_*bBT$f3YM?7#z|0|KF&D}PYZh}c1kL=PGXu@RA&4<f<Eh{Rr&BOxvnMj?JYJ|uDA z@@|T>*EylE!P*2l)jLC(Y7&jtclPL=rceeO8ZP>3v$Zu2bF-`M=o&_5?y39yvP90j z_g+x)9->HWl&X}=tQ)4ByG)c)&dJw{kcPuda)v`4ba`(Q3Y}Na%H)@jQIWPV>$-Vs zuBsZR64%K((VmjeWNj==US*l@`0|RWx$9}C{I(aTh4k&+>AUxOho;%lV&clxQT~t; z6M-InvC=6d{tOY1%e8sAMModo-+U<RIIUBo+%#lhSu~rrckq}(o`}mWGph<5^R18a z$a5n7l(<9?7-txmWX1==F&PgGOcqY&SX|TzNHP|e#9L@wV(*r8mz2oWmT>RXFR3mm zDLtHcc-%4J8~mq2&87MGo2-=EAa``ksXbq&L|0UlunT8<lMsRc7w4{U{v>^K33*;& zw(&PgtPWZpTvv^VuCXWClStpV4nNGY4NSgsSkLgm%eTjaqX}|z%nbR?h1CqbG!csL zkR!Y>K(tM&v1pvj97a}>hKUQb^%Xefi_FFr1Wp~dWKB$`QO2;oVVQKO17B==Nl9o; z){I0;PX2E3g1`ga1w;|Yk_D>cm!}Xb^R-_cT>bIlmSe3Oun*#rq>+Nhqis%pWwp08 zpC=t_JwDKICTX3g_uAu|NOnz+iK;=Vug5u&7N24(VBb&3E31vsxM`X~Elj>pC88~` zaI5y2^0QsiO%?|GkQh_vKmhUz2=aai@=WyfbMC=G=0Q*YM&~VfB9bH^`!Sq5NoZ0w zc0iMIv;#dUKQ#eK`L6NI=?eCoS)o}psKwAPKxV`jAh*gz-G^<deYAoRx7#=(Yk4_Z zfNPl?54%9G07yg`r4{ohE)X!_D&gO4q@c%hd&z5xk^WK;LKCIPbou&Cq!3DV&M-1t zlCLAQl?L%kae+ye)|ADsOKwPHDC{>}RVL8hvf53$aqXP`(AJ%fZQ>q5E$;bN{gtyD z%8Uyin0@71G~vty(V`vv7xq~0UREMOI!S%*eIeWNQeRe()W?>-RlP3S2DdiLaUc)m ztw2d9WT9{p6(O8TD4bjkIGo%loK9wL8?aLwL_idYv=X<*6-Cp(3ZB|q_^CYzPi^$U zTl`MQl({gm^M-oNiB^AkM1Pz(QN*aam_lIxEF&S|#eh?kML1IhY~?tKTxbH}t9lm3 ztJe5#=bolxJMSMkP+BrHHFg*|aes&-b_h9rUH^@&*;m1x<WMty0sVXm5|b=MP<T^P z61}%#bKEI^0cmA94eD`$u*9eZb4mFZ_DwxZIQb@=sPK3%!Zo!rbakoQteM|bi(7Xr zD7CPmYVrGTaBiC%HbGHaLT6!nNpaQ{uBYE->Z)+4=)TF<-ZI=AtC3EnDoYO(lis%2 z7D}0IU7Om|z%MU4$9?{eCN5)JG#(aQM?%#~OtVG!n%$=b>EAZZG^{lBRLoC)@}`aK z)i;T}ctHcTx!`b9uW5D0TN|A=uSs`Z3YYdAqkgUT3*$$S?#T&nK*ZL<51^Tm{(1J| z5rgU9)0tj}CliondL6EW=|A*G>0dJ!6yl$x|51gQ_4Gdtr2mE2iLo3xyu8vDa{OE( z3Z7i2ZBlb&V<UIoUy6PTCJM6lQx_q|^Hf!x95w|`IUmV2Amwyskn7wnO9iejTGKM? znvYr8b6%wdXmA$W&q@^bl4!%zy8Feh0H=G79IsRqL`~}JBePqOgS*d9GtyR7<yOy_ zWIkpWXGT5QhAWZ!t=_NYgLZJ1%|K|woYXU73#XVNNMq2t_W)Mi(XjG99R=$aKkPf; zWewK+Q%Qdztd|zh4tST9;=lySPnM-OZk++&E3IECmjg&vUY^r(CFtmmi4ju~M6`Sf zU;%`M5WNUS8sVRSqX*N77f8z(d;$a{0y~u(VHz=Zf=Ss4Ps&DUQodt6)1Fg3G=`Rw zInbOeIWi|NWXj2`CXr|XG>43p;B%WU+87e5DxDh0C7@u37*GDBzgoXSQbIjb>r#xx zP0ApLy6{UO(e<g)^i!yMU7vTlM>iz`ZJu4q-3r)umPS^(W~ATK%DC*&O(>K!^Iu`n znl&Y626+VrUOjpU*(M82c<aL>LG;Q=eie6~?66j)aZ|CjW8tSw+(rcCY_{nl0HF$m z(1}sl#@OQ!!oud|u*KdL!|)3rAsB|nu(0|5u&^zgvDC!%r-khTXzh~m9wM=V#U3J! z&qz&G%O`ZY5aA&Yp-)yWhZq}migO0rk-ImZ#~Yi=5c{~QjN&U4^7Q9||3afu`iZ^H zC8QwAorc$u+Gv-?ezNYxI{Uyv-UGye+b<_%9QElM*m2Q2z<!p=1koT^z`|hx>$1K- zv#TH^qG{8^V}zv$l9pf;58x7kaLs4HB@jIlE_<?_+C~hnRs@-k!IcH!GXD`=E0iKM zs~vs{S2g&<#9?raV-vn0wpT2nf?wZWjB^|(XJrU!>CCqk4OcwAIL`7cp3uo9i8v6Q zb3*5pSW#w$flRoEjWCrvd=jS!+XL`}5-gQ2%eVLr2r9fh>EmO$X0gbf(1`<V#~h<= z$bfIe^PN1{5$ZvDydcyjypj^+yjig1bL#7{pk2B#-kPlvanJpDO<hbL{MlURs{u$L zeP(;ifJ6`yc1Tv?3G&&(fW(@BJf_!%Qdk@Iz}m16rv@63qsc!}jgYKjyX~v0s=k<F zfi!u@ZLL<JC@FJJjgAi@61jcA5$|$(${tfDw=!Djo)YJyeK+<27*jKNiF`z2yI#hr z!@bYnTIYRJOPpgT*b7QoCPm#!UnWW5u)Z+2bc{gg2DwrW@$4|}xmt5VB?Xktilt)T z@pJ?%{1R*y%pGeO&oeeO2I3`cw=}K2bci!y!!Ti^`ncQl{(p>$bZkZeTf{xeUNzE6 zi34YLN>%3L-zCq@VwJ|Pc@16>cbAn$toTZ$x263qZ|xh-zKJ8hJC>4uDZbsgf7RLz zb?Yx$6nxHh_nbO^AFt|1{aXv8DPjjVqKvq4qxP{^O5_Q>u3brA9lKsEbZt2wyR)%k zzC!k$q-sY^gJ<V#hWn1ljX}m&`vU9<De#bffDutfyQ{IY@k7dsQ8h+LTnWerEF}JS zU`P^RND}doDAL%P8jK0M@n#s4STrW#BVzJiOI1~x5ffFGV`8n(&nZy7`>W%u;t8C- z1;-cg_i4NCC{Y@?SxF)d3*R1&<>c(Mv&+9t<qmWlo-A~OJ8PJjBWKutlo)1Izp#Jn zBmomM-7=5(Iw5T|mu@=|W3eK1P*A;&b_+qzrCUHnH^`Ko_6qH6r9o#~MQm@8!Rq%> zj2w{Dw|ZM|o_Qf>JtDTd=UJ!ybM4g5BWwC})L&<2h4t8X>fc(7#%3Rk4Nu;?GyToM zD+XPsy>@jx>$|qC)|A*~P`IZ(ih8D^EoZ&&>)oxL7sTb3BU-y+W`O8;!04nhz8B#K zcy!?R;$+SU&Kv@giUlXJ91V`e4cPov;LUFWY<@+(<16@`2+p+bcLv)1&KuGFYDr5- zjAL}atdfaTfjI+5H4I3H!`P#_2wkdbSV&G(4iOho1_imP$Z?72PYV`5?MbkdUbi%D za_JCJl4morZ>Cu!kw~0#C(X@4QnkSDY0vDd?E)tI34EZ--7X-}meO%el<)GRg#lB! zuFN|xFB4EZCcXE@)OYy<>xHL$d1ZC3b%o98#ooE*^otMVjG$;MY-tg+rCrn5bS>HK z?8#VrSEUa(BYP81Q+KVHO}4eu-62XqjKiEy1FTm;tfL^-s_2&>s)u9EkJB~=+~WyI z6b5&v3uJE2ut{*nn}nrw=C&72+P<N@wCjs~DB|WL5ZC9dVSEc(EPe}eGPLy6DN`~l zniLkXeZfxY9ReUd9W)CTj*YrUJV?(;Ye7yb8Dblqld4su7mdtGGE6xM^a@<D!Ptd_ z?Z$VRF$qdps=cYN#nALV4^8h<o<|1mR76hiOs1BPu_0ejIzZlgwF6MMn1gH4d!T$2 zQlc`1R0V}pECz>^k51hfh=vdlWsJQ&a)9iu3?ATe`~W9o>`f9LVPXgE2ya9IH68)z zC;~VB&n0m8Zx=7&)LA3(iGD>#`h;;ht&rWcn%XE6-g(`^d;W*};q7F<6P<@=9<<0T zbdfurv9A4K>zF<B;)7COOsOi_XS5aV;kssNcSO$89#fl6{+ggnE^%^nrJnW>SM`jt z>F{(etbHU%7J28~w48f()=|r5S54;?hg)w@pUV-E*wu+=LD-z&m(a?n3F4rs!LF2H zO#u9j5w)2Fq?KN#;Z0Fa{EupaW-hHx|D-02s?)63ge0^k3<{WyyEj9@$Bd#XZIYTJ z6HBJt4>p@8Y&=Z{(U4X@9=J0Br`R9jPR*Op<sF^SC!0Fe@wjxxdf3|3y)QH1iBQbo zM*HV+;dO4t1)%@KinF-sU3wc`e^v9+m2qpDse9Ab=PeQ*zgE>|n;RD=rvc}hMQNpG zym`%+`Y)cbscJ7GPm1bq_PXDZec-~1N;4i&1nF>JzW`vYGa6%wi=!~!;>W<4lQoR< zPtE^T-Tgx`enk5URL4&>okIoJjObyWEx}0vSI=Fu^7+=ii-KIvqs4F&0B<@3FOrd0 zBs+2NU|vDF90R=%2og!p)G)6Y+rvz4k7sIAjLyMCoki)PF}m3(qnk34(QRg8bgX8T ze~{5_*~DK=B!<bUK7X1Sc^sk9x7S(7M0=eB04OC0lq;jANr~V<!I}mc8w0722;zz% zWejVY?+<GlO4_1+Rnsg1C!fc-l8<EZO5Q>o+<p2yMOMkNofBc}($jb2QjlFb#)4h> z*xm{?@ZEBD2}U1OjacbH@dbTK#ya@rmVRYBa=A{%4;4YU4Nu<6F8fRt8_(4jSEEDH zB*yK!6?S3;XvD^*qY2U@HhDP6UHeu-w!VZs0SP#3qzSMRhgj({4wW>c{=-8B=$fmu zI-Rh!A&4#pRTex{=07@AfUvDtG5a>4Y(F_v{|062T7X~A^0kMZSb~D%j)HTc-t^vG zPC(ff9oHETV4-O_PZ+SsKz$NYHV6x#Y)r7&6ObqLYCzL-cEW0~3ug%0G}5N4Q?CGM z8|Q5rMR<r(gt!qDVN|M`#bR6Z&(pT=x_|tF)hj{Ae`fmy_x}2?4*rSdya7}96zII# zRqyX`sJ}(Sw=4K%Zq@DXvzP9l$hSKG9dpY}QXyZPSxmMD7l8%IXPcfZ@6HI)ENU># zO)IN4-=3L#wQF-UC&D$yyBP%LEIh9t8Q=B<RK=zVzwp}zA{%pLya>ogEHeIgA$N;| zkvWV<W*Wxbu+R`@JSCBw_OVT8%WBd$POxKJXU%USr#8UJDfDy`iKJCk!XqDUa6)ck z>Lz|xuNewLCHSS|1$%G01?up>@L3ox(dAdmPFdF%h2D@)i5;FkhQI52u~%Hn*w2+i zOXT*9bsFY!GuU6L$;EjvZFl$EMbh!9fjgU2PfjGOgZtPIi>91UK?Y=<P7HF1eq5;~ z&^Qy`<GkMXEOm#2o@p&gx90-79nDplU+CQTI(L8erPguBj_eRW_NgT~BfIB-)+^Wi zX=z?f!b`;@WG_va8qAS4q<@^0c8Q!M6Dzoi%UBr_33hllo<ViG>e?b+=}_3&71**$ z=LFfLzvP+M*=?PvHn~Gmg?pE$ce!xOQ)UqmKIwyK3U-HKI>GpU<PPIuqV>S$%u&)H zASbXWCEkQ2?#Df_=&_WIv4F<?qz4{F<5;a${~V3$rpuhT3O5G3TGO_7?U343d$-$- zreYLI3T=wlHQU06-i{Mcs<GbQHIuX>xofJ8_W4Hw+K~^>lanYl<ZpTr`uh+g;f>D# z)U>|!AcR^Sr5lsLFYJpDU@$nQY&D&L9K_J>gd-8ga3mrcABlL1jzmE9Z7(g4`%;W) zEbcZ+Ivhrj4t+x=7N^f*y835W+<Htj&Zmp}GFL-9Zzt6Ek=F*=^4bR8_wEnb9og4= zdEaP8ch+hC%}CELTrGNp33+#GwVQ_e%sHnc$i$TOD*?uh=y4{hLX6c=j3+ze7>~gz z9TUVU1Voii>g*w@tAwQPCQj;((n%fdNWUPg_MzS65kN`E9Z?eAgPXj^45mDvMU3@j zuAvMe30zK$i!SF9bI54p8Jn%gb6Q0zj54@fVVJP!^dO(YAi+3<a$hg?lPtWdkPh`C z66CcfvYFkdP$r5*yqdAJS6a(j-=%q>4CicF#t6m(J}$EY5dwN+k-nqO&FV8C4LU2g z-Z^ZPR`P}zzT^DW=1t_?-F8QPU2=<B>u9YmF8+5XEm>2Oe?N%4;^D%ws1J8@1~vw% z>D1VV>xe8W(%GFH=Y3<YUO=B|WXF;Pk6Jc+SzeqrXS-gtu33*TDof8pWodFEb=lCd zytXmZ8iz>ae8&&YIqmcAd7KrV;{GcC9mOUq@Q6*%k|l*boFav~Z?nn0XQwsQ8?~`X zB8X99!XSvN3rtgOjA}AP2ahYPCMf4)3M*iJZS*={1FK2wkE#h^eJoTHGKti9>wi&A zv?!pOe3eO6N?mRCG?mR>D_(ztwgQ#y^kC{1`B>9=h>Moff-l?}cnI4Smu{Wk*aoCk zJ^kgC3}y9Mc$o0GwWP80(0hO0lXbB^<)6u1yd0~x=C*gu!BkVNqKa3ipH@s8q{mXn zM8}{R3=P5CSJhcyPDYXRHaokZ=WgW6iIwDa<<{#P9$WIq=>t{z(E4itWuwt3Pi5SH z(@+Mij|pW#)=&n#@2^Ff4@3Dd?bdY1-b2e7vZw(movL-&B=^vot9u{;l-D!#05~pz zI7Wlh%8kG*H0>>ZT45G~1ds{HF$5%<p6Fo~GIoR%&=IGA%jp!5mgjpyXVCI|8k*;= zM&|jcOnIKw93&@$rl3ix<L;R&WDFzrTKZoEq|J(vSi{$pw9tJTsJLtm#AV_DpObv` zL?}yP%?v4+B5L0Fm?)0QQq{Zae0aFSWDW?vYObMQNMPBfQ3n&6*FFUtntQ+2whQH8 zQb_b9^~NRJjP^jkO7fd_Apk@`nK8hNpbuf(0AYj$bGkYXBP^ISddP$$2LaiD;b;sC zrtc36CM1ZzE|{YzV)XwxMbw}VVC8lnaK98DN0y2Vvdif8R2i-Cohqk#+KGB*6s<eP z5AHD2J{o%g{3IcMdJsQ&Wjw<d#}9tafHJCk`)bfR<5L9D!_dou^xFJK^cofUZmX!* z{`|@~9?<I<7`;|vm$y_DR#cCW3@w|%uf)&4f4C&Z>QThy%}qTw-I@b+9tx@>H#l#* z5w?crvTfkp9n2-f!Db@FyO@6}JF1<lXIk1W&FkosHLG6o>}duZH(A)np?g!VunXuP zs^W%|?+}_wUWX(2ZP@5ROrWg*d6R0PI}ZSpi03(O1OlTNF%lR+8kvCstdWIkQk*LP zMB#ds7NCtk<0k*>Y9gaVkr&dEmq8xr@8DB*;Tr4f;{mP?ty2Rv71~5@_wVW%O#LRL za6naL5;6s%rd14t_^`n->JNs951o`^iDa6FG2T{7!G06RxZ~*T*$FUv#-q94TN4}1 z>00ylNx@4i%ME_7hjOR8u4!p$RS)=NRk^OAJH5B!)2!WMeI`Pi0wTTd&zKf4+@vAO zd!}>a&8DD+$L@uW%CnRyXTT^5ZEmD`lGd2KX47k$C6R3(4#{{Qme`XQ1d9GmFx%_8 zP32B)xpr-B-9~jIE@Z#F=LHa%3>cYDjLbQ63LY7lIZ@Wg92znK`GlR>uO+b1AAp5E z5~q!tbjc5k4Ka<z8_%P>apTW;<M#g)Z>-T@V4qz%xo~0s<>hm;o1b*^F48lRQMdv_ zH5Mf?+NF8J3hC7S+sG};SJ^e$e#*{t9E=t;C!I|?>%I2uaR<%w{@JbkNBHE_5bdg% z^&nneFkUAaDMq;-j~7faKmlY9*K7iE5(`%%Wce1iVY__?Z?_L&B4DhYQ&I*03q*|8 zZHuDa_URGbwhz!~l^ESNtGblFj7Og)D#>#3$O*DF+B;z6e$jzJu03o6vO>*-1!{6{ z!uOSQXk=<-#aJxaF~|i*Sr9nN!pZ4D8>#ZSUee*d<tDs}2VHfKG?;cf?cculh_W<e zjPth$WdFy!<VxSU+PO#K$Yr}lsO)E`nIiXs5Oa2<=#Be1fVMqEI|ibyfwCLbg*e)R z3<k*z_!I&Xg8|;@i1M4;B($?IBjKIJ3Y<b>X}yQCk=9#uqP@k&k-dcrQ*W_|MSk;t z#UW|kg|i>l2lw#{ZIAai`@{=ax`PZlDSjYtmH$k~n+NCBM{ekFYH8alLOn$e<^c5Z z+P$^l#+1;E0!&nc0K<+$?Gz3$>^RV2&JhRt7y(hE^GDcm_}9V%eHTB_N9g>~8#~f$ zakL{HiyrBU5l4Cyfn=4W|78RclLjGyys5b%?oiQiSCjVK!?HZ<yzj;h%y=*~<TP3{ zY!TG7_8eaBlrbo-aVv6RSD4J*{oAy2Kbn#W6P}Z&?+$Ks_OZ=PzjV~CLC^1yO?sbL zA!n~#Gy!?%le8N|)(w6-PZ@<pBN&e?EG#I2Wd3lJ3CL6I!?_B_6>|3fsIZ{AAq$0N zWYK56u>5%xve?Ysb>`Lj$aM;B<lb+pE%!dAt68vdAlzH69Rbe9qj8?~aum*hLNenl z#2U`1cKFxg{7VwKEhW40mh+{G=*2()qZ%8cNYdtM(d$BP1m>bSsyLD~_JgX3%uo_p zyDkKCp?m2a{Qv*!!hfDdmH^I(s@bF)rH(RF1<tPApC?l2UmE$bRWe=)`8H`0I?AUF z&*4T!sni6F2)k^BrIN-Snc*8okd4?E59l{2l|4T!l{9sc#(;iSDo3%$ga0~v1nRZm zK3#MO;6fR?ptF*!-jVI0cj=qsfXlF9G&{oa!T2$Nj-fPiBXBH6>pTt}Lus5vXN|w3 zG~W6%mBt5{ysxX^kB(_)a-w32mFE#%0Rj)`2d?XYt^gZFM3qJimboP(VS!2`4vWig zD2?)esnS@exxHtJ?w2^S-9?o%XXjqX5ZCGpDt(k+)MpiFm-5nkoBg}kU_<NM{gj{` z{qk{R#%XkEbPp=6u2#>Ax~>>fvuJa8P+1DkfYfs>`<IlM-RSaIJ^FcrA$k7GZB4eb zjdN@qHQMsPQq!aC-ts4gbLxvC)C>AdKkEhA4Nc(ya$}{VFKC1b1@L=E<wlIsYun<{ zfkcERH{#&|!(6P(jc9y+M(O`bxl!|)ZhPhJ+e`WaC#;*@X58O&=iR-!;-S@bw&$K~ zdw!blCe?Y_3Hf1bzVLL{cP}i1<(-O(5}VJg;H<pU#X-M^k{!(;o7Zau3#zX1L@S!_ z<>@)pteNc7Gtl*^&DKe-YX|2yc=e>$00K$68v|+`!5hX6)gQ61N@pA%H-`R*hfVW0 z^v9ULOn*#ygWb1e+qi2yTWOJT1iL>C(2cr~=zV&iYcckjz4|=$qHk8etck3`RSt9y z7J+-P86x0&X^pjXYzZ!FS<~=l&&84)9kNpK(+mzoywMq4{t+A@+)Pb{Za5D22n`ZP zT!FQw0^I;aHAs-*{}K&yfG)SwhjXuB!_wj!(PoVoK2+KE*A?saJ~&qTFzm!ybN~ge zpm^j^?J9=zTx*kZlikWTDrP-tdwG0d9=Nq0EVuLn5VxWbLkSYQ{MUPpL(D8e;s~Go zEeR5w>i>iU8E~9-S+e`ViAUlO9!RfgjBxMHZB=Wiwe>jAdNN3SpsVRpZo+$o8I8*d z)l6N3C)#_vReR_TwsQpZV`}4)W5<L=Kib~btv<Ht(cs{cuFYqQj_@Yj_Bdwgm_K}G z+6^_iW#A$du3ibe6w(?)PQ2I$I7`)6rxs4qjyo3$HU?N}Jn5@{$*-NP(nF41bI5ae znrFU9r<UuH*Tr6!Z%q=>raVZL6G85A9!ArZC;Wa;9TF=u1{HX4X$l$CA@SIPK?@dc zj&*4|<gd!iND|5VRLeg~BKsUTg?W$8p3sz?bj0CVy}#St0?RFDmR&oHYr|t{<1FP5 zMNZL!!MTtKRzVJ4x9hU(S8ejL-|npVG1Wux&Z9z!85A~T>WWo20N4yU5(9f7L;s<H z4dqB2?B9|j|4OjQvf`&syBZlc4nACM^=XZw*mv`&$wSLq$ODHLOJupRAqDA1%K?tc z@X#{Jk&FECL(42j;y`{ven*Z3DgV!xBcl$v_vb*j2{CI5eI!)?^!XX%J+U>yj5WF> zfR-Lai%E4{46a_8$8_kbBMuk)@2QTzD3POh<Nv+tsM2*IaB}UJrop!3CxZslPw3>+ z)JN6rW}kS_yHqiFmzw3sKi64m-LY$D*D1(?Io0;{OSk}hjI}~;1lkK2zQW;yJ3&Bn zR0T_Y(DQ}$wL+u6YOQc{lfSq;g3OpS-vmH%2%ac(tq_A`$=8vP0Op88V#D%Uq1@j8 z%32{YR+nykfl+btWvm$+NRn0o*S?2av3)|aAZ;LnG@37_ysK@TyTUUk`^l#^)7pnm zOy@s8nA}=tU8p*4Y2nvIKXS(|5&iMVm)cE0ASWclkbHn4fqR8Z!7wEDk>h)XcuWA7 z|A5^L{c5ie4a!e;NdBvPh3jc!dxC3!U;`t|tKF!Zob@EqaonNghhj3?52|L$agZsJ z735Wq23ls43mx;HSNKLtAY0!>fvtC}$wJo(vF~LWST@9hLtiVzV*?l=i))3^H~y}* z!tO-M&N7z+OYoUUKkuFwQGq>*45N$(*rpF=X@ZO<gnY@K?yg>1rL~`G)wDN6t|JEy zOlZ7v>^<jnHl*hI#v}l?75oy=y+W+XGC6{S4Vx@z2gAru6Mtu~5M=GYaIcWQ<*ZyU zwc^^AX9cat&Run0Ccm20X;7yKR)6+vMTZ*aG%M>U+=v{!YuXYbBH2~o!ACWjoF58y zs2<O^MAr*TP-NkHA$GN~9Blev$C!4tfr^RvLEiHl>xJl1{>f<dXV7Oe`NOb2TK#YN z!)O)Jdb2p0{k9ha+7sRFPq*@8!`ERS{Pe#pIo^5s^EJ_HpHH=Qn_?Cbm_JMwHaD+4 zdge6Q`lS_IHC%pVi+0hQBJvsF1QzJmm6z`S+P-0R{~fRAMM{Nx(KIwAhk7P>z+JPc zRMrVWtg;fLK>Qrwmx1mXawD)ttjNUUhwmBU;ZtO72M*N>e^DbwEtdSbdxoduf};5S zFLdS6A|rbyMUJr?H@;*|ORt7gb9fLbU*yX`1^L1ClX;~pJt4u<U1XgG5N2!{VhFDU z9Gkfcdjf)oBh1Mf!l+XCcOv{hZy9D^k@kG$w@P~9IKb!Z9Sn;Ac&6}pqFaVodNDV{ z!Gq}q4w>TUjU%wWWr#N0KUoNq`@^;j3pqv)v184mPcJaN*io`4>?XPo9xCN2o;pxs z+SlZvz1LV<yRvAR0WXrOWHJk&IT@mft|DS(a8(M9CM<(A)`!ChHab~fMf^n>9L4zl zwN*r<-SHj@80vjiVTR1PUF-bT#z_)+?>PSrfatq%Qj5}&5J6_g*w%c?@;Ir{zF%!? z#)FFXZ;X>-<~pGt4C*GMm47x``5$cr=LiA(ZvCwJO#ql9@a!;M3a$nVa9A3HX9w~- z1~9fPT?(S(q;k{Y!t~Fyr~mb(;6FT0N;fDZYovY>PzbuyRp&10YEvkPS;=&-D*A9^ znRsN&AY4*6ujn3pu(@7r^R+J9#&ur|lfo*;+_RwXtW(yppDkU}!qJv&|4PsPYVvNs zq-2K!`;(h5D3UkTtmw*0*w!`Gaxm{Lm*FHK1W`2Jd<lf*Bn%7FEa}=!cv$dRQdI{= zTsE*iONs^NKQ~LNO?UV-psg6T?xK4nip~(|D6cQS;YV{%M67?XeK?rb=`yh7>)~X# z$w!kbsS~uP<r+q_6*e{xk~IQ4yAB5(b;v(lH(s6-IX>YqXpRY+V2GH;N7sS&nfc2B z<D<+G(qeghG#c8-{8i(lI(HwHUs~}%kvg|{X?jxEpsPxO+)SN?=4H6Q%r2UnBHi*U z^bK)wJ~Ui~nz<O+pdo^))I5pWwPHmUT&Dm#K85-sYoaG11r<&;0B~0bIMW2F6+{1H znjmGy95lA9Pmt0w`On5;^#7a*QrzE)-aiCj<|P4F>~m8ZUkvuC-xV+^PT)K+EmaxI zMHkBXcRT>5pvJyYO_{+}`9Xk3L@sv7vbmqPRZa|9>1v5C7*wM$GtZH(@50YDV~&&= z<%7R5M~a>8|HK?AokL(t2Rvsrv2`|WiK0|9)zxdY1(dI2`_F|U<Tb@(Uw!MM+mGQF zB3^V$SD7EU&D0cZCtvL_B%kTaC6D8q+BkO>UsL$HoTk}}WHa8zDd!x$ntQ{`_tu2M z>A(zSdB}8<W`~LvsOvSPlmHM*nq<y2IcigY#}c0$Wez3S+GTZel!Y=fvcCT*lcOTo z07#N8eUq0kBN*Ek`A+DAYv(7POlevAjVGhk!^1;L?wT;P4pmdP0plLu4~^PMje;2R zKt`qhjiJ%M7UGK-yPk@D5b;_~z>_`<&Pb6Y*z=le%gtJqXPEIqQpoqrNDClI^T1@9 z?;ttjNHT^-nNKUw`dHa9heM-SpZ>=Wjou~EyU*9pB?9qT(S?M^ZiPrI7ciiS%FqQy zf|yee)0C)vEDjgblqfS^)ZdvB{dGAU#r^*8r$jLun(w%uvVK1yiyv9$u0sYu$-utB z0McVPjO+leAh1Rao+}#nV_L<0jvxk@W|9RLBg}uaiis{08twb_D(1hz|G0M{g_1Or z9%Qr!&DS;PyACs@bn*c>G?U6_3~(G7{11Xd<9|%xI1-R&^yLDYQDqWbE=a+*)>LRV zG=KqOtJ54ap3&@1h+u7P-^jJKku`$C^4gl#Kg<F1X%)QIs~mekK%0KKOFZ}4TeI>_ zwTe7r^8=Frb=n>35|lq!k@aZXuZYV8h3&L`Lg=*NIjyZ?!!%o^4b$eeJTk35QPWpJ zozNl+3cI9IvDYi@%N4a9JGhOA2vyee9*7QYGPDmy2QE!HZ^Mr+{KnDAQ1FE_g(r}J z^kL!odIK&MhQaVq@bKu-mkROtaHY}Wa~_RP+Q|5foDbd0a(w<(JDLExEqmXh`kCt| zop<oV%{s6(?)LI}S<G>ieg|*eI-AH7UNb(5G}>EK<8Ee)si#wRtJSyWz7xj|$Smo! z0FOZ&=<p@iEcilRwRTZs&3++dF9BJm8V6V)fecg5X~tLOI%@xc#toUmrcFRjV_~zZ zg61?o-o+C2j>i0HUi_qo9<^S``YzT#wq8izCd9oJ%PUT3*gVhe!iB22*r4b*+EQ-m zC(4QSsQm*kG<fALymut3tGZ$`)ueg2`IbLt)6#vpEql)-a{)P!lI8XgpuPd39t%;Q zjjkBFox#7Bv5XbNk>3lTh_M*(iEs%wwgO#(OT9r~f}0qRF2TiFnVSjY*ozX<p2LiG zo*jHKog=;&Bw@}Wiii<!*dl`k`Wlj~ZI4s7Xj!r?mGe30hi*uZQGUrY)|VSK*;usT z%ThDl1%iv%FqeF~k-;dJeAVkdLZu^I^2xv@AA7l=PzLjB^P|5OvEC)h_Kw!uW{tU3 z^-HI`DH$~;n!GFdkc^!~giKp87x|j^Z0bWlDO4TQl3I=Ka<)K<r~!eVg#x`%5C>Wa zcd8kQGcc>spf4NJ-jBEiajwE~j>eY_=|@}?nL&ejItugc5imamo1g^@XOn|0C#G$v zvxyeEL@T#jaK;VNb&*LfA;QLXb2y0uN6m(adyEIf&At+2huBVs=)ci}E45lkD<_)~ z8GkY8?&_G%xjqG<)j7N8@o&`S?Z6)G*ndV`Ak}9Yn=~-FT*Gm)F6TXy*@-~w^*J5Y z8v_bYV%@PRye<5gjd?c7TDOW}?pZ~TGpts4^aK~`(Y$UNHwPYCGq-8rZi?NfD#yDI z+kC9<#Ww|hy~(FKpnq!_`k8dX&tya1u*1}*%*FmKnbty??RvL2PIEf#d=^;AD!Yu? zZBuuiyRa)+hkW3yK=X32cXTOvdzj5z;9CJaJhmJy1EHlYML%a$9Cx4=V9gS&IOwk7 z$jE~CY@X8_0_dxiv*Sk<2dankj^Jk%XJkjfdd2xiM@8wzG(~iWv+_4|XAqjz8P@^6 zc;)#FmZQM2-gB+SyNk(h%N~%E)}CqhnkQy26+EE0%QzK5l;+uR0<>v57!%r_mZQ+7 zkw>ONA<P=uP)YoI(OyP-LZQhMTgp-0l(m6=qh6}Y?U9>Y<sYJ5&pwTR9T-!NJH8ai zIfUgf{~uzcB`-$)hiM5@6`9*5z{U?@hqn`^rQ7g53N!pY3L*M?6npVzpBE9^1Z}iL z*}xWb$A~THQ2wL8pOp0Hq27IqNJ^=v%}B$9GM~^M8LiYng2I7&#MJ~bS5noD=LO(h z1+G4E@UFr_Gt{3G^VKc=#y0&_#uYAQ_-MeGlh1^OIJL*i*5=Y}%5WzP>`^l0I|Cc1 zV>Nk)&gEn~J}wkJg&-kkj1~hhXF@PN7{%24BYretF{O)&%xD6eL=Oy2u&a-*A;PB? z%<w0dgy54)v^7LJciM-nrom}}!r40l&J5tkv4!E6K9xnY>2u0*6(vtg2xs)!&8D$~ zr#|ipnCZrhKgVsYD-z*2W9e4@Mp?PZ_Tx@AvULC_22wV(WeMx$P_{d%-HqDP3+*>N z<Qo2g>VioI`=bmn?<5DYg@i^0?KkTwRqDtheq9RymMjEo0V8W}lEcA*S(8RFnKw4u z5o7@dRTkXXy#J$(O&Z5!!Q9~AAej<BA(<~5tfCR5UQ{;}z;hbH!<6QH^+v)&Bbm(b z06mL^qJrs+*mCthQdIsmnn`bvhcF6r7c+9Cw*Y-6bTgFy$@G-Nb^{z1$V?aSlFxBz zE<U^|Z&2i^z3WsrhgTu7^|gg;u`eVLg-IT(L6Ayekop<fbMp&4NHBY1T$4FUI|)cX zc8I@LL$Y}Ymi~iuvbj)>K{l}+cm>4bMrlcvD2F+>Q#K`5<2rj*fkeE%L*E#Fxf1Zi zoKG~~Jx^w_dnRo4A*e}csmgXn)qVDtsCu>weIG1|hb_BH7PTQ<rZBu}yhLM2Q0t8R z$?p#gM(GPpt{M`&w?pE9w*dd7)q<@Jd$m*zzHn#T8!qf}LeuSDV{;uspI+4>+5;{0 zbX)hK%z&dJI4KErAMyq6LlXt}d-pHWk^d$!Y(jS?Y_v(!OxgCPY!lw;(O(BE_=-E& z9Bw+<pk8~`XR9W5Rd7Zi)*5d6aHAvY$t3Luq+`_T&0TrgPH#O_`h)V?tDkTHKbuXe z4=(}HrZwmDQL@I{Lk13ru0=dBgdl8#0X)M<LR(Mc0fb42Mmm|}H=lr<!Qy8HFAFS6 zVN+g0Z^}!LVU{*Px4|qxi1joJkcX%RNd1UxJ&Ja+>ap?<y4oburXRa-k>w=z1|i*O zg)B}}11{5_dmHVIDxOI`kX)2<HhHUYZ1VFE9qqZhmXS|vcm*CM+;qT$7vN5_p^byM z&q3LcpA3$>@Ce$;480O)TQKMoA>og$fzVgep`RGb%sVmkMcHPw)2`Au03#Y7&+HtG zNNO^O=Ry`go&PK1SvxuX<@z_eh1wXQ$v*G-)roYCfAoWev%LBnKeUSGqtxYQNLzDl zRjU|iO8nT@Rsg7<phuiI3qlPU{<b|h)UYXm9yfrVFe9BxKxSdga}I1uz-y>KVEDq( z2PFZ)rvv>HhChmWCj7b76LUt@Nz$de0Ow$Ce6QwbZ7h!K&ep~>F#LPCe7q-wwmY4R zt?C{t(%=8_#KQT<`@Wr6G9lp1P@cGT^x>3=(+SyvvDat|iZErl+<cn<5FIMkUK7zz z-VyVvi(Tbw(;L^TjTN2CTEv!p%e*6UKF|Hpx{aDaYw~RR6BiWrrJ~$Z=)loD5Z$dX zfweO#kiQEaU08uI?#UcnFjdixeMVPl*4r^Zsz5aI$w~zRQ=l1)&*(QQ5F4mKpS1PY z>8Gcb7;u#Ns8a5e&6+uk2MpdADI{+}s(q?<_WW;O9gf5vK5C)Aj)W~Oc>7`3)ZJKM zReRYPMCl#^p3AUZR8@PxJwZl%S~k_i(Xl1IQ55>7=AK>)&?T6S20fr<6zDVx$_%;) zYoOCO=-&%E=9`+;LVum^xfA+w8}uv>vljwepmpF*^5Omas!nz6NYuk+D5YNn@npJ$ z3{u4Lr12)y`esy$0^`A~TtXg+vqJA6Sx8a;%S%WEoZ&qsmio(%mkbeiK0`XRee}Pu znT<crmBu!s7JWf=6L=;<pi2cj6R|rLB~RD`s$pL^%#G|f3tB@@ODV(hDRTVeS-MH? zbQz`l-k|%c+6#H;yR`UVtBJJfNeRzs10H$Fi%!d!j6+OS76J;1DZ!qMiW=;VV+boM z&OMn=<$DD2#8Lqu@hJIpfp&2&bh|hqW7IB=PChYG#Y>2zvCmkPeU2H?&x~T93V#m! zOt5o5=!^_H=z&%PW1ma{X9#2dcZ9%+Z+(K!{&xh<Uu=E;8{88WI9(f>O}2@OrCO6R z)S+vq!x*#<<u<Ez+wck_$eVlfL3@DBQZh-Lp`-L)y2OdY<Mw+JC%TUPH%grST~<eV zqE75+ZHrO3rPr{4x;WoI@YvPHQrn1kcOHBjqtYcam#p{E%E?)F(v7RTH*G2o+OkV3 z<YTUGfM)LUWBmJ%G-+dEO*L_fAbg^Uf<D`sPF*w<oH?j@u(WU4fE_Slb@%9RxRz}L zs7u~i({j^S5!a}L-<HXZK_0yDNd_Uh3X>+2&bfnxfAAx9PCQ1zzo~PgLHgMR!C$F! zYQ|gUc%@XZ2N*cIe0(FT(x}*#ka2xt<OACm?<?6>8>)e4H&WKqUI-8HRG9hvqxt*i zhk^r64^4@v84liYo;XDu4cm+zXxOGTD%<o|1D)WwXZH>Mmbva)9`95L8=XiQtL)xC zP&U8Ndg-Fy+17{JH}xHmkeq|)8q9Y}=g#qX<Y4ZhE1h`YepBg0JwyH`r4zS~NV&M% z=Gd9F&C9TdYwoTuY&$vhNj{+N;)J%d%H)h!;yOKz8oipM7auq0Zu1^+J-d%O{ANa; zip_mb@odhPy|=!Efd>^Srmpq?_3xC<aB$g%sWhXNP8|5(S2_Xqe~HqWvY2)S6M&5w z2XqTMpYBZI=qqbb4D_}A*y5f{ebS^HB08FHTIM~;b+nq>6j`@1i~4T)FjXQ?6ID9D zZC*Vc0NsfuCL)v4xeGkLi~&7L>BMoq_`6Cc3iE$K>Fiq|`?BxF)Xru;yUXuyZLjfG z!Q4`dVriFMeKAty!M(~`^Im<dO8c_r>RsD|j{O>!7q97?Dq~#i*C5su&~NkDZmaXj zAoJmvikBgJO-pKmr3MS^&jf84cv1M^`i7RXJl6_rTs}#-$SQ0{9UaVNp#5`A-zRUi zmiD+ip4Y*1uR%WVvXUPbI%(Su50Hn{63I>LRJwAAbDAYJpJcc{yVU3|A>-w`Wd@rQ zf;gN?0dI8>Hp3FcbVt1h+|d6}_{0MZ*0))>qecyKXroZSDnWmw@QKIFbydr!TP52P zbna}QKF;>y?!L#ew~gy{__`Kj`}3<-M1wzp5c+b;c>Xb<3ApgwgsSA}-JH2;X12|F zXOd$4%KgWM6~IHtUKUdT<TUEZ1o^%-qadfNpE%?o1+oG;u73WNkdy7`4++tR$K8@j zoNlG!{zK*58TEPZmS1Z5AZF=Ubpp6N>I*H+1$fSaN0>?fjQAh*PaM#G<Tv$Czy<yS z{c~DFcT?^hkqL`A3fS-&T0jm+vzsF~y)y@nXH74301NtF=G@Pie;h4y;-LM$%n4BY zqh-z%nr&a`2Q~U*s}~#;5Gm)I1%A`PB<=I_I_L-cox5rzaLvJTB*R@*jqZ^1JMO9` zKVRGZ!`^X>3`*uULcl<i4iGX4N$|U4a#uy2K$u|x1k=?ShsEhP+*MV9CCh)~9Y^{F z^j?3X&uT*nef+e&=e`}4)h{3D*=DTePu`L}Fu)a1fei-6T^2pM^LAs&XlnWS>b@=s zlO7M$P@Q9{bc<lb<(8!_zKzqry~sH<*Tp-)e2wTS0%GubBZvYa560#ryh?)4r9@xF zV*~eFY2K=MaDslvTNRBC;Xn73BSsPn=}$4^@7rl(Px^H4q`jP0;2;03=++^<o?Dl5 z3b8v<s_nv0<qs(_5pcJ!6!pUu@p$ERKeu(ryri$7WJAk}?n|hZOQ>igI>lKbot^LA z8I^hT{VW35t=yZDfL@|*gi$*IqXuo9V|?(aF`QNLpn(ar6Lc-@S1&up|J;7$&wJUC zKEt_$F85;t>ER#WEl>G&a78d~H!^ysGEZgSoW_*dHui<rUnWyKzu4y$1~;_u%()2O z9YvNu-J}7KrWu7WE!`Yq)IZ4IX%;$6>1*2WnW}=s{+F1l(kG_!=|i%cF>~Rf5dTY8 z9U_ku`5vOSx~0pHewgEdmc+(@^xSgt(Al$jO&5FSnCdC%^CG=wmcWjPa0@-l%$}-o z^YOFH?5T>M=BVHDR0ZexKjEp04^PO@#`41+EWu^~OJC#T%XAfacf?}Xt2f-6g0S&G za){i^#_R>3nlu)?pe7vkcxSkNN@*8yiVD1w3_~xs&cZi=iZoX=!<`H8BnP!|QW5pW z<OxlZ$@?-k2cK{e@9B@QS@4Na_*zAVeCse5)j=mrAEcw;?8HzINZK2yOjZd;IPgHi zQbK#j5sxFdZ(-d(^;e~2Bscs+{8RCVHt9<;;ScC*$n=@!@7{6bGwR7cR4nE;VAfbl zPP@y$KEK0qp(J8XvYrPp{?0Zve#0n?0VQNgM!#j7`gdads|Pqdhi44si)>OXg%5DZ zY%oN3<yXN1%4D0G!0>-!woSzktK@IJ;s}!ZpKqIbmxMnHM}KFuP*GQfLq+#Z{;Nkt zn`&}1gfBe-kBkaQY<h2r3X?u3sq&F}d4p$?Jp(+x?ADo0m>|c2JX~i!6+lXJqGj?{ zJqq$V*5$)WNfRZR4ks9x{hb#be^Dt%ZCm~yd#j%KAlXIV=9L(81T0^m7d<y-KyM=F zn_E+xASYr&wvra1v)JD)T_!R7kLj8u3Ke57n&qWSuyJWZGu`>gGVi~oN&Zhum(M>t zf-8EJkGg2nMRRvyQY4dCj66yhVPt^AvLXpKE>&s9JAb1hNuL(*+FeNra^5V+n567q zad-9F>JM43u+5l&%-Q6qKAW!W2HJZ9$BLfQRxkVRzdFlaaqY;C1TNzVa8!eczKF7> zWodCnc6(6zhH2)#_e>j0+e{1IW!t3kq}wbyoosXcAzPtj+|w5Xq=Un2A_!47OrT7P zWJ(VnB3zLid4T;`RwNlg`p+qnh4cX>?77#=ts7dU8m##gsRGzzn>L|)fEUk;W7wm_ zZ-;3vx#LE^#?iO4k*h`fW|wDM<+r?ctCx;v&#e~#^RMZ3?ngT69UF#%Q(A8{Tm;W? zhz2B}*D&8nk*TNgkkO^ckr88AiUiN6$J0!C{w681=tX6QUD2{+Y6ZW%=p6U?Sx08> zjrq2D=EIbMh3n2=b*130J@hSy(Nbj5l<dmBh-)WMWz4fp!MU+GZNPcjl`m{YW05;D z8_|Wa@1)2R4F3xzDRLz6zavHB*#9L`B))VxhHe+O3rl93LlhKO_bX)xro8pB+~%id zqNCuCK7o>ndbyVvwj=->&w%!Wr>HS8LfR7sU9^W!UI6{ak|3*H0O&@@BblVglRNR_ z&5$BT;(U~KDUt#6e?f|5tn1a$-p3+O!<^xhX`SEw?xZDaYVz*~`D|TFS6f8WhVWN{ z1$?)fFP+zCedV$`_1%g*T>Rp?F@N;)j_XMd*^W7h9ycecHAN2O$0xsUl_cMm*+9;- zzd{}oIn%QEOlRY1yXE;2En}UI%zkiB`J%mY6@qkf9}NX@rM>RRq=KEc#^VYr4V_jp zx&bgd&WZ{Kgh$pY%}8?jr)*r(sbmXwA*mHaf7IEAvgdoF9-la2?YP3PdB^gvG+ny# zr7Z95BV{<~8r^F12;ltPuH~5<qj1KkB?D*HcP;;BoPW7%Dbu!mlXmW|EAU;8lflO5 zV8nM?<2f*Jhp{1;jo_~3$ZYf*S|i@$|M^<uu~IKA!KX$zzDHGB%2=+bt^6D`HfacM ziLx*2MFGszU{A@kQhDAG$Bap990?jAku0xN;;8+(TI1q&jm8@6ZLsfo<g`uS)VRas z5tD?)vH&nS2-rf#LO_}y4j4RSV676O#k3y{rZyI0T0j<D=)M1=g<h~%iGsx@Y`Csk zpO899fYb1dLi7T;qhn4beVGznQBlG!ob63Q2rgWlyNo$a<)-rsbMO&(9__oauiAk# zHG`MPM<llEWt=+P`~0nS-Z!<xId+1*Vf;uYMcqnYhICOsvGjNwVG#up*|}hB7!L(Z z<?k|4I=nW<^U5HX=*N{>T1x3B_BxkD2T|^-RViz$s&Q6_*H!uI&r#hsu>`+R8)e=a zFxa;i@JJ(P195=Q35XBV!bCc_aAy7p={%ANA7_?k_rYQ%n$mcTB%IZV9HIMYk81N$ zz@yr}BOcW*00*ATSkRScaYQ;*z?5s591pv|Qm&F&(NA|oG#TuamX<2v=Mq<F8*{sV zXHU`bKs^OLcH_y_JGu3jLhvFl%h!J(g@je-3?s88`Eb*PUE%`9me!QTuhGR_h5d%B z%Eq*}&^N~!od8{`qCcKibgsAJ)2!WMeVtK7XW2J*<!XlaT<n{mm~d;7`@3^0pOvP* zonAfPtcNzyf|}>%HTNAVOsB?OxATa4S=rouD=oiu`_lu|xqaJOUafuLx$ul}*K*e< z$bAIazI7`)Ra68c^ckLDxUh6_E*>HH$<yUW<}GUQzT;=?2!AbuTa^)Tr)4j`RjG<? zRWf3<I5dqGqZw$7{71xSo3w<403$}ME>WinD9dpYxn3?DR2y$6NSyoFY$E4CvW5Za z@SvlkYDNf8M~E?zIB@y$`VKOCapv$?ZU^?JVS<&=$qzLYgHxU0Wx26jQx#<G=Ty7x zN#^HIu$;egY1*`sA+7|sVM0ZqXe5z*C(X@4QgxoK*16Qis6(4c4*Zq^h9{@LpnRa} zPP=(0L?po(_bj1b`rCZiK7HGVrPo_UdZXVve$#l?`3_r=?Qc1-Y2HUZp27y9pgyH@ zxQ!2qvt$F1A$#+$=gidedyuCQaD-Z$GH*SJKg^;LHOkoBTJE&=)4Ovv*S~s!w>%uQ zV<SQEd|~j;GSbhbK0J7|j@$gZ^fQ})oW){i1vg?Xer$7sn)t-C%kR&Mr?BZSmge7Y zvQjQwe~y&V+>guTA|fa}@-A&92%9w6mEe=qqMTAS5|wA46~p2~yk=ZS2Wt}KRPPwD zRfQqs_;@U0D;<XkCqMvpl0(h-jr@;K^7&$-6nR0u{vc_XvVZ4Xq+*=HO$vo@)Oq!+ zOn!;SDn4Jvw{GH^S{WKnnw2=83+%d<)!x>8o^-60{@Bg2&I8kIulh*WhG1`}wF=N4 zKlomaRJ_!j!fR(=xPJHmRsF-lycTQmrr<3W2v8$+k9!UP#62M5hauvc=qhD~8;-aL zW0i7r&IkSQVY>bc*H~lA;f7xszDt>e?@}^wchKKT!#x+poofW{avxn7AIuCElUlR@ zEvNMgkj5Kjlvd22xIn;wtAu~Ik%Au2?Io`%M)X9ME?>Wi6hax5$oOB13rrfB$OPJ3 zs93ec9YiN!7b!ux#qlXGGs<jxzioJ_(y-Nj)Ds_(?bZ~kP0)sxD=7wf^Q3nb=4r;G zqpe%>E#&~#tti&S*$`{Ewwn16#~Lo#z+KAGPy-vE+4N;fxMbu1!?jg(nUaC@0)1y1 z(x*|Ri6fBy22Qvp<Aleue8N?P!YIU7CPMKXFWwu3OLX}yxY4y@!J9jkBvOdT?GR+; zhG912kkI>fsh<QD2Duh!>nm__rMBoJw@mjSv0yz2Y<XV+Ti#p(;?W6xX1fh)mK?{| zyg!u@M7tM-qFdf+;N*`BmT2pyZ)|_1KjI-M9#OkxZ^MoUID^EL<A9e_TMFyeEbUv+ zTPdPqqvdru)g?eD`pyk}v0`=Yvds4zb#fZww|CsHKRx|B8=uWOVIFHWJ~VdQTYD5< zG%o4;uw;q$8QF2<`{B-zTuxZ8M4c~wu7zVsZqt`--C3L8ujd6<?5~vL(?M|k;D_{r zQFpQ#`VXu-IH_c64dxP%7uaXy53R6r_Wh{tV6>9f8~m*9jOq<ouREro?(7ccQs8qF z6V*DWFCj41tXaUgP=AA-f(*~;Ljs|a0tsfiWhQtWKLc|V!9L9@lL0}qLz!j*jWc0y z<+klv>dp!=%bfxy`w0<cZnLI5RxNI&_W_thc?`dy#I4A%C2_&;CR#oC4mWP%oYOKv zT+4I4jb`29^!F2>pHE+j4SKP^ay0C@VA>UH$Y`+BIVKbAV4IQ^*uhLIYvukAg&ivk z8JJBw?|08X>eya++()f*hcvUi+XTJSrHu$P?bhdQ#{s2n0;1cLqm$HF)^_XBbxPKf zlw3PgIbd}SFj@d@pT<h?xlI=Z7Bs5TsexPq3U-L`<WKsm^(!PL)HAg%#aP^=405Oo zzZ4Q(pDNAOb$E5%4Rw<0b$#CH9^I4(8DJ#lQtnp3zOyv4a`$HH|14ydFbkOqhAqJl zYV&mRzLlpWB7$Jt^;G!sEP$sjJfL2T0-Jve#}gJ<hKR}Bkq#k<7nT`rJHXXSd$?L@ zkFQpm;;WSmUZs{gkH)L4P+k=_f>*5p9la^Wt9S^@ok<ssE>tPGAiU|S8LFzPL&Rkp z*QpfOI^U5!x#454nO+qlB&BeYqn_iGgoLzKiRd1rb0;z&2;A9jFEJ;IQSP`pY%-a0 zK9Vp%bds-jfM9ZRdeGp^C@$%6-*OWLbKH(Px1I}bft>hw8=WZlY^U3#mw~CZf|YqI ziowjt^+7Rt0uoYVgwDTChUhI~WYsH-`B(UP)A=a#T51P^EW)t!h4usYf8>dT5z>9w zR_f0PyecpvvcS3%OKzi#HS%km#%Unot0gQYBqW9@Q*tke+r7%_h^ou^;(rc23bkiU zY#m!C;?8lOUtmx`j+Z@NPIRAy3AYLOK~4^t*J3>GQ1w#dqsmI{*NH7xBJS$q3yd@% zH&OPgk(Bov9wuf{Ht`e4>9l7JcaEZ@1D#)114<hEO%E)N6VgX#z^gOx0|p_YQ&MJ# zJXy+s7$==hUnpm@sG#}C@Bkl~ha-JtMsD%5>cR+oWadE|Mx%Mi84A0&b+y2x7f&03 z4P$}+7caBoX|eCdbPO1LnP@iNe(E9wb7Twz$Bt`2%4w7%<E(2wW@RHB8NGlbBkm?k zcPQ<q5Apfc6y<5ZY;NNFpg8{Alvj<4!CO|&EFLPe#Vr5&{ND<s1jfwpyqw*e@%F(d z<M{2VFD8PAU5sY?@JJ9na;f>#z4G$Qsh+4=Owq<zw}2`3ami2LuF)3j=GA`FJv;CE zqsMGup5}Dh);AzjH850P7!6=yJsv8UTXAm69IHqI@&!B2UvEQldK5MZ2{<`bU?Qh@ zu-GjsX~E(J!J4J|6Vo47olE|0)1Og}vd*}n|95S~+7S990Ct$|W)UVr&|k-hpJ(Pf z7G0c~gkCd{cX-A)rBP#V26&2}<7!GN`gE%=Jx$7pB6Bw(n`~>R+Z?Ck@7d61Jw}*_ zh|EZ=0Kp7`!92%EO+_d0V8ZVX>|w$($s9{P0&)(Er4_tru=uev3M8wn*bY4PA(1Sr zN_gbM4Nk~SOl92}rLoJqmYuRrKv;hQdq(*U%(iLIc#z>a`t;;-h&vth@AJ{pyc77| z*arkbnkOja>CXlHp^<i#_B5Dsr{Q%ZdX=WcezNYxTvA}+S<Gv5g7UcJH^P^l`(57J zH=KPFM}Ld83;+K92ii*J7te3ey`JbbU~E#`*Zs*mPuwoQIk-8M+ngQAedPt539xbH zBM^Kol(t?6x0hJkCpwC@GUGp;fE>Z_PlT5Rv3DSEy^ZtMm=U}c4*~m(7c>_jPT&G$ zHOd7@i(y~l`0u&^t-xM8q)&3TQhM6-bk^Fa-MnKPygRb5_wqi~-qhD(=p+&P${8Z% zd9&$jY2S9!e5ydxyq5FpmwBA+=R`@XpM(|qE@c;b%!zX#((r<yWG{|1>|Yq9l^N&@ z1Y{1KwZi_z|A!X@bk>UFOiZJ>EuBZ*mgbGXd6Wsz`9IeLh|W&^YV;S_XID-xl%l%< z)8AyJ-zea|WewQdtQweQZ9pl<hBuNi!hOC%y?u#NYu@f%{>1z8i3!5N`$NtYeRX^{ zy;M5DzK;@f1U~Tq$NnF9<VP%N?(TQXC<@f7>+8BUuI1e>k*>xS+gfh<ZED^SsN*4C zJ$O&qtS1SM;5Y?kCAUo63haQEEI#@a#G1B|*}<q!Wn1xB!}^4CSmsazJJ1g7oAQUg zS~-b7s!zB!O7jj>_*s1#*-ZRKefmc&fx79|=JauO`U^93v$^>B-woext~rn^;$h_+ zP;;V&>|mIAvHYzceAF`P+In<@a5bzVOpuqq9tAm_zcND(o@ZnQa*V*T)Drxekdx_8 z^&F?U$O(!}JIYvj4Ff}FPb>>7(FH?jOFOB`q!xf`3_)eO)U43KL8WmnoWnAs%FEiN zCY{8xlCzKmCWp9HEZ2sAz!iwzJYjeFdLa3O)<KBfP<s9&`{zF6E8JSVo15}(9$t7d zhC)DWWsJaD3Sk~Z(wk9dD|h2a!aB>uUYVi%f*{^lPPpv?>8mrOug*AqT{?ok(peZU zo0u=n=$8n*foA^98%T-8JL3OO&a|kEdJ&spHZ1SJc7ro{!64C7!=_@_s+^$SZ!?V8 zkQ-5`#*A46F)67xOL62zDXI9DD;UWA9VK<@pQ)tM?N20RMRnlopl}=HV!%eW`TA_g zO?I6&01xdI6ec0H>gh;$=&aS%8HdOI_k`4Vr@vH4#bpM}alUU?gX?3<bziD<11p@$ zIa))yB6vH}WIV=D^H(dkN{@Zu8nW~4`%|xq8)Wzo<?S5r)rx3vnPTS2=3~${Z@p*X z-RaGFz$sA5yXJGzYIiTHr*%?(o9#-!>o+g8bB(*qK4pR`f~=e3y&OcR9DeppBI@m6 zJUWou;6#-vJmJ47qN4Hn*=6?MDWXoc_2Z0Px3pR6oNN6Im&dt&D+PJ<D)k;bdHB`A zKe3!Q;AWI^T1A6hNqzal?Q<rysO0%yFIqQYVVg&URNsWQQ>#t;hQda<1a&zk6nVTm zU|d)v6{7Um{r!2D6?Zq2go#t9t}eYoPP!=DWi6hP_x5YgSg_E^<`D~S7zx{92$`hR zY6Cokqoh>)0|Vx?zayoZ{B2U|<-pU8@)nhqbp4L%nIaP(s8MtO$s~<QwVfYV2JBuU z;<c-0(CPAkTida(Z|;)5>etOgZ+tl5jZe5|-J#&4OJdFk#O;68Rdn=mrl0?f$t_}I z<Kz}2T(w@I0Qm0|)f&eBGi*K>`<>u^0LT9K6;%}ezeG{x!(OEe_#k#@jQEz}OigT} zpy*DF_`Ki%_b$gPjeVQ14{)v$+-Hlf5MC%p7n$qwRDgtSB_saWUCj0BicXsz-Mfmb zz&qS?;;lCVtY4ysoLN!53-*SvYk=<*RUGQGzpJRCNdG4k)hAQayqbiUiUmYe@6k%X zyM#(zy<9qExWL<6b9>Jc-7j%{c~e%#gj@=5PM<OScDwYJ@yfD?Z{E{vdA=*iiy9pD z^}(U8^hehDFP4gAU-q@r_|RIvXyDPuvkBL&8*;sk>{?!3c+Nh`qc+d4=;4l{=S747 zFtyTE)6?11{;9l-T()6(%VhCI9u3!d@|}Sl6nUuFS9|E#;(#Yp6dSv3X0QWkbujbT zWe{bWOD&VMTE~w^8CD~lmNI=$z$%CpjSrVre^rhCOpUL|b7}00WA4ZM{ISjHbPJs= zcGJuqFDoV_zqfgsQ4~irg8I&-Hg9T4xuIY0HyiMtRzUK@@%`OyVTKxM{)kkfr4s<1 zw$I1}`hChM(CNgK33M^mK*xpEzZCS>Yogw*64!22++}*TX;3C=t^GXid#J}M|Ajpk zVaKICdQ(cM&jVc4;vAq`P~664;EIx<2}?4QwEAGw{0C!#mkHC)2urr*bXLkP|Ep~E zXGp6zZ{^}Ep(B)3%L7kVi998k1HfAJw88(+hp;gzsP%mKNu;rPhb{K5bV(Y|^51@2 zK}Gr0AFZI`UVC1&4X<ZC*rBrwhr6^MGN-EhAF^)?l}B_n3_vO5g9CMw4?zB|kKU6% zT7qK7VPUdi^A`S9TYR1EJ)M1*dbxNDFY?~%;IUoKV}qBwvlIBs<}Fqx+|&7x1Cx<$ zgnFxG9@6W?idxAnd#QUf+XKJ6n4*y&Z>pY|Oo-h-^#NJ>(4N5f0*yn0Uo8CAHpN-2 zox8ezh<(=vbt8URo-y~iKZpn)U6)~hYnOtQt`z$PAz{Ti+;fbSh{8z$c3ZEcJ@E7k zU=zNZmUgLo?YqZ*-9i1W0e80h54p#l<Uj8GWoO=$6$#nHhKkj@iZ@u83@5p7-|0Qg zZF7p7L~92{IjNA(^``5&kWUAWwcq0Z>Tz(Iir72Tuf>@=&c3#LDAv0~+>0%CntwD~ zf;!uw!XxMTUcG&I;NvrieS5AVxdGo^=h&?LNEY(nT)cAS;`yhIBgeA8&h&bll9;3u zW?Qs<QnukIiH4&)G!?h0$bazXQx8utxT0{^{BXOZ{Stl2YPY8f(Oyrl+P#+Ar=~A^ z_y2Wv<>6Q^Z&;Q{BxET|rzCsUvP4-z60#L-wyep%rI1pTaH16{QI=FboTO3`EtdL~ zk|mWk4pNpDg?{tS`!(-4u8Y3@sIIQ-zGt49XP#%~n|J1({er3vqq|n*M$2ElaVlq2 zDk1%YKD%4Twjjs6V=KB2tc;Kq=Zy&G6v`~>_i%c#C7?&wKI0PCyZ+J|xfhE~Gqvu8 z8ryipCT{28IeCZXcAlS|JH@tP{&PNF&iR$2*&Jz{DNbQ8LhALF$w+WTT(je@e{h`T zaXClcf|bu$JqKm7XSezreaq%L-W|K^n#e5yw%+^-u~n6y`>GZRkLonceSD1jjH`0l z*EttnE)rNPxMi9=U#Q*8DTUdeVjK5nJ-ceBA||ELvsTWq!97jB#mCQY=lB2dO5V)f z!`~45q+RarB8AjtJ;D1;I*hORmw1;2`h+d5<7bn}EIi<(;2oka9Y1g+C%DaJ)8eBa z96R%0$IGVa-7gi=e<*cko&WF*<JzNgt6yhoTjm+H6<@hHCD6?A;z+5}#p!jQdDsTl zCR`PFT4G!Cx@Vf_rG-zM+|6c>O4f4L`Te}rN2Ad!EqrF&U#~FdhHSk^q_A|s#=GeQ zcCpQ!6=%11pFH_>=Y?v;70j%M>-jyU`c_%(s+X@w3(-uE(tD%W*Wu2#eD1B6ykQ^i z^DJmrw|C$8ja60ns&FeU@8-NSW{;vx2QGWIoEH?c=4wnV<f?h!92xdZ<9JmUjZ^QR zA~mZ|`nN5MpK>auN;YJq30b`0wOh=5o}(#!S9v;X_ftpy9abK<Mr5`5OUj%aHS}q@ z$xJV2y*ey$aM!WYv%5a48DFxB&A!T;F6kG_+UpUJkv6D(Oe#dJx?8j_GR9-Nv&qc6 zkK=?2Rpg%5^mgV8a_4x}?6&v2u2j-iW}eeLBlm;Xnuv(0r@I4MeK!pb*BrFm%`euT zw9jR^l74I85lM#-t@_ZkZ-XZ5^oz6SMX8v5^?b-(o`2JreR*b1O-SJ@VY&S5s9i4W z)x^H6&hhK1dQ@Z>{Uj*EgJu-L?iVZ*KXAQs$lBzU_;k}CPiF_wK&QU`O3$nNwDiqs zyY3z3o~rVk&t%Z;r?XY^=I+PL#mh?Oc!&41J>1TBS1Yh_rtUXAPWz8}rv|*$)glC6 zDb&2azQCq#0b6IWTfWbJLypZ_;j-cSdi*oaIJ~dQ|5-3&{gROBw-wHNIer&?RK9Od z#D>~NYmFo)qk*EK1A(4pLti#n+t#X#*#C&uoEfopijPtlPvRH-_>Varx+T8HGMx1k zhh0nr!zC)()cLHQ+g#sNkbCAH8}A*z0?oGi&pIx%bateuzMiRVG3fI)+Usz28;hl} zY~c%Mv*uoJj~MrzbC1$2ME1O(ZCl6ojV-1{vPb3I#~qQU;~JB$@7opG|8_Q4f|HK8 z@RCE@?NScT8_-qRcj!0|>u$@P7C(o(x5_c;>SoBCR!`nnx4oh|bABX$&=Q(vP}srl zZC#c2#{Qlg6g`SX`TohRJ+?^Tj7@ahIlqGD<okMMMkB@pD^BIeKk(&9$SaU__m5PW zB{@H2_JI-w5!1|K!(ge(GFgpdY{u2vPD(vL(%ZOJ=q7gs?Y`xuVbkE%B<Iy6$itJo zL*h<n|J;r{%8LedE&eAKemY96YhL^e;iS}|(Ze*~%NMVF8Oh)76Yjns)VA05Ku(8J zOX}8(9jkOQV&A)NdwEX&Q}EOyoJj$NT}n-BOAOc)G+b$KyiOn0zR7i5PxOPX@&>uZ z^^FluTX!U1(2&S}7PYghRXC;oi|F^_X7eSFpYENpS|~`qQY!emqPSqhcX@Lqiyes_ zUp3Rcj((GfbgUfmXbzadUORMI+3mK#-6z6RqN*w$iW<E3Png#p_CxqDx#FC2%`YGA zjxhiGU)7t^{z~`md=DLTcNsC2_)#emsU-2m*Ge$dw}#Wyu&?Qq(z(Lr9@YPbcF210 zueAA_scQ{S-6M6c)U42$tdleuCmkuP9pU|H<qq?tg)KJT=J(FJq+VoGYWak#$|(N1 z*yf~xB#FL?6>5(Eu8RJoCThzav%vM5YvAlnEv4B3F-He4${24p<}aE$zhuUVO0EOE z4}xo6n;#3a+I)R^sz5C3NU*RN?^_SCV~0{y<_sSCVQB{bO6+vmx>{r~)0AcKY<bc` zW$~Is&ABHt4?J%(vgJC>V)WyuOoIO-m%lAU3dCs%7rI4u6vS_w(^8b`G@x+Yxpq^- z*}K)Jg9E$Mga2{9*1E>k%5D3D!^fX|;Z0}eloor}STAUm|Lu<Bo&GOfmCT$D!5Xt7 z)noSY?R`5hR66aFP@46R`CaSlp52?JzjW%Ji&rud7N2k06Oz2$?ve8<w>jK)s&y@K zwjGIkhNat>*Z$y?GhV6CX7E6Zr}A>6eXI0?tMB5(_scH4%)YRwTBUBDcbr^UeNpSy z<|Ui#72G3qQX36w-tWI5z3fXdt+-+)OWbGK_a)|Q?&^FMuJH_JKJ-5G!6xP4E^*yx zJ&!rLF&j7yZ5m2VuS@UqujnrE(Xr0xSXrGXXqZt867kS{?huX<jqZGh>=W&EI@(Ix zV&2E^PEygnp>d|}U5Zyv6|HZ-i<Eh8-~N=l4$Cy}{5$<eS%~$j<2FCpbuCh#44BLg z&+MH4ct9cjZQn+*GB(zX^-Hb0<kA=K-flAEk!I<&a}k4n@mF?_2-hdx=r=n!{qB<y z^}*P*-qFCUv|eL&qbOm|fhn&3LYz?zCe4;iGOh6;75hK7+kO>@k`kz;S$@5uRj@`| zELiH(EwPS*(vh>TS6Cf3Jg{MYwW*2BclnGHJuR)DL%0PEuG<{aZFprLS`=vD!Y8$0 z@zDV0k@YUj8p14hylRa+uBiF?uh?p|a%<H#XA#xhH(cvAOgOJiIqfFC)b_CG|EwSH z?M>?B3#}1+#w`%;{w*O*{+b)>IsLf{SiIke9`bH~UA6C!EN}Ee*MW4^fsnNP$bM$U zwxzyT1KWq=B!s3K^hR0OehP_G$V$muY&zZg^1V^+vVw&HTaK)}tUtnc$)GCO_E`?^ ziMn>J6Ax!82uP@A9zWGI+Sv5PI_yJhRB^84XK~F`k=CD$O{40}MoI@yJ+0DtY*DS# z8>hpuB&D7vakjn3Vw6>&kHw*yB|Wsft#hvHk6S!SK{AacJIhm3YT62Cm8@+NYr7r4 z>Ebjikqev8->1pnWSzBnbwie0pZZ6plK$@4VK1#%^OuJ1g2Ux&cPnPyb_udOy(nG5 zUj0<!w0XlWdQOekc_f#H<#BY3T0XZmE8Q|D?8NQ79fRem=~@Xdx-WmXiD`V<IA{|o zX+31eHGQp!<G(yFcl0vzWJC!Db}1H^ck-W~d&H7Uf9|{Q+@pK+g|cgh*F2ONxKZc1 zF2LNx?t9}$#pjhfE5fHvPdjq>mYjD`hvHDo!e_%jOJ>FGl|EbX_I%mCxD3<i)}big zswn5cP5&_8)83!e7MI(6E&YwMi?FmiP4&%j#c+QgEjPAm<3x^z!qv7S)A(8+4y9hc z>iKAmL9|l%UELFYLPmA(_b=PrVCu0UD`aI$6q8$T9=M$^1}_(jDZmx?Qews3UPi9C zjXb?wXB#=VdOH{exNdPUGYIx`2vJd0Q(hF{>l*|xOh>_w9WMA|M-$N5nPdq%6LkY- zDsiyIDTD?51CVhL*-RmsnTd*6ZB{B9L8M<09eDyGdm&PeD3j#?Lb4NOg57*N)D=Qc zQiZZfASf(!ixnMd0g(qGQh_LRY8*mNLnm<P;35LdA_u|p1epC90&@^x;t&ZPyABrI zLRmYFI&cE51-m_TD0#LPgL1w?#gfpVP&(8AmKsl4zy-7_>AeLlAbxw(v5FA8g=!kN z6T-r#!H=GFFh2xqQ{WlkXePa22nHuqmA&ZTWC(svfqAmVg27iW1SUU`^+E6=qSJU6 zBQPi3Z4{c^c0NrN&DVg?&<=1M4HZpp?j%7l)aaZAj(*dPhQey(9yP+35_YpJf_SJ7 zDUgitq&g(<A5}c5+tx-|E@Xn>&~jqK4i&BgI|V}vU-%Ci>@*>?3`8eVrp)d_XlM%D zL_u(Q2zRGiD#DN8u%+Y&Y=jqr_+?b_qEydNg1aie97={3Aw<j01Up7-Eh-+u;b%+) z&w-^A+NkVIu;0Z$A~>{${H})Z<U@CaDkr`8zd(+l`-$v#;*24Jll@LeOR_Vm5F=(j z_(O+}k(NXZQsP1hGL#91gezj;Qi+J*23tT#^3hu$Ngb_#Eg<(|5uTElqvID+Bc8;= zZA64OhUH^2YEs=}4WjRnA%ZR>U?O2MVB;8X^RE*Mh%p;7mV+j6kWP>dKn!RSh*)%% z0VLW~)MPqdE`BT?_!!3*Li`{sANHvNILS`82=*!AWSl_00G>q|w1_$u3=IOIi{qVO z1<4SvN;pl)0963>E6C`@DJ=wrMHy1y$WYEk6jG^&2w<E+ie$W^TA@mP0*0+19E}sm zLpK;f?LDf3Bmht21TuSLLa0l?2k0@L1ML{YSPC2NMKxUA2Qgs7NnhiYQ1Q$`2B=0J zqEPWnZW;n#lQ|a?me#Bo3y1NH;8&nQnAY*q%?J)XN5(V4`$9aXva2JA@Kih_xC?}1 zJ+y2uf{%%3#2~L267kHz1jpWT>Npu5&xo)MR)I-u>VdP(bSIGU32*x#JQdIMU@)M< zjl{!vMtD-g4~yp&;i!CQ5Ivp|VL3Dii)X`JM1XDn70-x4&A=Q?a3x~Yff&DLU?r%K z4jh~UizjAaI@tL8STJxf0-uE7J_v?0ut@>}qZt^X$*v@3V0zJ}vIzZa21elZuxMfi zruXA&N=N|qBN@X8UqRsE3``%#W__q|a^w&JjNs0&cw$cFV1kxgP`44$42;m!3`|E` zQj;W!22Mq2Qr3l-f$64Ltr=?ybSZ+9S9pjSnBG$B3<QTQB^`?J<I=Out+9BJp21^& zXvRJUn~IHKTX1j<AHmS06g~^$vGlyoAK~GMBw`k?z#kH@^lT4KN8=TM^o--(As$Q5 z>#3;4(lbt}BPe)!-q3@ppwctWAX5XDZ8u#(3^Ln-xWx(M(z64l8b%VJkEwnlSHW2F zadbsBkby{~XS@n>X@;d|r^ASWrDvQX2Kx$oNYD8{FU670#@0AwhQ^c}T_|@$vq*Pi z3^GY$!h)`0W6h#F9HWdAwsZf_)I_=*V~i7J^Eihpf#0Zq#WTKMYlUvd1jf905Q#ja zLk2a@Ar}jnc-2;F{R=ypn3q8pW44h2i&3`Op=wA9>3WP}2K|x(gI0}LV)#(aftJx@ z9Ir+Jaxk$S-vLw&?1Eo`j+5p>l0K{mu4VlHLL_J#IRNk}ozb`LLDpyZrFFmwgO>gN z<KBSs2k%k?)(fH{hMrgkB!*w^1ssMSo&_AnA6Eq=GIcQYnkZnALjlVL6F;g67-TBP za>2y!OajJL=u|8h>~<VG+)yq+%ZqWjVB+`oKqcdH!K81+0a6zn1z0Ya?A<fK352b| z0(+7dv;c+C7oY%TobcFWj~oHcxLh#lBR_yNZmmASV>bZK$RjWS&d|Fg0Ph7m_YAen znczhX04G;m*mODZvkri9A9@^Ht55h$0U$6WhY#@M*6I^Uy8}GAD}=4pCzLP;1afhY zt<@(M=mv~&^Zmpk)qpWB#wS*828?3pI4s5|5fTQJaWOuzkS$=0i}6WCSOJOLZNXxE zGC@(mA%BNsF+Pb{C7_I(@6T0@O>*1dZ!{zY4k+VdJeLnqsQDgVXGIHd#>MqOMGOnf z0nQodQ0%V2WTI<;Qw}-U3HC{4zyOJ1`6<95_g%5OM!zAT1ZZu9efY`M$+dt0D-^a0 zJCrx6$P6GcE|CIAe;@+_Smc(D56qeHvgmJ!T>zQ{Y}N`$gPLuVsyqM^<GKfcR1a%n z=mtJuML-rKSG@s=oIe=6q6~OFL}d(KxCJzFEr4Aloc!)4VEw`ML%<?`OJZaGH}2N~ znilLv1}~EV9=R|yfWrg+7@6!U72uFR6S15z+5IBGxee{Za>k^$UI1x3Br$N$0&vFV zjNiB-0BC=3+8wYMKRpdd<Wc}jG?SkG1tfLY6%3tk1*|_g-U;R=L!vS!PB<vwch;Zt W!2iL?#>u|3f*-R#-9i^1X8J#wRObT# diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_WZMG.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_WZMG.root deleted file mode 100644 index d9b5b80792e91bbdaeee6f2e28a50dfd23199c85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65394 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 O!MpY8fY24knf?!hh-(x8 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_WZPowheg.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/F_el_Default_WZPowheg.root deleted file mode 100644 index e25cd6801cfb9e7cfaf2005ddd5837e993f87371..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65343 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 IUy{c1f0GMU{{R30 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default.root deleted file mode 100644 index 13d678bcf9379067e93e2d11599447a868483f6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24217 zcmdtK2{@GP`#%1RvF|%&t;oJBWG8z?meR)9*O0X^F_vtVwXC7gB9&bwj6EWivL=<1 z7z#D23BPBa8AHAAzYqW8_kKU$_t$Z#j=G;o=Xu}Pd7amF-H)%gw?6<pDF6V#5dds5 z!LI}0?{&d182DvQPWX)xxQNadfEmF2wO$6Yyiez%$jCiY{|Wrtb^SOG;6KR9va+@f zP=P)f{MP`0!cyPO(}~O6*2&XW-`B~}*3!&2P+mb%PTCj$ef@v_1^6KNNzkVOG(O-5 znS)=@Cjx-w_<#B~VGQ{1hD-%|UL5*v=J3yxTN=vgQ#v_2+u8-f!CwyVp&kMN6*Ax? z%nyN(cS86h5GgK*AOwQh1wpPOh;T-{Mwsk1NidakpfuMKW2Dr-Dw?F2)J<vL@{{%9 zTYCgq+@O+dI8XtH>k7j~lGrKZBBH~|J@oALoaNwV*3qbF6lzw$+Wb-QY=HEUCGNf1 zcVd2MQ-%*{ZIa4oEIlCD{rbr#;EGl_jn3uR#wc_p_(9t_A4zmnzg&XHe;4KDy=e8c zMIQ069{qvaF`X}i8$RCT>Zl^f!(GOVP<k`4KyhRg+w?7eg2fS`*RuI2SsUO{Wm-<A z#|#JdQmA@>EXP1#Os|3gTmBUcAAcekmM~zN2u5%RdIF8E%tei$P}(^t7HU*@CJGfP zwL?m(K0j)cA*@K5n>+K0)-$c0JccauCV~kGC>kN>Q8YlN#z;?3wMiLOC~L?rM6MW% zs@ht%wITy1TGE7WLZiPiN#1a(`?f1xD(vjl?ta}xLAaJ@{#i~ls`N<VByzHtLO5cx zp-*!wMo@?GJOkoPBwgAk%J(5U-(Q*43#18<6^-R9HhIPZX&_q<Ti(VQo2$dHnh*Ej zn9Nek%oqoxZeEFVLQkB0lONH_VI9S|=PWFt$yHHUO}2i7Mpa@o*6(y66)lBDK-HM+ zgzmzfy($$$uNd_OZec<kpEx+x9A0SK(cffTE2SYrA*1oJMwQ`Ba~Fj$mp0{r-Qp1@ zXl{haK+J$<1yhH*vq0e22&C(_Y~=19Kipj;6UIX0Wogf?5pP>Zwf6dVvo=ZFft0s_ zB_IvO5DhaB4HEc02|q)kfeODTo&4>HJOsjknH3&dAs$c=4-q6D)IlCJs)Uj^8N%Na zh?v6@!SN>|;?_+B7jq;EK7V<M``n!v6tCBH=E%jznS!#9mdfO~2O6U0G>cHE#s2<V zzN%!S1IyIpauJwiKq~g>w{f(f`PV1NOR;dav_x4RXT_F%lxOxx=3W<i!G>6l+*7$6 zZm&Vx4y$#tQY@qA=9A&IG{dxasL0AuN>UX(WuHTT3*<VFv@QL5{LaX;&Uyn%^#dzh zVXD79V1MwfaCAm=H}CDGCyO2yk4vg+RBwfhWqH^Y@ts{>`gm_LUd2W>AphOghv;}i zJs%owIEEY-^>Yu-lIA$BkRcvRqp31IR;#Q{i(xysRA%asTxohjqAc;zQ94#Q5Zsq~ z8f3~DV(QZBfuWEkF$F~rM{^=k3NYXjk*F-_z@+t{XV7TD$7t#(Ep!(e-FPwUB4-|J z3w>d@IWPU$J^KaS1hW|mW4{Y0wYH+kSu4B|0F04}@=P>+j+QyM5G^a&<`(qfWb5QZ zT>$$5JA@qq@ssM}^KzTeOOGyU>i3RMT|S)z6WnR0Pj@}Cdue<RbH;l?*gI`Nbx#+O zp6g}Hz<$IsTt`()lv1e9jOA|Vc20u>DU*h!%Ub$Pyy5nAX=7+~cz3yYmNg~)4A<Sz zb2E40Yz}B0+0A=%;cYcIXTi&*hsKge3UK{ba}FK%4iYK$8e}!%sD(#I+_*n<B2ZP4 z5hIZug7#`E`$Sh=KOOxMu2&-nm)OdI7DmvQa$s4gbf?))7EQB#P%AaPZ{wM#7Bi}$ zvY)$<8bC9;ya!RXf>1sSp)7?z50n>4DAVB2gS(SIDKZJbfU`uPClUBCZETMZ(@FL# zVfytRFiiItONoivQI?076R_sMp9#KS&V-<av%C+PkzJCgA+;+fe0`BRiIK`gkcOP` zD<c@0N*i0%w&*ZwQ=#c&3`I3*It?aJhFV4-hkGQ?-xPXr0uhGls$2$kY@&M~K0?5F zoQrX*^-+}G1iFR0RP?OAMHA!LaQ74C(mS3ruv&)pdYOSA)%`Q1J$-m^;bDGz=ZtyX zY>Nrk`R3=5R}LnjI9R6eJKD1n84;X>^tH@JiYsZ7--!jp0Dwu=dJ_n0As$q?1O%!i z9#pC+5~$R8P#w)&-H4ml8wN<g3DS4K1&?X)Lum7MkT!2Jw0V<~JLnw&VHGIe(}sKQ zOp+f@*W%=Yvl({PqhRFU__(>fRzYQ7C#d<1HiDFJDtus}d-x`jR&L-^RP110)U)(+ zjp(KAY0JQsXG;`mOF&VB)<*%eA52k!;b!!VS~Vyj<q|VY^dlOb6xZr^p)i<{S6WbE z`Z8l=R-%pyqNXH%`$bs6$7s0d%Q%2)dt10wqpPCSPcZt|b);&}b=;{8F%!)wzR4G( z-TcmU;LvydocW4oy_NV+RZv3=G+tFR=R9slUy#LVb(nzgCr`d+m8BeT!_In+PLH`a zW5zbgPmk^7FEd3<Rhar<Dorc1Jo7&PxP-L#zl(f(MjBT**^TW$=1p6KHqKH2g+3Ra zf*d778-Hk32xt;X96>^G+-XISkHLT;;<mrv1_?p<-wA<I6{yI65Q3MWBCD<{^7@59 z1QY_@26!4pB`qzlr64^Oo9J<>qGS1$0%_-?o*Chfz#dTnyY0IH<6W|{j`k-)g>Rgv z!tpp>U8K6+VJ%99A*3&g4}8p;-qK3y;OWq_Q_N!Z;vQXrH_$`^$G_=|_26-3EV8k$ zrj8WxAD?o35h^j_vT#ECaPXPJs5;{px(fkYcVK4{>#mXeVX6`j)GO*vU@0<A<-gm4 z5BWQw15$;IKYt5ZURH)IZxO&beg}zY*^Dbp+Ku~?PKG^%GRImmscUTp)VI3b0tq1` zNNWh86a0-3{~+R-u~;7=HHA6<LPBP=E+dL>2j-0AUcc{TB4mXLbmbj5xN`x>u_21= z$Qg%GE>GmJM^NjBqSvh=i-BQ+lhe_64t{(0U_2(1%9uZbz9iNXo*piTJ}}(QTTzpk zkm)F}Fkg*)pqYofGGu~FV^YHS<pfOAEl5|%9Akk!0|3(kuQHGZ9q3#nti~?-Ya|+= z*yRN(0+9y>7?40b817K)GIoUYz>%Z}hIl=AWGrPzDIcCfkOK<59Blek4s_SZ!FnTC z5+govv2fG5im?xbh0F5hhf*<$+5*PgzGzu#wQk~;FH^pqV%d&bq>yJFXJ$W=&%1IE zWE*_U8prAPl;Pzz0+d?{)y;X0D=Jzw3>2A8y}CPo*xGGjVyQ~Z<-l<B3sqTJYO-yN z{7~@sszf$bs$=8wqNY<nd>+2WeTfW={+vepL8xHT5Q2`YlFIOrgdilTUiSWWE<^~w zfrf|(p)n+>zJDvJCgMhWT>dDjC17;9L`q+>TGyGr6w?{X$twGVi!sBV)4;F-f|c;J z#6n7Ovh<#ow;9Ifd~ht)L&J<#(P}Lf@Lw2^gwlEh67{Hm;=C$8V<azl`tFcjXf4f( ze!4o1Zj0oX;ATjr(#ykVBM08#1GXrxh2a?1C~gNfZe~i06);&cs07hsgV0i2MT?2+ zSG4Q`ZROmFXpI1X8WF8>2rcu!L(5b$L8;6Bk7#v)|Cb9yv^dFFOE}^<GF$1j>^LYn zDJk2+5Jpl{t^M~rzdI-%ujikn+636cohrk3p%0@JBf(G{O9tCc9le#3jjR{^piFDY zJ3_<0I405Y0v{ji1A1(a!nfea@*I+m1tRR}Gw2GE--ml5Uh0I8L=jFd-B{!m1AHps zfsd3WFEs3i_>%x2qE7u72+27JlFzG<FpK{RiI4v(BnM%@XCfrQ&5$_7LE;ooaw!Us zTNHXFo3QC2S*Ne8th^q|5*YLp4Cs<UNlH_0Ps%{T;nbg%Wo3CCUz4Xa3GPo~ej-WP z7vB;O!kAx53#Ws_$23a|FMfSHb+r1YT-HuormvCoKp9H@uomA@#*134)VwK-;ckMB z3|tkF)GEq5!#6QXo7MBAeWH0EqWk@{*=g#u^O4V}E4GlCJwu_kuqB9y8+|1oSO!xD zO|89cs~N*sbR;e3K?KV#{NAE1c$)SZbR!?s%H8WP%v7kZq-4Y#EoOctb08WJ;ha}* z=gmLAO+9`0hXFHE)=#@b51%u{LpcKt_VUm{jIMCybhAe3aLiEukbyq+K>G-Ljp_UG znx2tQcD89s&Gjd<c?{VA>Exg%AQ@#48M6=>()e7CrG`WXEzvNpvJngeW>?sF1hJ6` zv5`e$LxSKL<sdr9jr|}x((rUd|A`LS_0yq6Ps!L7^TR>0o}be9?qwZ%tg1@{S`ydZ zhCnQ{b}pw;QetgwYdWW?Lmig4F}F~cFT*PZ^~bW|k%o}6Gww0dX!6W>%B+eHq9?DU zSek|}GRZ$B)IwH*s6UuZXqO3ye86YZykIu{5I#11Od-i^pk(%;S2MwpRIM=PWokK6 zE}SC1LS^JlO*@zOJSQIatfbe&jo(HE$I;JGDG88;X~bI?Hq4lO|BwiuhEv|_n&%o` z!FP}txJ?on?i<e(#=<voP^9}tX(CN6CFmPR-=sE!gb{pW{_5#rb0rZ5g<nVWRla0l zKt7SLEa>!Dwm{i;D=GWVgtBjT?~GP@N0<{K{T9ck-@ATEzm<8pxj9$U@AZ0`e8!!) zYz1w^#YplbDi}sqj>yuLwk7y()FKo0G;o<a>5Gou>$yy8-a|&k+ZvbPn`r!icqy~< za5#MDqheS4O|o}wU(fBhKZY-|(1B_8DMs$m+_CJ+&W=}MfqAK8?;GN}%0oURTg~6{ z&l^z@MG{qwWPUO<%>3!(OShWC@TIFGb^^iO&oruA`!yc_C_(C6PeyL-amKZ@Tocp- zM#|k&K$H(d$089zSr&gR*dLQnrYHHvRiL-PfJ7qDlg^NJbb?X^CsL|lv|=6O@WI<R zoR&~giN|AY{tMPxl-;XwN_m|JLy(UUrY8B&ib;sbgi|_Eyb+9Gm`XM~&6<|@1fCq8 z0>yIPgGR+;=q0jDw`G{SJZI-hnWRgGcX#PsvV<q7I61_A?sHe8_}Xf+FP}iz4!(p3 zhFqDvD3xqkR%_|4Hv24kEKn)`t#>tlATrB_#)2u{24A)+X~u8qr`TDgzCn?t{t8nu znljU>J5{F0@6?5$dAxME14I_8P{E}kWM%Nka*C3WrCTwNtHAog0BNFs?6ZgbV-vK4 zn@KzP645_yg7z@{Jz)>K<8d|q1=rs!<mUgq7P7+Q_;$5;TJA5sgzA*fEFCfXVB|tR z-ga~R$VUxT?z)wF39*J4Ge~7@1Et1P_|$k`MdAhNN-%gh3shLNY8)u&*XUDts1f)z z6n9sN3Nv;fd$3(o-7PPl-!U)a+jEWCjv$=l4w@tw;Fpk(1DQ&M&cF!76eJB?U>Z%V zZ$r`mTF6zRtYN?i@dVr_lyx)yP8yV|2ul42Y48DaQOxQISidyn;H6=a(TwwnxTudA zN|tv|ekEU8AnMs^vt6vlB7A@Xul(iEs7#WtpS@7Hiyz~il!+C{-|ldkxAX{<+&ul< zq)n3`QA&-kgmXqebv3>VCV(pi6q2J{DNoHPriDGiJoVV*axCO3v6l7eo!~){3xy6r zuq!?FaqnM5TnYD(o!9En#jCYDq}J}Z!jQ9AnjN>WGz-$h?P0<00u75r$fJWsxQN~? zECc^rY)5}14Fw=;bpoufz><EaW0T!)bod9Y(s5{gbkr28{U@dVUrI;81!N+9a0!NS zq+#d#F87d?s-aJCLXSyfg6WTG?Cuv*N4DOuU%(vBrb)aKQ5V&QLOS^|4S0B2-xAq* zO0!GNY>pZ1XcTU~OMVtsJ*1Ik+pMwu<|~bH-%4axO9J-9eBm_PNdKTqsJf?Z(mNO1 z%VY<rfHNiT{2(7n5Fh7P1KH+T5+6_?!#l}ULcn&&`4xqL0-3QLq!4x_h1f?llaN4^ zqvi;HatGc|3jgXS{nq%&^@g#3%ufcCvf?uAeJ(K_<A02AYLV;ns`cS5(Mwlclv~J4 z<-_0YSOqr&^%$KZ5Vjo<Y%Z(H%DWo>A!UW^<0@`H0l<Zbn=z!UzJIH%cn6vIpOn=a zEF$h&Em56cXRpGN3oHTqyap@;$*!}JVKlW|sYC^g7%a)9^Ws|Nz!*Y_VM<DtP1x^= z@&)sx(nC-bY5YN!e&;D)5NMICsr3swDw@6pDiAB$Gx3ByYNxn|pB;&h+1Anco=*XW zty*b7<Yery$j^7=MgUOOYj_g`jS~V*V|B0bfkuiLilMy*x=0r%`4u1e3IH^Sn3Y3& z&HV578t5ZUO?PyHPVx_X?Z4q9F`$zq_GM%>M1#pUS+kT;;wA0ybm~2U2y$R*UQG!^ zg&<IKtElk%{fY``B-fw<TFE&gD#7iLd5MM;>I})es1mHChWZOp&`eTx65PvkynDIu zC-<Vb&Lr)B#7xRyN<z0i{ywOFRB~6Zu+5_xZK&YJo3p%IUFawG@*Y+HAH*7lDmRi? zV*87e+`^hVt(#ywY``1lDX<0Gs1aI&LjGi>!m(dGh*fFm8{#_THki)YK<P#X6ifTl zgLK@7HtGE8$rdCd(E*)ou=lu@4-^cTU*V$%;^P9u$3+q!B1AJuBm^e@8i8<(Clezp zAJj6=v?V)qlzxw(9FCHb`Sl3|Lir(@MkreQir|*~6ZGpXdE5=>rsvII`r7Uqs!spT zM>m=q6ZDuIbqJe?Zx9HlEsHVGV;btcE)27LYg;l9jAe0LrgGIj+onWCnOqz*GqsyH zBR@21P_|%8pgdTdp4}~cBNxC4I9^$#VxQly{7a|UUUT1Le0r?{rq@YSZ8aekUrVQY zzZlo9G>B*R5p87p<T(+W`#vvM$UCZ@=Dnh0qz=P}zPc0LRi&&~8Pks956KN`X_!O! zB?ROpU$~q>K4YT8wbYqRv$-F}_agH`YfNj|Jo0`_-$Ck}-fl<_e0rA#7WQBs5OY^n z57L$gB<2V?x%pb+6kxy=B5_&JL9+b&oSZ!`*F6pNm4C>|fAf{=6|;ZPSLzWCNv-ME zHa3}K%3cdAo%)p&98C8bbjQ&3<@cx%KeV1o;X48pP)8sdNnTM4)u2;;y5JliMPkM7 zwPP$2Y$MrWz)N-y4G?Mv2<l`AYI(f<*(O4QnsL=wt_fSBFd&(T_9QesVhjzBB$0+k zUgL*Hpsr*bA)fo9j0xtl6K{g-e=$K?`fJRk);i<XKVvRc{g;Q*6mCvWpFe<Am!Bvr zCz;EGp*FNOq0hX7h-r03u-O+{(7)UB;WzlX>O>inQq#x1HKs;2rKT+Q6{b6k$-#Xr zTWp;TLX5^k43~u<mcv6V6i<Sff#fjPAbbV}$gX%yJIG_UK_0W6<T0~XJSJgBzk^x% z5bBIDP#UU!l?Kqgyj*oJYU_kpi|+y6z2tz!63(P%Dh~V7Q5u#CO`0MZo=DW<UeRUP z?xICH(M6bX80wj3{ucqLbiy0%1&0Z#lB$j$z^Ws!@=-14AzePo9Rkt5Xs<&YdnMue zy>wJ&ciCY03d+rhr>=*;fre((>uhhPt>M6;e8`u>ZHKt_Eyoofsorf)@i=Uy4jC70 z_)Tsp(`WPcrIngW;{@p-L|wYz-J+tIfy{p=j6Ved_)~yU#O*eqz_nOVO{ebD8)z5X zS791h>yUR+=8?u=<EVz%<RxTNvI;g%lXFOf=2(sCE5AVvr&evycODDL4*>bgfR4!M zs*Y?oCh-U92;O(Dq0bfuj1mvX{ccD{(*90IK<Bv*9SKAr20H$K=!h~3)R7;2`I7lo zX0P+f?36RK+*C!U$%+>9{e{x@?E;*Y9d*7_E0CxflQ0TU8yNjdf%r{yB<n8)VxQ(U z1>%(>vya$Ou3Z_TXl}itaO`arW)orN2ven*cA+?ga{!mXe+rZNV^{;Wl~I8yO%2is zO8hapRc&fy?UeV^y#g8kR1BBa9x|PJ?%Z_hwVgvEbr;KeGz6XU4k8#p&%bNfJs9NW z!tcC@y#0+A(15Pt<>>l&0WIjimY0R?rb`b+8lI7KyQYi3?&68Qs@j#pnFt{pYy23K zpyzVG#bdDIdQ6nSSe~0qJLY&t`XTu5q$JwDMF{j@M>I}1`QyG>eZa8IDNI{n9S1+8 z^_0u_4%pfH9uz2q0h0UOkAkG=L!>0F20O7J5-CuygIwquR_I|s(u$lw!OqwL@}UkS zAG&wNhZ59eE?k_TCdGI)IsB`dY+s`$>kV~+eE3MWRhILKxoGJ!V5hA0osrk99!S%l zKoy6_E8tuFN5K|997pFU)U^d_%@ODA5U0U;yY5XH_V^Y*1=!-J4OG;~@u(q=C=OjB zWJJ$qo)QMPVkCUlI@0*3zxOl)WK6)u6igFB(QQ?g#p_5YLaIzKrE6d$hXG*b3ypLd zL#piix2g=;(*LZ=zZuh{|8Zk_Gr;?(pHxXDY2OkhnCbT>XW<ez&ap-nYZPOO5(1(W zjRisYxFPs7S0lCr=-P?)6pGlOJ(c(NRao(-qX3{u1g{+O^yYu(>G6HeP8s>ff3B8i zfSz8Q=;<ZNg{&o5CFBz}g*S=QOVZPyT}G!I?n}7iH#pbsIuxq@oJk&Nq3m>p1%y|T zxlzWPredZb+rvz&N57r?D)>S2W!5%E)$g$aW?cqvUY9~cKDt;6jdsCW4A=*f<<j5w z2sVhGhz4q3+*i7NkMqD^reY_lvYCKvW3_S+7s3$E8b>6>{wpq^L0yXrSVLWhBdX6A zdL`QMP#LtS|A-^vl|%_KD+}=fy;>1G(#}*YzCNB{>GWuRsFLU?Tj#==xyAgS%%Xf$ zMJ&#`<oSirG_k2=$|OzcvbOV3Sa{ai)x@Knj*3I_HhQZ+z6`>yUm*4dH9KuXD8Mz4 zM*kLk$|m-tpOjKwb|ZAxL61tzE<lgEl5LMi{MtLy71}-=bN|G!!Q66XqR%~q!0D!8 zC~UqHamU`<>5SDYD#jKiHtuHvZrl#S7oQrTjrwIZT1ta|O5CVWw8UG~wT#5TfG@<I z`U4H+7U!Vc;ylTtDy=j;iIl*L2`2Rh-lV$!$)uk8mzdP$FGmAfd1Y!>Dy}nobAKkA zo-P_G3Lc9~m*%YrA!a3SCIzH9FMVXa<FwH9xKrtEPTokQPNU_qY2^@&#F8xUA{=5; z>(_=g&4XuHv7oQhsl`geB6FVAi4A3pg=h`A*&E2L{5YgLjvaS0bxKeU@SR9C015Pk z2rO8QG_uYl0-;C)c0bqhrvd{Ci2P+iH3rL0D7Ak?O6^mL4bU`O$DCIBcK`<=vuDR= z_C>#B_CDYQf#hmtzuwNA7M~|p3E!cnq7h^w8?dt{mKJuOTcnC5!wE1C!F1#VKSsx+ z-z$_Um#0`7L@ZK)BRv2#(nCq<NtkZ)X+XdC@Nb7&5?}^D$17W}9z#gLYwz@N_4e`} z7^n*izJ1^Rd^(AlmAT~+#&d97=Qw}(?-R6_1?Hy5b{9{xvE>axJ-b)q&UtfhC=FQv zJz7rz5OF66@e~Mg1-zS*8z3Rhv}#z_f-VLFQiz~WI^g|OCjy^hm?20hhAGLh5+nQ^ z%AJs8OyZLa_g|9?=QT;j?sfX9f7r5;@^9ieMlH`~D(r=Bb;LrxnXJ`8RmQ9Q>~&CG zHwLQfPLDY#PN%*Q!lY{M8oK6laNyeQ5K40ZIJVRJ6bLfGvdTdqLsbC<brQ%>{(+yU z{bgfE!vMJz&kE%q!H=Ph-9y^g=_{Vqo4B>fE)ceM8h&fH{<5_{|7u#-TNn5*nAQg2 z{V8F$qlXrWUUlE{=;Z?B;?1o&%fvPh-`Udy`%3#b><T~Y>9b*1`Oem_^sTQE5}l~u zd!?qa8i>3BH?O?AbBRdLMpj&*1q(KgRt{^l{}YBSk$YI=n^cwQOS+cci0RbGuz_oe z<KTo45b`~{3FI#mIwY@GbwzQJ#2=(9c+0x>h=88;HSvhtCyX_n{X1R3cT3lyE5Dl7 z_3O$%Yg$QnEH1AM_^*`GNQZ@3kq+S$J)XlWv%J^wBJy2ZscoIfrRjOXOjP9W^PVE3 zm+bN+N1gIso@~}=ok&AIdwvjW)Sob&`h4?rZ-VeN+w(|p>h@)jj|@mm-0#HfT%G?X z5CeMFwZxdNj~IO4^j}L1(Y3Pf8zoeJ`Wf}}h{lOgUvobbjb@u>Z*DU|!s|LuiE-N8 ziup_T`s6E4obs|f?(Xfagn@!|<pFR~w7iGqYn9Bd(9Zgn33fv`&|T><0uo^e5wWK3 zsSJt>G4mogEPS_gEfe7M?Rx5-;Ph?WicR>xU-$gSo$6&nu|-cOnCR&(Xz&gkGxv$l z)-iF-ZtMlqY??H~B0X<{#_WGEn1eS{n2l^f9JL`F-B;yU#f5|;B*z4&x)w+Z7~oEf zHK5lA<#_II<(SYxB^a(h$?<PqHTl2iRh_UCRc9-1k1!CEn~umUrueDTn@}}A4QXz8 z1zA4Khbz2s2OP+q*=eKz0>}jcxTcl5>pBU*)mEzF8mqeQR%*xp&Q>b%eihU2L%GrK zISc_n`<yy>T^Du}f@MuFRkh()SfE}i2^PN%^iqZXwY^mA;ZWP$aqp9McfLK<tNQkX zE~JPkWp`dWhA0h*ci4RW={7FYA25A^_uXV+ia&;fE8($!Tz|O>F^tX-2Sc%Ed291d zNtH)r(iuxbLt5m}kX9+v5|@WS{k|5BF8)}TV`Yg)^S$!kl{RbiBJz;cOFXzHaH_n> zqAyYr253s1z?b~~(q~n7CsDPg&r0HILw!~}S^r2?;lJ5u?e9cha0?47A6e$xHPqiA zK9u0~^_xaOS)@AG?w2;5gxRgT!Esi%O-rP|4oh4gv|)NDU&eLBVZn8@RU_m>!-vqx zou5!Q;J;qbZFhVze9hgq%=9+49O`2X&IuZ#kn$d-$m(Z$I7MwXT-UJ^pnF~NO40+F zI{_WCHGNi1Arf<|eO3~2pm|+)pEc!Q)@QY;{q%OJSb}Hzz13dcu;shnGB<8kPTV?B zJkmhCKj-3AUdMC%f@9BJYyYbzYNA*{yh7sV=V%dceKvbWBmF5VkUu{fVQD6{u{S^? zYf*J)z~ylcg*gSFmgrmz0&Wihz9#F?x<CT_mu@QwbCLCB9r!z-_--p0^8Y2>*7QJ! zoX0<PnpOs<vAlr?>RCSg#2k9A+mtxlQ;AbLHD{pl{etY*{0R>HJ^x+!VQHS@d7l*< zHEvkG(AY8k0Qsz;0NcUku1yPcBdx4Kga`2muWhz!FOU$15^Tu1x;T*l&f8G472MYU zPc&OYQW=FuYp3Edw~7@PF!w&WdcVVJF1&hi341l~uuHkrON6&OQck_wF1l`O`;3cC zLJ5X+Fo?Wh;|U$4##X0XzKl?X?q|7v&F<=D9k}VtY|l^nM}!+OaA6tzBzAEmzUXjm zP()x~Wg_Q@dtUYJK8=e{hcsqwE+Wg#>XC<=kCq<A-ygNth(vZSDB_;0f`bZHBU+RI zfZdr6&h5Z*prf;<3#$uW7g<}=Cv;&+ygIC}+ehfa{wJ0B)zGegn&%%iwAigNN}Si_ z;|CRdF{j6?9(Lw_B;1}G_9I@WlWDo*ntw6J;m&Q_fqLiEtU6+W4p;bk!Mkhx;2>A7 z+LfTYAEf^>dHS*HEHb#P5E;LyfO|fFbK2sr1SWO4b?Dl)r3x8~dmat>OZ1?b!hLj? z`#Wy*Jb&W`>cno88$u`c-^mTFdv!nj-X2WR2=_IGhNRMT>-RreCe0g2L%$U_j{k5( zJm{KPX5^cmvgMeju+QP*drMQ*zhrixc;*non;<~qf8pk;Q#P_`DhS)LY(LFr+%PQi zzPr@)&?oOa2Zho4Cp~TT4}4WXZr)qFd4b$WLFZ;oL)L(r#0?Y>i49p2IrG3q8nU3^ z{I74w?z_Fx*kL;O8hlX&^;zYU(B+U4{gu0<^anNBK(PMOcQxEW0_&H)D+#R)_Feyj zKL6%r|L6OzE5n+8@9R4&8#D)3LQ3;H?WZE(Oiip6el&e&r-oj8pT--JYe=#?iiTvs zY^1&g^eQD#e7Bv0iUC^q+C2UROMoMV<sLUbe|iglUnjfcPQFH7&fcuMy#wq$PYHUu zd3iWFg1`9rgYP90qXW)u1Dn_{4x4!L9^$AQ2^@}_jw>4r{r*l^Aya6deAy*f+S%>B zfxM})p&54-QklM61|1x{V0lo*>ctZI88>-DdI1`SXVkN7tl5W3?K;kg@@VjomoT$R z?4;glC<$lH39${hSKNC%D1?l)r?~j`%)w7DgJzHmBO#AY1uuD|70_RH`W{s+Y?@iI ztS`}ZrrynR&vK5(sVHv|SHE0W?veK>>6}_Rmv)!yVPDSWjdjrf@Jtqw;rO)gM}1ku zwF%qj9A6E%yvWi-f|JNH<;hZO({Ipyn0kJ0{tb70?0ujr<mW`?vHkOb%)x&3`}gaq z6&asrA)hGon##?}QIE8#JGHe!{|k42c7&3|Ng1KpU^@BeOznH3J?0n3HrW|yZR&D; zEt=%@`o8T1PrRI#Ku;W}g6&fH?&~PY`}KL(mPF3wOzTiNe>m=sxRJhlGTsm=&d-7j zrscX^KIdxp%F!32btv}^{rkC^PKj4LOfK(w7-V4S8gu>>HPfZGGUuCYR1B$By<1<h zve0gAS}LT@rcJdw`6{qmTSIIcJ+juCq5E+L{8=6K4I#sRa<?yHg`0*?=zlAu&zOn{ zujOgvpqME}^BFgNoo$ikUQ+KBc$Us^#Yyho!sc6}(i{gk9cd(4gRGfhrG=kk`l1W^ z?_10Bi6~<ZNa*#tWJ?Zt`S^tXc)}vwa6OW(H|F^piFRqJEDcORoY4n^+7p$Y_x!w0 zs&=tah+Qs?x0CV=R1!^?zi=&J#NpVEi_?gS;<pLn+1ed7Tsl1>R}P-|$!PHCqQsuJ zm(}*)&>yL|dmHAr7jb*B#_l#<*H<Qr`2*+f^V{vT>U@i#al5nq#emD+O-sU$XuEut z8)wVP%J!RjF?Jl5+FUQ*&2yStwB%@e&b)QZ-~_tp)YPR*3!%4KWp<O1r**TriOd?C zhj&Y&vjbIf!nDU^W<R)4XbLorvYedmU=n(xbjaoCH*y8;``p82HyXBF+4~e_GGFaB zbd!_Mg1+y3DShYo;OUe7${8(_WwhE=<%;H?b(;5Ayr7lI67J2-<}!W7V!eaxCiOs0 zcwG+p)C&Y#h`DRyqPQAc<vlxuvQF9c6kwG7b=tPG;psI+;a?RE?wH3E-e<`X_6Z`N zarMp3{-TyH5~$cZ#XEaC%9YOEh`Ie)ELW+##EZ_EiDFKMYwn#9hkPE$R*u};cWsdI z`n0<l5=ogq<vZ+s?90#2v->01_}(O*anO|28TPv%Y#X?%J1G0x7o&qZ6@^>E<o7PP z^)S>GHyBW9UcS~DSo)e<qPQ?D+~KeyA9l|*A56>Bay`^@|6JEHeI%7nfLOx(gNg4J zMz8tlO#I#KZF&9dX6KsR?w{GEv#%`t;Y9{Y`IoFlU!0fi%~Ncqo{?2(RBrYRo}=hF z#oE5hua8;ln>OvCPdD=BJ(U!ZoUf%i-#!qs>=L4wsBkX!iqoUE*%d4vtfS4wc*S<S zrFgl7@$k+-x@M`H?uZ|}PwUP^B9A=kvrta7)1NQ@9`EON?>qL0h1DbZ#X~rh3N!Km z%uDtp(|N2;!l!GlT9w}Ex%S#JKOKxXgSVkalvvGQT0S^da{bCf3YIpX5|xqeuj&r$ z>LIBLZ<*Chzj(bvfdj@P@cjnjrLXMw4$gSGM!AFvTr4x?iF{Rd{2;|Qil`xBjQrJ4 zA*b_W`w}0V2|qpeZWH}EJ9U2Uoyn)HQ_pUh*OEVzoWVpMu|L#w`R9~}1fZprE0(X6 za;EDPy7ltb(`^1b%T)YNo}D^A*>uR@gxe7r*9u<Ns_T!^r8%xxqGGT5lnkbHXy4Oc zG??F=cTMuKH}$z2CE_k8PRp|kZw=fOUn#|7a=Ah;K&0uOxN<s$L93dbEC!b|Lcd!p zWzs*Q(OucH*L^_3eSnjRDJ5iE+r*r}hc-FsFIuKg_=5Ap6eqVNFmfkmeP2o|^RB*q z7rR(|$}8AKD9CEYD*oCB*`X|t+aHY8b7RJxj*niI{2V}efi}^%bW(QUK&38)l(JLV zn0x+3wFdeOZQf}uxg!!gy8DoJ9w8~Wl(!Z3hlNfKbEkG=d4E(4?%Vn7MKt3cE`P}; zk$?v>{G7-ilKW&$L(YF#P|0z>_-)&1MALWIL0=fvqwm#n&dnU{&$(e?E$ALz-M1&s zZFzGN$1NyPaqa5h=+g+~zNC)|4WcJxAGZAn`r_iSXtE90#B*A98`j&LGswG>)<kc1 zAW!ycsite|$Dj}5u55;uNx-BTQ`b`^_pE}TsDevnVs`2x<{`mz*>$#CM7d3mHnVva z+)*mGtl9sZzC}ObC7(^=eB!oQ^lnAOM`P4yMP4h0C?Tg>C%;X{hH46Zqb`2AEoNY2 zz*bJVwURNji9Vj?aX{zWed#C7Z60W5am0`>25|GSymRGCPfnHJ{3RK;e=qpc`3VP) zJv?77o4~&m)g^A1<L^ALB5>(){L2x2EBbu6K5kj;+=-_SNv1p{{AK5EP4R@3Bpls5 zRGwuwFO^~c=vZ%2dux7x-&9UOm3{57nUlHmsmEy<&#^2yWVE7u@B6wr&5OUaA=>7! zlTBo_wgJlQr<J14utvYz5+s^^hb!9xw{`MxSN}tH9aYN6+jn!%?YKD*8JKd)`l-FK z^JWHXg|4Aks}JWRe~ONf9l+5_7#K>8=sw=X)KuMfXjt^|{r9o_apK#nskWE5%6Dz? zjFmXqT|VqFxbxT{DHo)AR-bO?cwD`x2DYNC0?iDM{VG0QxzDU!eSy2vEr2X}{PN>t zasiY4S}1MT&DW!j(CS(C)|fmHJ#zv*Rq3T}k^8~0^#-S2?jtY|f8WXwNWG{$Rcu?B z`KC)<P4;-yctS*?yjs2Tm9F=x?wFRc**FK0eb;B>Qrm4cRN6k$;qC=m7-v{6Q)!uI zJ)bw)6nuGN>$7>OoOiQF`R-AW=N?wIn3Txb5pl|h@u^Bp?N#I#pM<*+i`?Dk>*w~K zrE7n_sPrW!duGY6AbZAuN<WO-Z64-yf{Qk+*JyA*AU2#3h>rX8#%h5hOoZc6+5UyQ zyGqQ|_yR;eH}ZWbsaY&~yW2cXFaF5ZRudz!ACkG5n4#gXfef6w4=j_ldS4$3D)-ZM zU=<PCanYA-@vsA#GB>=<{gJ-wT}AH`yFK&`Jz9?2^C(;&qd%-{L|Y5Xcji~MO5=TE z@ho~Kae_6dle3?JBiQBJxopW=XY#8$0zz=lG2Ud)H*Z_cB#X14wmZ$|D9i_D7oVOZ zlNnL<zVG+uXY4jEO5K?-Q>)K`u~G%8H+GoNSyVq<Vz^hb-PiGgVYSX8>mA*e0IU9M zESX(zc4hXkOL1&dxSWwUu+%qzwKzFF99D5%_$$9k7SHf<-@uX*nZE4VycaF%&rDm@ zXJXZ<ccyliZ7X_%F<m0(n1$Q6!gGS^MkWNDaE(l|{$hQVp><iQog<~}l?Mj+Mw%0j z-KH_;xn*;+qfD}aoZV(mZ-Miy(kGyDZYt)d`>vRMqk1l!KkE)e$P_d?_*>^o=SUq= z$~#Z9<)?$TUEc#HVbzm2s6Q<2e`&S1#&Pq>%;p;*U+S`QcAa}QRsF*<s&BOKi{)uy zi|^L-bO(44ADKo&X2_Uw!#MpWWlHu<u-z26u%BK>;QbGVrAQsF!bd;Ndc@}IyW9@? z?lZFf(f3K_Wm70Rn3690LRzDQr~e0;?@`<Pe=b+D$3}}5q2JxScP2L11U39UjHM;a z-tSly*+aFsf|1zkgS9zhat_?0E@cX188X2qymmQLv>KeJ?k(M8#Y4k7-19xF`o7y! zGhLKyaJyEf50`$|c$|h!uZioCf<VKeFu-}{2H5Ba-x3OD+%!s1#tprJ6nsx8lyU#@ z4W!@_dC={w^M#?{%5}a?6I{987e0bZ*ZIalaOL{nng=dk_uJsWwd;K=8Mt)4@5=(0 z>Ohuz9q)7k*RKEVMd0G~zq|)ry#CkPfQvWq+7)p1`rr8hF5b|qE5P*|c_9P1d;@O< z09S9|(mJ?$BUh@y<r}(646fhEEn0B-My{8F%m31r`_uJDaQ#Lu-GR#;piRD}mGS3` zW8f1Ty9Wh6u%U}L;Q9?+2m#k`?5+a%z+cKke;&&RpV-hOI=FsA6WZYVjSUck4{T^) z6<oj3aZB)#4Gs^2Pi$;l4SZl@V^rV+8yxompV;VN3;4)JMmfOc8yRr`m;dEF|EbLm zuHQ&=7hJx<)+G4E##(LQ0~>1L{N4ILwH3hi8!L5#5B%jk|GC@?rcJu|s0Yxl=3CHv U<-rQ)pYtuS6l#+hv?C4pKY<kA;Q#;t diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default_CRreal.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default_CRreal.root deleted file mode 100644 index 5956a4bcfe93baccee5f9b13370b1cdbbb15c913..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66481 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 F{{v&>P%;1j diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default_TPNoCorr.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_el_Default_TPNoCorr.root deleted file mode 100644 index fbb0666ccab0d1575911f0d96f5ecb28c63fe07b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24246 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_mu_Default.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p1/Standard/R_mu_Default.root deleted file mode 100644 index 6293996d65b9c69138439f10b1b474934d008340..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67144 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/F_el_2015Test.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/F_el_2015Test.root deleted file mode 100644 index 164ccf1d6e63b8abc81a7c7b051f34a33ea145b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11087 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/F_mu_2015Test.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/F_mu_2015Test.root deleted file mode 100644 index b25724ea4275f9aaf90c9ac7a916acfd068ec7be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11085 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/R_el_2015Test.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/R_el_2015Test.root deleted file mode 100644 index 55401f2409f20cc8aac184cf6d9db3dcb8f1b8d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12737 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 R|1Wa^U|vDA)<q&5^gnP(u#o@& diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/R_mu_2015Test.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2015/R_mu_2015Test.root deleted file mode 100644 index 3c023c3d648e9e6f2772471069b775c0fc030c64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12727 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/F_el_2016Test.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/F_el_2016Test.root deleted file mode 100644 index f3f764b0fc7282c2b7f18aa1a538b3d039a1ff8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11092 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/F_mu_2016Test.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/F_mu_2016Test.root deleted file mode 100644 index 326ae1414b3df298631d6eeefe926d6c163462c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11103 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/R_el_2016Test.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/R_el_2016Test.root deleted file mode 100644 index 189d69454d21fc9d32919add4e4f10d27448b03e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12747 zcmd6u2{=@J|NqYzOO}MJS&|~zW-Q6RR46-<CCd!Pl6~LP*s_&<i;{%0Wmncgmh2?i zl|nQqLZ#t<W|X`8dG70fKX=#fx}L|?T+OMDGtTGzd4Jxo@A>BD?Cb#mSOEO80s!G| z@Wl<j&jVi&@E0@j-kW0x0HEvzAXL6|ql{l^7gCvWmu_BfTm}F3Kly^_0r+q9#0bh8 z4`kxMGyZA-K%%E?=YaBq**ZI-U`|MP3#2Vf1L@&r=c9r0uywXF_jY!(N4lYqfBI8( zl#7S6lajTyouwVh34FQ3+%4VgTs+)i)<}DllDmhUBhtgp*$Jj+XJhLD(?ua2z<+J7 zhjIrG%ux=6cS3IXAN{|1ZGZ%SKfu>A06@Rs@Al980sw-7e|NKqPUG(>RDy6%MF`b; zf<K>F?}G4oauoRUx_FoiUp-)JuHoPSzBg7s@C^b;Kmi|!I|3n&M7SXkQf-(O42H8G zb0Aa!(}Q`|oPIln(OjF(Ijt?8b~PgrY6VSpfy0HB&`FRn2P$=iTo_tFh?A1ndIkd! z$xu^K<ugm5A5gU@kW!CCJ&WqG=*t`qPWUcEQfkLXB|t?Lvx_OHEMhWWD4&ZRto-Wt z@Te7C#KELNqT8Kw2=WtX%&{VfI+Wb$NgDh4&SqM!h1W!Lb&6l_YB!!qS|!VcW_uja z<3Ng^2UMltaQcwI<I%Gjs&URwOkNC$B#K^IPvA#)MQl(@#3<%X1Of4*Xejg?&!{o- zgguL4p~8p=!2Red3!KATqQJAwPz~n0bT7%iO!*V4t|7C9zB<={nQh6!Y;H6<Qev`k z@T1tJfFX3GFoLPoR%~G%^TjJRrCzxBONpI#`mQNstDkaRw5Wq-t;&%JQ}ve!Nsjg5 zmD_da6Q_jq>-@7W!)I!Jdsp6Q<vTZRJYD9%QCus8kG)!PS4o|eQil0^O>J*$DVbH7 z`=K(_)wMV~*Mq5wFxn6z>omtsu}Shx=aJpR(}EiVJH6Ot_1J`G%QN){N1bqU`M8W1 zH-v;T$E<cQ4+}@GtLEY+#=N8RgiA_;m{wfBtl3a*dy6z9`OjKUG-a%LwyU&W-S)m8 zT#+}nIo>qoCG9=2ECWd8SCj$(5up*G(x7Nk05QC1prH7Eh=u|$8k7eTR1Nu_YQO_f zHcUi-^iSE?5M<Mhm(9J-ec2>~vdJ<|U<P%QPSDLPz~D;I4LuP-H*No>8x~ME0xcJQ z>Zas}ZX#TN>Za>obVE<j&5`FM&k(OM0T1Ps-+n-H-eBc>hG=r<InYxc<UmEb3CsSj zWrslQZg>_>-ol*OlqXV*;oO#2ptKNcl!Qm<$$FTdoW&5&9q$QeIarp6&SsAG=4+mI z)llnJ?^EwpEAc=eI7g&kBS_O7cOeeY%Pna1vBM6<a9v)J(#z-~6rig6QUr0n(dCP; zq3qj%wxiUl?FOg)7cwihCSBjY(b?f6+o%mXO2uc$re67>H{aPT2w_1r+6+I^yCJjb zTi56G<f(tiRBXPM&y3ResOge#jckx&*;M!2trKI#lgk_tUh<odB(H9n&DdMGKBM=~ ze`;YA;Hc{5%#meahBdI?!aaHa>i#)KuT|OTV5(}lic~+3fR>IqS_S!YK-{rT3<VVf zCnEenc7n{Nvy(DK`({sdkiE}q?9hDbrgH`L^Q%RU6+shBUFM$#J9Zp*Qi?Rfw6HUm zQ-vjV4H3KZ`tw7au??HfE2T0YQnsCTt&N<UK1KI$I#YZ3Iz{-RcIP{uyVvl1YMrG7 zcxI<|LED<Z8xhecsHxik!H7r|_ccW@A}ifLjL1qCRMb5PFiNy%M71rLcNom@Ul~yr z9sPf1L~NiD75=snSqI_u;}!?3ab9QVvEChJrox(^9Ucw3&Re<*$!6!IhbEXkJYdqu zj5Ri*e|0(7q<ijmN=kZW`t4K`a<Op3h2T~iD~X;{G|}1@$w<T1ORHKgjQlDWnFbfD zrfG(z-oWIL_hQ*EJlV!KyQZoQgj}s8cs&Z*)1RJ{PJ8m${F|bE7v6tTTWs}gpqBvp z(df*=3p-`T&3CgCKA<-b9jh~!S8|VKZ6BQy%z$@0_o>!(-&KZHmuZwwyoPDJ&y9Me z$;B-YvlyZqNr|kV@X|q%Z6C;V2G104PBfj0zdL&O6X-9+2ZL{z>MhT>c~s}wIaLSo zuj!SXTnBB1zMcI{?6t6T2ypdiTnt#+K|*PtgQd*^B=B}|fNj6DRCv3%it-?g8OlAw zARK}Pj)MTte-v1%i%{Smf@O5=TSg+@GLnsT3B%?N!8G0wF}UrS29#hL2Y)pUPH3u# z3(-a2&@w8vB8EtY^fnpEM<m=|eJK#@XjMICLuO{?T{Od0BUob}s{3e;-TH>Md?%cS zl{cpigTX8jrcL%Ve%gpXNjrJI^VoYJ?F|k2+)2f+2V`l;c^5GlZ7Q#a0#WDq6{+Xk z_8ozk@AydiYX#zTr(MW-3o=k@=?MF<_#zadn8>IbNP19!!tnaN;Vm7~{<xC9OMRBT z<K%Xc844!Se+4=J07b1q*(5b-N9p#(+f;Y@!(u)3uq8$)e9*Sf=EkSx5tQlEM|lR0 z-d`ub&oW&+vuws<X1u}G*SxY0RbI}|o!l(4VO+UVuE~<e@$Qr&>E(OQ=<6&(QO~Zk zI__S^-E(k^tiw$N>#yh5ESCpKpZm<FGAO!TQxj}3*A!V9WOL{4kpLr_JSKqCH1rnO zrQU?l5DpgfJ|K=SDES}$Pl+$6mA0)N*sT<M^~4{6<&+=-!hcKvCky-putp%f5eRK- z1o2r;@L=|}riNOy7I|l9%$c6qu86JP=aBX5T@uV`Y4;UW(GKFIJona86&RV~Na!n^ z5dh>G*e55cG8J^Gk-ShcdnF4cYhiEAtBMz|-6iVuxJSW2%1BDu9)$2T9*KVJKDO3j zJ02iAd`N`y8EKcTFdY7oNSIl|g>Q%2bubxl`*QCr)uyyfFh*cIQTtoDF!Sh4=-N>Q zz44~&Lr3p@X5z&`Rd>+?)HG4ekoV#=3gw5n0B&|>=BVbKB&AO_+?`n_C3be{&(k0I zK2KIaJ@Y%v2IYLQoUKV*Hu%?xA{<N<6Q?EG86JBMyw@##Z6o3E_-jk;Hwy2_5bO8t z<c9+KCDN?*M&zX9{qX)@4Eq0@@9@T{)mY)&rX$tBVh&R!)BG5YcK)Lz7sJ)9j`scw z9ZLyQt1n;7I~OjL`nR(rmKCF0SM1!KdhJJWURq|}#Bx%#%`1_Up_#C?8(0qa9>0ak zsh$;D%PV(r4_<mPF>5RtrozglMQ|^l=3?)O5kWw);zPy&5fQ?#gV-g1tjYgb#ntY3 z+0E7Isk<LXKS$&0oR4gC2$PI9ZO^uRboH;t)oJBsn)T05G;L$==gH6X>`dWix${^9 zurte6{wqR-7P}=aTD~iCC%3&-6-ffNTd*^IS;>KBlOsF5@6>Y_J{4>}wl=+z%`I_s zo*2+eeklg}NG!oe(4g${_I!j2pa1u=D#1sbEIg1lpzeP72;mSEo+bo9|L~Cl6kd1~ z)&$|9_Jwy56kfj?-$nIUP<efL<)K~B6p{qxMeQjs{8!~Mg32=^)#N-C3r|6ZRB@GY zRivFfS#|G(ycWbkPCJqUN(qI&l`lOj_@V99Q-`mXVvda*OJpph7En|rGqb{F#p}=* zh?@XCI3M6_2qIfC?RsV`rx87welXj!Uj~Doa*;a*O;S!`eLCVMH5)UtNb?BAaieaG zF-ds}g!iI;_x0vaE%CdsR<=8(cQ%7$NgnUMcP{t$yq2O0-4fnznl>LQir$ihlYDln zstEMoml1{;4b(9lsWF=oOD*+Z?7rmpkc*y&+O3`w%0FPB0K}3!5r~7FY1t{R=wG@2 z)@0KeR}%P$a+mxPF)$#Hngd;cj^F~v!EzMrrND#h`{f{{Kt~jw9e$)h@Bl2uO9*iM zhX<q(QsDSsroaqiJU#peDR2@L=Z)V^f#hHc99RWV5Wz4aGKK@K&BUq`igrxA%VfF7 zvpt3&@YZ98yHwK1X|E@M*J(4X*CF2ww>LJncC)@}=EkkfQZ@~c!8$#*4{_2-yC4vq z#8>!Z=>4dQ^f~QWt|#bKQ8A-oY}ViFQSL^HU5bk9twM^|Shu+!%ddS2wD3&B3?J{5 zL?+~frf!?&BWm_NeIfkQa$oVpQ%C1+rMh$F)=NW9-q>4BL8ZsecMq&|WryPGh9s~n zeBwd!o35!-kHez%t6=jJ(xv?q>&vq|+g{t#4(Y?|o9+hY0n^^<<klRWF9<CR?2U7$ zDqNi%1A~e<`9xELTaTV?Ljf*h%luVUo=|0wB|W>@=I40ahk>K_t=B2A=H0SoG`4|G zyW`7t`q_1PxQyXl7E}Aj<4yie_WiJ_oA3&V^79-Tut7Zu4T=C2QL>leXh`-ILCA1O zuRk&z0Vbs&0OCh$MiF4L+ydX4aW?y{sg9os0?}Y!cH;Xo62=SRdxJn&L=l~WmX9%~ zT~{?HGBQzM)b43SLx|HrL%vN2aTn+Xh=-pW#~a2Q^`s{nYbRvo#~G3)86Xiz1mZi{ z<y=(57pYXipqRYgSLbk?i3$$)Vi>jMb3(W~=}Ad%l#;>^o=7W=Xnu#O1aVM!l%brr z<RS6X;O^6cf})b5r(sX&9>&<(V0vnH0ZZhN!ur2=CK}f=*x4^rtn1x`yV9LMlXhBU zIpv1KOPs84dPwTwZij07Yt-HOWW4?lJ=oKjp<aS9%I;F4F^66@4PRSKb`%koMRTf9 zij)!sLWy1U;V*fE;U`D;VeCW+(h_V#NkSV+fj7NkuMKJa_HR027=zKu1|{+*hW`!$ zq<+GfB>~1-{{_bG>@j@S-K$AIDE=Mf?`Ui<Jnz%ke~IFg{*L0K*eT}&1>8pzPkqFs zo{BuZS<A3KFaJX3jduR7-|3p7($?jT=ZvQ!50de;UpJ-78O-d5zMa4sZ%a7ZC_kE# zPI>&4I)M^9EmM{zw>3dmS0i!=R-C$7y=~a|>eF*C`#NW-Z;7x8_*h_;q}rRHPo{OS z`I3w?jWJc*XI@_T-V_!hYr}8<NOg^3`?=;(ekW8tiLY54nt_>50Yg=BFg;wlc}L@B zpwDre99%|y$AWzpt|rL+Gc~`~+f&<TJ{)q4k~r$HJ3lSc*ZE3id1iz(Ny<^qc31P1 zegE_1OV}AXd424wfUX_W`Ruu;`CH>nfp>(;XR14PiW_$4U_r}}FSJj?K;h^Ugd+<I zr*$vI9j@3H4q=?)DITw!KXE)G5g_|RI@MML>GTt%)AQ$04stv}J3l;}D0z?MllDk{ z?$=OGSOMDeaP9w5lE419B=1w6{idLGu!35(nyG+Ez!a6mxm4Y(c>R@P1FoZHM}(E^ z@bOb`qig2b@Qn@!8(lUwP|6(Z20P8|k2aE<IpIVy(eVD-VY_w5eA(mX?H(JChP=#$ zy8Ev5I9m6&oLRKr$tv7L$~PVP;?PxYQ&8voU|Xe7cIJjc&CpwhO@YD^wwW(gt<&0) z^CMkB3vV_7S=djGkLD8g!Ok!q-7xB@8QF1sFjB17p|D+(9I4Ua?}nXmiitV&z0Yp9 zTBvdBbAtS)vrQ5&N5f(J-T7*rrO*i-kmFq*r`#GU3vz!qBXWwAXZsA(P&75lf3)dq zt!i%R7tS7PVB+#HD>wqC2_s+}6xH)RH)1@nFRDE>(EZho2q2#g0mgrVd^>^j{>qI& zkpEBJ=ogg#4LABfK>2gDe~a>2lVYuXoB1K{OK@a!0a&d5sF9p)S(cl&A!E`r-tk#P zLN11VzHu4zjJZ?|DOON{J_S%<!*nef`wQwE`bT}Zf<Clx)CHZ*>WebWn~?3AG%@Zp zwD#VO!|X&cZ7&P;ZT5N(bl+Hn`f7sa^4=a?&jEEnbGd%!>41u0LHkZ`(S(g?5z|Cd zGR-6-N4nMS$ahz>5ia)a8gk!P#49hyo9^(gqgpyH!9@WJ``B`@x-SXU?FOsc4@lv` zk7<6ty3~J=Jl-_^h2;|<K=)6U?<3T>i(ngl`?is~&+>#a@6kLhz&E!y?8ykj-q`Gy zVXvSpgnCV!uy!DXMZ%Duj$b6&*G-pFb#0v<BMu}#gqOnM@Es`saJgB)o$eHQ<rniG zvaiJ<ImNY=qtR&e%VxR@MCfx3&@@sy2Nz+jh`4hD_{c}sr4_tJ>&Ho_J%k3=_ORMU z^fxXCvvvJBmWwtw9}t<^fkr(0>sYSyxkbleO0=K7`vH4sdF<{@b)0qowv<p<NcPL@ zM?66-DPaQCyWbi&G_cR*;liX?3+9{i0ba~AD??d{a>bEB%PSiGWv4}wn^*K3n_9C4 z+q|497vv0taLBEv!fxxj{5olVaruN*8j>Het`c`;C4_~cW_rA7qqyj>Z;S12wa4s6 zN8c)TM#$%Lw#V^U+=TbxqAb0v&_xp9QCLI~I0t+Pb07jN>hK;`vDEDs_253u<7@h7 zo<BnbMEvA=LUywzWH;?Uuu9`6&ueL&?)pje|39w!h3EzTjpzgZ2Z)~RZ;77b8vmgk zLE5EzI*)q?ySN=zOO@U(4VIWv-zG<fT}D%~sb68^5brm+wvS>U(Koy{uXvv^$hH~$ z%K0M+Q}P658L1Vwgz-2fhxCB^u`|tPA3wNGh21~7yyM|%y@ZV~-)<eP^7d*Gt(!^S zl3HE#9K%JG)ZXrZS!^X<>J>qb=+vz$O|4SDSDujlY9$yjCjVlk8unQGey4C+;5`Le zD+Eb6BMrP&DW3U2enTBbYIh-=XxrO>gQ9rNl>9;RSh}G1SW}&hzp<}QF0Rg!#4VDd zdwE8-%g~tt*SRy5a<;htE+uwG<Kft~F&r9KcVcI8JPf(%yj!LJ{enno&;;#0*{#N6 zT!wyDTUL90X;5*3<9*k|Ne`L<pkHV3A!sI91TzT%bvLnRCTybnx+9p$9?t(_CO?7R z1OkNo1bPBRQlJPx{|7aw?E^hQdV5HJ07%|j8cf<-8Wj9Bg$RIz*MMJ4;y}WGN>A&@ zV$vw-J-VNZNn!u8m_)U=m~_1;7$9SYzB2)rdjX^bhIqjCo{#XTVmU8$0kLGnpQyob z;d%(A6=ly=8di1*INU0@m_fNb1zkm9B?#3{C`f^XybU|<-&e(Ys{};)))nj<-v#8> zscS8YZJ%kjn`lMPC9Jkf!<9-mrfratc<;CjdWQ=lM&bIDqByLg5^=chkXJ|H+4=g4 z#~O~2l%sbJ`~vn790$ljuy=HE^RB-hgPV9baHg&=X}qbSz*k4?3L7vheYFR)1xA7` zaD(M}vlkE9hxW@uh=+K*|0N#o0sbop!2QD%E)(M6_+Q3D5b*!gc=!wA|3*CgKS6x> z-yuGuRS*_A={BX<+<RKgiQzGhC~RxWE?Jct_h`0;2bYHBU18X`8Mqz(C&V{XDXo8B zENSiiL2xy(JX+st>%Li!S>y2J%GeGp*QQTzqQQ@6h$*MO@9tFHddF7n#Aai5Ky=<t zba|G`o4npP52&~APB{3dYF;4`J@n2FT-Zg}0uWIX`bbF4_>QUH*-QNE;@dS@Y=u4D zC$KZ5^5$!0UmxHya*k~!*4!-%%E?_3+j@O;`<3bLSCgED(I&H@A=mHg7TYz}A8N30 z35#8Eo%Ui6PwE~ApiVF^8*Ey_upqJkRk5&_?~cCTR|O&8fryV6#jj6{r6GXDPsk_G zW;v43u2%byPgwXBh$i&vADBP8H~EPPlRxTz8S{14Y|4h$zLIP@Z#>a;-f)><zp&Gj z;J29_lIrW=bLk!TjkyN@)t=O`0KDs0f$O-7J#aboCY)7%EJKaRbTFGBnAJZYq`~Mn z>*XA1$wcgqOz*CxHf;j#XsZ&!wh8d@*l~OCzApm`_~eD(OaWMt=&9Sedr)2S0Jk?d zqTDVzSv%96clNY!@a1%{bFxQSfxo%q7v4fC0sG_N!?KsgGtO)V400U)%kAP`cO>M; zbwxhg%$~Tp9D0^+{1$u1RnD7g4UU-)G(_v9Ewx0XE&F@gy{^1hmC=3#qmR=*pVcLQ z-6xywfa3KvfG&dUL1Pjb$G2d;X&*(t8Of~`AM3hm@2TKtRn{v#*gM-(>v!DyWw&Ak z{aoTHhLw0pv$Vqnmi)FXlV$_xB)win_K`VV@cBl)Tppo3Xkzxh{b`L4tsvj$nykR( zLZ2GSVzWf=1=TZo_dCrNww$zUu7zx?EY2q?>2)`&Pn5N4nddoWX618a9=+Hc@$hkk z*&R2L;1sj504Jvs+we7FdCj+-$*a>_g_dJvvM(;JFMI?nADkegl59Z4XPcjZE-(>) z%NFoxMoFsB-(J+u<osmP9~ogw(E(x0NRi{A0~iN4q&)8^HYkwx^^@O9Z(H<?Hk*|W zIl}vfbqRo;^^i3^SsOJ@=eev=ccb<QRRYhA4bMZjcWE{b3<vWVOFul=SQgQkcwFrX ztOOQa5Fj#uVUWC)uW-JyJ5cW9<*R*P)1k&mw<i}KZL=9~z8<Zl8VMe~LX{b{ND`@} zSDaWDI(`hgkV>+p%~<nV)Bj?9%{y+M;kO1o5@m_T4kh6_VG-f3m4`Z8nyxU3ES@|& zze7*SQ(yR{k{xFHaW-`4OYwS>@~aj`GvLl=KhZlag4bLIUsEsH58rgxvGS2vPK}^Y zT5;b}H{}2NA#auB%(13^xM0*)-OP8H?I*}N5{_<v&(mMbyIyZS;AE~RI)?Lu+;q+n zKJ>k~m$WgQ)O!G7L|T%xGgqk<yujNh&2MvVrh{#x<+a@8%glS&QSKSx?nQU^tKS5S zgYJKykY6|3M4qG1-q7;o?pjq!>d!Bw$t6!Yf-}qtQ-`)4L^qbY+KuN*L}J}6QeIc} zlsk90dSP#VPz%~^ow#XV!Ybl<PS#YupfK`VVEp3UB6TCfp*t9p+LVtJS|cBNRf!I@ zyx=-AS+;XhbGVS-#ySy#DYWRkap~9raUM-~bD-ZYyd+%!RSYy~y|I1e9_}{}OF+_& z5qWVP5?^hYO;ap3cH;_n56GuD!`|v?6>}&~{bh>gJ=VVP{Qj`o@~13={o%)z$PQ*{ z4ku5B>`+C&->JQ=;Gf}nPWN7wXC<P)o{N1&?M5v1DxW6za}t=#d$PcVzPBXM<-QzQ zd;fx`DvW3qAJd8iQ!S1QbxIl6Qny2=!gb_jB6&IA>30v16^!K4z`|&^C&h*56Fp~i zn1#*nzv^dun_zG;g}$B7ygC+AUQ0c~u)Tc-88osU`0Wd>Y}K`faZtrGxBpPan9b9H zW0JRVshyZ9?y~19>sa@!mYvdQ{ujy$ZSAAk6ywBn3|7~rhN14Ctxa7&JHC0Zz(++@ zk|p?=MY=Zf;lf9p^G--;Zb`RKh~sD0UV+mNpTn&moeyuLy?m%o<;AT?+X4Ls3az@A zRb1qkYG#YF$wh^Va-58G?Tc+I9Zqar;1@e)ubt!BnWUsQBw^5rxntbsPW$$HN>sy; z0+jR>aZ`k)8kwF8ZorypcmrX&_*QPPV?~c9ZsJmapGEl2*W_<x@B2z4cJvK4zv)!) zgi4Bi#Osv;c`BR#e&lhxRO0>!q18JQ;&1hPxu3DVv9L0zF?xNsc5@~6leO^?N|UUY z$`4)`B+0h)OzD=rC~+BhTWO+dpc&{P64tB)eMBj9@S{nX4f_{upCcE;h_nRg7m*fv z&?coz%vcQUww;Cit;YABVoyT+^lb|$G_>+$b!!({_$?G$*H+u|Se5e}*UlOYO4F^= z%&?#44wjEe?VIgnXh5lE<*pez!c&EqTER>#-AtXMr)DggZ;+(L$)ZqeWYChLG}_ID zHN0%7XmLio>*QQ>b@&URN^Z7Hw96H`CnV_ZHYygF=zW{s5!-Qws`LIDT0@~!(Y!Qb z>U`g`F=7w<8w|Yy<mJj~#gpne<-~;DzdStEly-y1hB`y#uDqOgcO+cUU`+h$OTm+H z6&gmJ%n8ZfN5y=1&AFjARjs{YI}Izr4fAcsDR~U6+akN;Ycf0CJ`vO6SUU1@wKH4P z7<Ha%wyxfrCYmqDnCv*Wn$V{4XHm@S7e7m*>U@y*_OKE6X59-fv4z^QM413vi-3Rt zfuxL95kWOCtCUpi0W>Giqg8?MB1NyrSw@{2fyLn9G>z&^ek;Q?A&YZ1<sa*q&A1Y8 z(AS3YWF34`*!-CM$!(#h2i^*8nOuLg`s_H<86xwIP#V1@sQ!nc!tcdOl@H_1c%a^0 zhu(RObgDnAT3WIdR(F`me5^la`dDguR<|Y83t+H+m_ammAm?O7%;u?w&qE}Od~(A- zk{eGR6R76D---3&URV^vj!&}{(YZQgi?WmrQy3~))$@pOba(lrCb&Af1*uhPelm89 zZD054M+jZEf9db(I9-mref*Nu*rCKwQ3U&=GWH8F?YM%S;kb!%sn=#yIZFbYb4anS z)aum+3wMzgk2$0bSL0wykQPbii_oJYE@t#?*G_4D9)n+KG4{|VIepRga=p)3%`4g$ zU58xG*05!r>`j!Y9s>#ia_yR>%9>CqPUr$R<eCiS<Od7g5>2_dcHOiR86)Gq49&PV zp(pIpJ<mRktL?vY#rl?tcyPNmM`_F@iRyS^jo8Mi;8mM*MY*GH3h$j0(CY;eav2N_ zGk1zf65OMXN^d^6)=IpddD@bCvb}%)7}Hn97u0;#f?izIJ$GB0r|n-1@qc|HOle0Z zTL?=;*ZHzsaKdr8<lC2gIM4R^(2~9AWt|{c6_eOxUp(jH2o>35ips8_cOoT$M^>f_ z(}nA;xS({!8Qd%kr0`poYRK*3D0sM6ppl(KRCOHX2vxl%>B>kLdeTBBl-L0t`{2V< z-eCOz9hP9@$oPmi9s(Y-$z|aZI`qm8Tod7!jsx<6-`M<=A0OMIbmyHcQR^}HQM1^| z!}8oX`*}yJU*^`1cebzznF@{s8;FqPrRqY(X^rga4EHA-T(`@3xZC#8^6s3S9Tw&% z@a}Ha5pzzccYo9oci$YdEiST_bF4ZfGrFv`L)oj<pUyX%KJ;rgJ3pLv$ta09`-4(i z2|z^6x|kAPOIyo%lFxqGQ>3W9TD&G7!Rzm6?&!;s-b~6YQZ3y|2g_``N|DHz_Gr+K zS^Au!+IN<i#5lII9<$#3#w8AXIpp>!EUX&7mZ|wntO!Tx;>rTmBPTPuI=^lO`$Mdj z?cmj-Nenk<<B`Z{E}m4%Ccn8Cz3&=Fo287<EGIOMI{V}ukq{R=xA^M5^2*x5gHc^v zeo6{WcTFWpKQ$CD^*ki;<D$A{`C;H54J~c;YNx5%gJ-_)BwQUFKAQH4NXHw@lb5mH zkf0wHRMR>|6&U@nBz5q#hzrwmL${1U2urtsis17cQLkAUuJ@gSubXvV7)d+c%94^3 z_WeG5%H3k^b7W$E$Jib3a!jq~_!iSWo76S3ih$3GFS&_Np8HN7#l11d2=}r7Kt7gr zjhgk`+ZJt8-vzTzeOW!8(IF#p6he;{pp`d5R=(O-gm3`xoDli+d7~Zca!Zwu2A`aK zg}LItbcVlG&3eA#5Fj9d<Pa{?V58)5rB!#K8d%Y5=Hs&L4Bv=FbquVQn<PA+Jn3sT zA15DhVQp$&De_sw!QqS)kM+f?^+k<tLI{OLHQ>f2jGkT05Jy5ze03)(8r8!U&hF)! zz#T}YP+afXcZiBFemH!`sVceO$RcC$5@n>Opx#KxybP;cY-ynT6Y*!racbAN^M@;V z6CuN?R#z9i{AH@T&%h*_Ey~4~)VRaZH>?>>c~(blwvCTaj1|5)N=6@+!%AO{dlX}( z;xkcDWd26@W*w{83XT25V-j_4tHaSViN*oc#es#+$%i{p&#J5(HvDx9XULgxWHLSF zRD^B1_)WJagfLIo$P8}OC4~9^_C{v#Q-IHL|LLY+@Qi=FBNRl*f4JihJma@El7XM@ zH})%mSNpB)Cg9cn@xBP~TL19LIe3+S{MZ*f=Qp1CfuHRkKhgou`OOCf;Ai};)oAdF wzqy(SUhy{;y1?uG<Ao5gxAO2yY5>I_eNXsr5+KC?*ZUq^P!R6+KAi;oKS~m|ZvX%Q diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/R_mu_2016Test.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/2016/R_mu_2016Test.root deleted file mode 100644 index 04fa25d8ff939f317ee22d0201f110fc8d8facac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12765 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 Hoe2C7J$kcA diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/F_el_2016PSTest.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/F_el_2016PSTest.root deleted file mode 100644 index 2ff43ce2794a4dac8e752cd6953b1fd90727e7fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11102 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/F_mu_2016PSTest.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/F_mu_2016PSTest.root deleted file mode 100644 index 81877818132326e2197fa44389f97333dd7d3095..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11117 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 V_r!u}`Ohc@#%*EGz*A|!{{wJdktzTH diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/R_el_2016PSTest.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/R_el_2016PSTest.root deleted file mode 100644 index c8b4c2d06ec3a1e058f31ec25a7b38825f2081e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12784 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/R_mu_2016PSTest.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/PS2016/R_mu_2016PSTest.root deleted file mode 100644 index 5b4e78f8883daca4fd389a13fb86698367b36369..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12770 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/F_el_Nedaa2015_2412-fakesStd.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/F_el_Nedaa2015_2412-fakesStd.root deleted file mode 100644 index 527c19f9d75176777f9af8b58de6c4c5533d70fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76239 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Fred2015_2412-fakesStd.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Fred2015_2412-fakesStd.root deleted file mode 100644 index 8f388f06d0681f0d18725035abdf31362f0dbd18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92915 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 VI_!dGeN8<FS?f-1KGTlT{tq$8lCA&% diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Fred2016_2412-fakesStdNoTTVA.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Fred2016_2412-fakesStdNoTTVA.root deleted file mode 100644 index a7aaf9bf85baa5af8a1fb977ebdfe8e668854724..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98333 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 ag{518@J3qH;`d6oK<(F7CBKPBDE|R6-Dau) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Nedaa2015_2412-fakesStd.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Nedaa2015_2412-fakesStd.root deleted file mode 100644 index fccf00697a3d328f6c6a6963a3678bf2a4637b1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92968 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 QO+5!$>+VVcQ;*XA4{NION&o-= diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Nedaa2016_2412-fakesStd.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_el_Nedaa2016_2412-fakesStd.root deleted file mode 100644 index 929bb91cd5284ba72f82d1f0ebfd40cfca8adeff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98356 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Fred2015_2412-fakesStd.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Fred2015_2412-fakesStd.root deleted file mode 100644 index f7bf09faefc98ca4b3a4d191152821b04c9fea90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70352 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Fred2016_2412-fakesStdNoTTVA.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Fred2016_2412-fakesStdNoTTVA.root deleted file mode 100644 index b2413e4757ac6c9fac75ad277264fbffe78885ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64571 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¨Ix?@yZMnTlpwI7MSyo-^04?Vh|J+P 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Nedaa2015_2412-fakesStd.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Nedaa2015_2412-fakesStd.root deleted file mode 100644 index 11feb6886c3a3c76a6014a999e8cb9a9c8962856..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70490 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 CdZQEo diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Nedaa2016_2412-fakesStd.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/Standard/R_mu_Nedaa2016_2412-fakesStd.root deleted file mode 100644 index f10330bd5929e2bea797b8b0f4367f5e37b3583a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69012 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≊lTEcB~y&8B2l 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/F_el_Fred2015_AT2414-fakesOldOR_MCup.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/F_el_Fred2015_AT2414-fakesOldOR_MCup.root deleted file mode 100644 index 03a440673f48896299180195c64affb3c28ba262..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 438 zcmXTQ&o5zMxUiUkfgy!~fpHrUCjr?ZK+FilB`i<|kOHx+9X=KLE*5+?U7U5sytaMs zA;N^o4GbWI(n6nIeazqmHW_Fe0|RS_TV_tGhFg4UPP|)DYD&DXb7_IDk%^&+Zdzh? zYO#M#ihq!<k%6J9UJ=Nl#H(ar1=$6*kAcAtXcf?xARmGNqX<Ed_<`Naf^aWT4^Tg; d?gd*13QdsjxsXf)g)!--0b_)5Te;~J1^{JqWy1gf diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_el_Fred2015_AT2414-fakesOldOR.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_el_Fred2015_AT2414-fakesOldOR.root deleted file mode 100644 index 93606bf4c6c8cd8bc786ecdf015e6cbbad1d8bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92945 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_el_Fred2016_AT2414-fakesOldOR.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_el_Fred2016_AT2414-fakesOldOR.root deleted file mode 100644 index aa809097468c25ca29eb789b04933bf7012e6179..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98221 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�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 PvIT0r0xtPXKaBhz^BmAT diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_mu_Fred2015_AT2414-fakesOldOR.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_mu_Fred2015_AT2414-fakesOldOR.root deleted file mode 100644 index b48cd20f553fb785a48cfab536af68cc745200c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70402 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≈`CpO; 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_mu_Fred2016_AT2414-fakesOldOR.root b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/20p7/StandardOldOR/R_mu_Fred2016_AT2414-fakesOldOR.root deleted file mode 100644 index 89c14708da9ccda819f2edf4b041d96bece1fe05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68930 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 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/mainpage.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/mainpage.h deleted file mode 100644 index 5cac0dedaff7..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/data/mainpage.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -/** - * @page tfpage TopFakes - * - * @section intro Introduction - * - * Description of the purpose of this code and how to use it. - * - * Example for usage - * @code - * executable [options] - * @endcode - * - * - * @section addinfo Additional information - * - * Some useful code is: - * - top::TopFakesMMWeightCalculator - * - * - * - */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasExample.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasExample.C deleted file mode 100644 index 24870d823628..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasExample.C +++ /dev/null @@ -1,224 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include <iostream> -#include <cmath> - -#include "Rtypes.h" - -#include "AtlasUtils.h" -// #ifndef __CINT__ -#include "AtlasStyle.C" -#include "AtlasLabels.C" -// #endif - -#include "TCanvas.h" -#include "TFile.h" -#include "TROOT.h" -#include "TH1F.h" -#include "TRandom.h" -#include "TGraphErrors.h" - -using namespace std; - -const Int_t GMAX=864; - -const int nren=3; -static const double mur[nren] = {1.0,0.25,4.0}; -static const double muf[nren] = {1.0,0.25,4.0}; -const unsigned int NUMPDF=41; - -TGraphErrors* GetGraph(Int_t ir, Int_t ifs,Int_t icut, Int_t ipdf); - - -void AtlasExample() -{ - -#ifdef __CINT__ - gROOT->LoadMacro("AtlasUtils.C"); -#endif - - SetAtlasStyle(); - - Int_t icol1=5; - Int_t icol2=5; - - TCanvas* c1 = new TCanvas("c1","single inclusive jets",50,50,600,600); - // TCanvas* c1 = new TCanvas("c1","single inclusive jets"); - TPad* thePad = (TPad*)c1->cd(); - thePad->SetLogy(); - - Double_t ymin=1.e-3; Double_t ymax=2e7; - Double_t xmin=60.00; Double_t xmax=3500.; - TH1F *h1 = thePad->DrawFrame(xmin,ymin,xmax,ymax); - h1->SetYTitle("d#sigma_{jet}/dE_{T,jet} [fb/GeV]"); - h1->SetXTitle("E_{T,jet} [GeV]"); - h1->GetYaxis()->SetTitleOffset(1.4); - h1->GetXaxis()->SetTitleOffset(1.4); - //h1->GetXaxis()->SetNdivisions(5); - h1->Draw(); - - const Int_t ncut=1; - TGraphErrors *data[ncut]; - - for (Int_t icut=0; icut<ncut; icut++) { // loop over cuts - - TGraphErrors *g1[nren][ncut]; - for (Int_t ir=0; ir<nren; ir++) { // loop over ren scale - g1[ir][icut]= GetGraph(ir,ir,icut,0); - if (g1[ir][icut]) - cout << g1[ir][icut]->GetTitle() << " found " << g1[ir][icut]->GetName() << endl; - else { - cout << " g1 not found " << endl; - return; - } - g1[ir][icut]->SetLineColor(1); - g1[ir][icut]->SetMarkerStyle(0); - //g1[ir][icut]->Draw("C"); - } - - char daname[100]; - sprintf(daname,"data_%d",icut); - data[icut]=(TGraphErrors*)g1[0][icut]->Clone(daname); - data[icut]->SetMarkerStyle(20); - data[icut]->SetMarkerColor(1); - - // just invent some data - for (Int_t i=0; i< data[icut]->GetN(); i++) { - Double_t x1,y1,e,dx1=0.; - data[icut]->GetPoint(i,x1,y1); - Double_t r1 = 0.4*(gRandom->Rndm(1)+2); - Double_t r2 = 0.4*(gRandom->Rndm(1)+2); - //cout << " i= " << i << " x1= " << x1 << " y1= " << y1 << " r= " << r << endl; - Double_t y; - if (icut==0) y=r1*y1+r1*r2*r2*x1/50000.; - else y=r1*y1; - e=sqrt(y*1000)/200; - data[icut]->SetPoint(i, x1,y); - data[icut]->SetPointError(i,dx1,e); - } - //data[icut]->Print(); - - TGraphAsymmErrors* scale[ncut]; - TGraphAsymmErrors* scalepdf[ncut]; - - scale[icut]= myMakeBand(g1[0][icut],g1[1][icut],g1[2][icut]); - //printf(" band1: \n"); - //scale->Print(); - - scalepdf[icut]=(TGraphAsymmErrors* ) scale[icut]->Clone("scalepdf"); - - TGraphErrors *gpdf[NUMPDF][ncut]; - for (Int_t ipdf=0; ipdf<NUMPDF; ipdf++) { - gpdf[ipdf][icut]= GetGraph(0,0,icut,ipdf); - if (gpdf[ipdf][icut]) - cout << gpdf[ipdf][icut]->GetTitle() << " found " << gpdf[ipdf][icut]->GetName() << endl; - else { - cout << " gpdf not found " << endl; - return; - } - gpdf[ipdf][icut]->SetLineColor(2); - gpdf[ipdf][icut]->SetLineStyle(1); - gpdf[ipdf][icut]->SetMarkerStyle(0); - myAddtoBand(gpdf[ipdf][icut],scalepdf[icut]); - } - - scalepdf[icut]->SetFillColor(icol2); - scalepdf[icut]->Draw("zE2"); - scale[icut]->SetFillColor(icol1); - scale[icut]->Draw("zE2"); - g1[0][icut]->SetLineWidth(3); - g1[0][icut]->Draw("z"); - data[icut]->Draw("P"); - - } - - myText( 0.3,0.85,1,"#sqrt{s}= 14 TeV"); - myText( 0.57,0.85,1,"|#eta_{jet}|<0.5"); - myMarkerText(0.55,0.75,1,20,"Data 2009",1.3); - myBoxText( 0.55,0.67,0.05,icol1,"NLO QCD"); - - //ATLAS_LABEL(0.2,0.2); myText( 0.37,0.2,1,"Preliminary"); - - // new method for ATLAS labels. Use this! - //ATLASLabel(0.2,0.2); - ATLASLabel(0.2,0.2,"Preliminary"); - //ATLASLabel(0.2,0.2,"Work in progress"); - - c1->Print("AtlasExample.eps"); - c1->Print("AtlasExample.png"); - c1->Print("AtlasExample.pdf"); - -} - -TGraphErrors* GetGraph(Int_t ir, Int_t ifs,Int_t icut, Int_t ipdf) -{ - - const bool debug=0; - - char *cuts[5] = - {"0.0 <= |eta| < 0.5", - "0.5 <= |eta| < 1.0", - "1.0 <= |eta| < 1.5", - "1.5 <= |eta| < 2.0", - "2.0 <= |eta| < 3.0"}; - - const double mur[] = {1.0,0.25,4.0}; - const double muf[] = {1.0,0.25,4.0}; - - TFile *f1 = TFile::Open("nlofiles.root"); - if (f1&&debug) cout << " file opened " << endl; - - char gname[100]; - char tname[100]; - - if (debug) cout << " mur= " << mur[ir] << " muf= " << muf[ifs] - << " iut= " << icut << " ipdf= " << ipdf << endl; - - if (ipdf>=0) - sprintf(tname," E_T (mu_r=%g, mu_f=%g);%s Pdf: %d",mur[ir],muf[ifs],cuts[icut],ipdf); - else - sprintf(tname," E_T %s Ms= %d",cuts[icut],-ipdf); - - if (debug) cout << "**GetGraph: Look for: " << tname << endl; - - TGraphErrors* g1 = 0; - - for (int i=1; i<=GMAX; i++){ - sprintf(gname,"full_%d",i); - // sprintf(gname,"born_%d",i); - sprintf(gname,"full_%d",i); - g1=(TGraphErrors*) f1->Get(gname); - if (!g1) { cout << gname << " not found " << endl; return g1=0; } - - const char *title=g1->GetTitle(); - - if (debug){ - cout << " Title= " << title << endl; - cout << " tname= " << tname << endl; - cout << " strcmp: " << strcmp(title,tname) << endl; - } - - if (strcmp(title,tname)==0) break; - g1=0; - } - - if (!g1) return 0; - if (debug) cout << " found: " << g1->GetTitle() << endl; - - return g1; -} - - - -#ifndef __CINT__ - -int main() { - - AtlasExample(); - - return 0; -} - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasLabels.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasLabels.C deleted file mode 100644 index eb382c7759ed..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasLabels.C +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "AtlasLabels.h" - -#include "TLatex.h" -#include "TLine.h" -#include "TPave.h" -#include "TMarker.h" - - -void ATLASLabel(Double_t x,Double_t y,char* text,Color_t color) -{ - TLatex l; //l.SetTextAlign(12); l.SetTextSize(tsize); - l.SetNDC(); - l.SetTextFont(72); - l.SetTextColor(color); - - //double delx = 0.115*696*gPad->GetWh()/(472*gPad->GetWw()); - double delx = 0.115*696*gPad->GetWh()/(472*gPad->GetWw()); - - //l.DrawLatex(x,y,"ATLAS Internal"); - l.DrawLatex(x,y,"ATLAS"); - if (text) { - TLatex p; - p.SetNDC(); - p.SetTextFont(42); - p.SetTextColor(color); - //p.DrawLatex(x+delx,y,text); - //p.DrawLatex(x+delx,y,text); - p.DrawLatex(x+0.16,y,text); - } -} - - -void ATLASLabelOld(Double_t x,Double_t y,bool Preliminary,Color_t color) -{ - TLatex l; //l.SetTextAlign(12); l.SetTextSize(tsize); - l.SetNDC(); - l.SetTextFont(72); - l.SetTextColor(color); - l.DrawLatex(x,y,"ATLAS"); - if (Preliminary) { - TLatex p; - p.SetNDC(); - p.SetTextFont(42); - p.SetTextColor(color); - p.DrawLatex(x+0.115,y,"Preliminary"); - } -} - - - -void ATLASVersion(char* version,Double_t x,Double_t y,Color_t color) -{ - - if (version) { - char versionString[100]; - sprintf(versionString,"Version %s",version); - TLatex l; - l.SetTextAlign(22); - l.SetTextSize(0.04); - l.SetNDC(); - l.SetTextFont(72); - l.SetTextColor(color); - l.DrawLatex(x,y,versionString); - } -} - - - -void myText(Double_t x,Double_t y,Color_t color,char *text,float size) -{ - Double_t tsize=size; - TLatex l; //l.SetTextAlign(12); - l.SetTextSize(tsize); - l.SetNDC(); - l.SetTextColor(color); - l.DrawLatex(x,y,text); -} - -void myBoxText(Double_t x, Double_t y,Double_t boxsize,Int_t mcolor,char *text) -{ - Double_t tsize=0.06; - - TLatex l; l.SetTextAlign(12); //l.SetTextSize(tsize); - l.SetNDC(); - l.DrawLatex(x,y,text); - - Double_t y1=y-0.25*tsize; - Double_t y2=y+0.25*tsize; - Double_t x2=x-0.3*tsize; - Double_t x1=x2-boxsize; - - printf("x1= %f x2= %f y1= %f y2= %f \n",x1,x2,y1,y2); - - TPave *mbox= new TPave(x1,y1,x2,y2,0,"NDC"); - - mbox->SetFillColor(mcolor); - mbox->SetFillStyle(1001); - mbox->Draw(); - - TLine mline; - mline.SetLineWidth(4); - mline.SetLineColor(1); - mline.SetLineStyle(1); - Double_t y_new=(y1+y2)/2.; - mline.DrawLineNDC(x1,y_new,x2,y_new); - -} - -void myMarkerText(Double_t x,Double_t y,Int_t color,Int_t mstyle,char *text) - // Float_t msize=2.,Float_t mytsize=0.05) -{ - // printf("**myMarker: text= %s\ m ",text); - - Double_t tsize=0.06; - TMarker *marker = new TMarker(x-(0.4*tsize),y,8); - marker->SetMarkerColor(color); marker->SetNDC(); - marker->SetMarkerStyle(mstyle); - marker->SetMarkerSize(2.0); - marker->Draw(); - - TLatex l; l.SetTextAlign(12); //l.SetTextSize(tsize); - l.SetNDC(); - l.DrawLatex(x,y,text); -} - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasLabels.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasLabels.h deleted file mode 100644 index 82b33cdbd032..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasLabels.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// -// @file AtlasLabels.h -// -// @author M.Sutton -// -// -// $Id: AtlasLabels.h 726730 2016-02-29 08:41:06Z derue $ - - -#ifndef __ATLASLABELS_H -#define __ATLASLABELS_H - -#include "Rtypes.h" - -void ATLASLabel(Double_t x,Double_t y,char* text=NULL,Color_t color=1); - -void ATLASLabelOld(Double_t x,Double_t y,bool Preliminary=false,Color_t color=1); - -void ATLASVersion(char* version=NULL,Double_t x=0.88,Double_t y=0.975,Color_t color=1); - -void myText(Double_t x,Double_t y,Color_t color,char *text,float size=0.045); - -void myBoxText(Double_t x, Double_t y,Double_t boxsize,Int_t mcolor,char *text); - -void myMarkerText(Double_t x,Double_t y,Int_t color,Int_t mstyle,char *text); -// Float_t msize=2.,Float_t mytsize=0.05); - -#endif // __ATLASLABELS_H diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.C deleted file mode 100644 index 99515ac6c365..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.C +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// -// ATLAS Style, based on a style file from BaBar -// - -#include <iostream> - -#include "AtlasStyle.h" - -#include "TROOT.h" - -void SetAtlasStyle () -{ - static TStyle* atlasStyle = 0; - std::cout << "\nApplying ATLAS style settings...\n" << std::endl ; - if ( atlasStyle==0 ) atlasStyle = AtlasStyle(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); -} - -TStyle* AtlasStyle() -{ - TStyle *atlasStyle = new TStyle("ATLAS","Atlas style"); - - // use plain black on white colors - Int_t icol=0; // WHITE - atlasStyle->SetFrameBorderMode(icol); - atlasStyle->SetFrameFillColor(icol); - atlasStyle->SetCanvasBorderMode(icol); - atlasStyle->SetCanvasColor(icol); - atlasStyle->SetPadBorderMode(icol); - atlasStyle->SetPadColor(icol); - atlasStyle->SetStatColor(icol); - //atlasStyle->SetFillColor(icol); // don't use: white fill color for *all* objects - - // set the paper & margin sizes - atlasStyle->SetPaperSize(20,26); - - // set margin sizes - atlasStyle->SetPadTopMargin(0.05); - atlasStyle->SetPadRightMargin(0.05); - atlasStyle->SetPadBottomMargin(0.16); - atlasStyle->SetPadLeftMargin(0.16); - - // set title offsets (for axis label) - atlasStyle->SetTitleXOffset(1.4); - atlasStyle->SetTitleYOffset(1.4); - - // use large fonts - //Int_t font=72; // Helvetica italics - Int_t font=42; // Helvetica - Double_t tsize=0.045; - atlasStyle->SetTextFont(font); - - atlasStyle->SetTextSize(tsize); - atlasStyle->SetLabelFont(font,"x"); - atlasStyle->SetTitleFont(font,"x"); - atlasStyle->SetLabelFont(font,"y"); - atlasStyle->SetTitleFont(font,"y"); - atlasStyle->SetLabelFont(font,"z"); - atlasStyle->SetTitleFont(font,"z"); - - atlasStyle->SetLabelSize(tsize,"x"); - atlasStyle->SetTitleSize(tsize,"x"); - atlasStyle->SetLabelSize(tsize,"y"); - atlasStyle->SetTitleSize(tsize,"y"); - atlasStyle->SetLabelSize(tsize,"z"); - atlasStyle->SetTitleSize(tsize,"z"); - - // use bold lines and markers - atlasStyle->SetMarkerStyle(20); - atlasStyle->SetMarkerSize(1.); - atlasStyle->SetHistLineWidth(1.5); - atlasStyle->SetLineStyleString(2,"[12 12]"); // postscript dashes - - // get rid of X error bars - //atlasStyle->SetErrorX(0.001); - // get rid of error bar caps - atlasStyle->SetEndErrorSize(0.); - - // do not display any of the standard histogram decorations - atlasStyle->SetOptTitle(0); - atlasStyle->SetOptStat("emr"); - //atlasStyle->SetOptStat(0); - //atlasStyle->SetOptFit(1111); - atlasStyle->SetOptFit(0); - - // put tick marks on top and RHS of plots - atlasStyle->SetPadTickX(1); - atlasStyle->SetPadTickY(1); - - return atlasStyle; - -} - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.h deleted file mode 100644 index 259bed79a7e1..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// -// @file AtlasStyle.h -// -// ATLAS Style, based on a style file from BaBar -// -// -// @author M.Sutton -// -// -// $Id: AtlasStyle.h 726730 2016-02-29 08:41:06Z derue $ - -#ifndef __ATLASSTYLE_H -#define __ATLASSTYLE_H - -#include "TStyle.h" - -void SetAtlasStyle(); - -TStyle* AtlasStyle(); - -#endif // __ATLASSTYLE_H diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.py b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.py deleted file mode 100644 index 1113db98a72c..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasStyle.py +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration - -from ROOT import * -ROOT.gROOT.LoadMacro("AtlasStyle.C") -#SetAtlasStyle() diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.C deleted file mode 100644 index e2e336e2ae5e..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.C +++ /dev/null @@ -1,330 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - - -#include <iostream> -#include <cmath> - -#include "AtlasUtils.h" - -#include "TLine.h" -#include "TLatex.h" -#include "TMarker.h" -#include "TPave.h" -#include "TH1.h" - -void ATLAS_LABEL(Double_t x,Double_t y,Color_t color) -{ - TLatex l; //l.SetTextAlign(12); l.SetTextSize(tsize); - l.SetNDC(); - l.SetTextFont(72); - l.SetTextColor(color); - l.DrawLatex(x,y,"ATLAS"); -} - -TGraphErrors* myTGraphErrorsDivide(TGraphErrors* g1,TGraphErrors* g2) { - - const Int_t debug=0; - - if (!g1) printf("**myTGraphErrorsDivide: g1 does not exist ! \n"); - if (!g2) printf("**myTGraphErrorsDivide: g2 does not exist ! \n"); - - - Int_t n1=g1->GetN(); - Int_t n2=g2->GetN(); - - if (n1!=n2) { - printf("**myTGraphErrorsDivide: vector do not have same number of entries ! \n"); - } - - TGraphErrors* g3= new TGraphErrors(); - - Double_t x1=0., y1=0., x2=0., y2=0.; - Double_t dx1=0.,dy1=0., dy2=0.; - - Int_t iv=0; - for (Int_t i1=0; i1<n1; i1++) { - for (Int_t i2=0; i2<n2; i2++) { - //if (debug) printf("**myTGraphErrorsDivide: %d %d ! \n",i1,i2); - - g1->GetPoint(i1,x1,y1); - g2->GetPoint(i2,x2,y2); - if (x1!=x2) { - //printf("**myTGraphErrorsDivide: %d x1!=x2 %f %f ! \n",iv,x1,x2); - }else{ - //if (debug) printf("**myTGraphErrorsDivide: %d x1=x2 %f %f ! \n",iv,x1,x2); - dx1 = g1->GetErrorX(i1); - if (y1!=0) dy1 = g1->GetErrorY(i1)/y1; - if (y2!=0) dy2 = g2->GetErrorY(i2)/y2; - - if (debug) - printf("**myTGraphErrorsDivide: %d x1=%f x2=%f y1=%f y2=%f \n",iv,x1,x2,y1,y2); - - if (y2!=0.) g3->SetPoint(iv, x1,y1/y2); - else g3->SetPoint(iv, x1,y2); - - Double_t e=0.; - if (y1!=0 && y2!=0) e=std::sqrt(dy1*dy1+dy2*dy2)*(y1/y2); - g3->SetPointError(iv,dx1,e); - - - if (debug) { - //Double_t g3y, g3x,g3e; - //g3->GetPoint(iv, g3y,g3x); - //g3e=g3->GetErrorY(iv); - //printf("%d g3y= %f g3e=%f \n",iv,g3y,g3e); - } - iv++; - } - // printf("**myTGraphErrorsDivide: ...next \n"); - } - } - return g3; - -} - - -TGraphAsymmErrors* myTGraphErrorsDivide(TGraphAsymmErrors* g1,TGraphAsymmErrors* g2) { - - const Int_t debug=0; - - TGraphAsymmErrors* g3= new TGraphAsymmErrors(); - Int_t n1=g1->GetN(); - Int_t n2=g2->GetN(); - - if (n1!=n2) { - printf(" vectors do not have same number of entries ! \n"); - return g3; - } - - Double_t x1=0., y1=0., x2=0., y2=0.; - Double_t dx1h=0., dx1l=0.; - Double_t dy1h=0., dy1l=0.; - Double_t dy2h=0., dy2l=0.; - - Double_t* X1 = g1->GetX(); - Double_t* Y1 = g1->GetY(); - Double_t* EXhigh1 = g1->GetEXhigh(); - Double_t* EXlow1 = g1->GetEXlow(); - Double_t* EYhigh1 = g1->GetEYhigh(); - Double_t* EYlow1 = g1->GetEYlow(); - - Double_t* X2 = g2->GetX(); - Double_t* Y2 = g2->GetY(); - Double_t* EXhigh2 = g2->GetEXhigh(); - Double_t* EXlow2 = g2->GetEXlow(); - Double_t* EYhigh2 = g2->GetEYhigh(); - Double_t* EYlow2 = g2->GetEYlow(); - - for (Int_t i=0; i<g1->GetN(); i++) { - g1->GetPoint(i,x1,y1); - g2->GetPoint(i,x2,y2); - dx1h = EXhigh1[i]; - dx1l = EXlow1[i]; - if (y1!=0.) dy1h = EYhigh1[i]/y1; - else dy1h = 0.; - if (y2!=0.) dy2h = EYhigh2[i]/y2; - else dy2h = 0.; - if (y1!=0.) dy1l = EYlow1 [i]/y1; - else dy1l = 0.; - if (y2!=0.) dy2l = EYlow2 [i]/y2; - else dy2l = 0.; - - //if (debug) - //printf("%d x1=%f x2=%f y1=%f y2=%f \n",i,x1,x2,y1,y2); - if (debug) - printf("%d dy1=%f %f dy2=%f %f sqrt= %f %f \n",i,dy1l,dy1h,dy2l,dy2h, - std::sqrt(dy1l*dy1l+dy2l*dy2l), std::sqrt(dy1h*dy1h+dy2h*dy2h)); - - if (y2!=0.) g3->SetPoint(i, x1,y1/y2); - else g3->SetPoint(i, x1,y2); - Double_t el=0.; Double_t eh=0.; - - if (y1!=0. && y2!=0.) el=std::sqrt(dy1l*dy1l+dy2l*dy2l)*(y1/y2); - if (y1!=0. && y2!=0.) eh=std::sqrt(dy1h*dy1h+dy2h*dy2h)*(y1/y2); - - if (debug) printf("dx1h=%f dx1l=%f el=%f eh=%f \n",dx1h,dx1l,el,eh); - g3->SetPointError(i,dx1h,dx1l,el,eh); - - } - return g3; - -} - - - -TGraphAsymmErrors* myMakeBand(TGraphErrors* g0, TGraphErrors* g1,TGraphErrors* g2) { - // default is g0 - //const Int_t debug=0; - - TGraphAsymmErrors* g3= new TGraphAsymmErrors(); - - Double_t x1=0., y1=0., x2=0., y2=0., y0=0, x3=0.; - //Double_t dx1=0.; - Double_t dum; - for (Int_t i=0; i<g1->GetN(); i++) { - g0->GetPoint(i, x1,y0); - g1->GetPoint(i, x1,y1); - g2->GetPoint(i, x1,y2); - - // if (y1==0) y1=1; - //if (y2==0) y2=1; - - if (i==g1->GetN()-1) x2=x1; - else g2->GetPoint(i+1,x2,dum); - - if (i==0) x3=x1; - else g2->GetPoint(i-1,x3,dum); - - Double_t tmp=y2; - if (y1<y2) {y2=y1; y1=tmp;} - //Double_t y3=1.; - Double_t y3=y0; - g3->SetPoint(i,x1,y3); - - Double_t binwl=(x1-x3)/2.; - Double_t binwh=(x2-x1)/2.; - if (binwl==0.) binwl= binwh; - if (binwh==0.) binwh= binwl; - g3->SetPointError(i,binwl,binwh,(y3-y2),(y1-y3)); - - } - return g3; - -} - -void myAddtoBand(TGraphErrors* g1, TGraphAsymmErrors* g2) { - - Double_t x1=0., y1=0., y2=0., y0=0; - //Double_t dx1=0.; - //Double_t dum; - - if (g1->GetN()!=g2->GetN()) - std::cout << " graphs have not the same # of elements " << std::endl; - - Double_t* EYhigh = g2-> GetEYhigh(); - Double_t* EYlow = g2-> GetEYlow(); - - for (Int_t i=0; i<g1->GetN(); i++) { - g1->GetPoint(i, x1,y1); - g2->GetPoint(i, x1,y2); - - if (y1==0) y1=1; - if (y2==0) y2=1; - - // if (i==g1->GetN()-1) x2=x1; - // else g2->GetPoint(i+1,x2,dum); - // if (i==0) x3=x1; - // else g2->GetPoint(i-1,x3,dum); - - Double_t eyh=0., eyl=0.; - //if (y1<y2) {y2=y1; y1=tmp;} - //Double_t y3=1.; - - //printf("%d: y1=%f y2=%f Eyhigh= %f Eylow= %f \n",i,y1,y2,EYhigh[i],EYlow[i]); - - y0=y1-y2; - if (y0!=0) { - if (y0>0){ - eyh=EYhigh[i]; - eyh=std::sqrt(eyh*eyh+y0*y0); - //printf("high: %d: y0=%f eyh=%f \n",i,y0,eyh); - g2->SetPointEYhigh(i,eyh); - } else { - eyl=EYlow[i]; - eyl=std::sqrt(eyl*eyl+y0*y0); - // printf("low: %d: y0=%f eyl=%f \n",i,y0,eyl); - g2->SetPointEYlow (i,eyl); - } - } - } - return; - -} - -TGraphErrors* TH1TOTGraph(TH1 *h1){ - - - if (!h1) std::cout << "TH1TOTGraph: histogram not found !" << std::endl; - - TGraphErrors* g1= new TGraphErrors(); - - Double_t x, y, ex, ey; - for (Int_t i=0; i<h1->GetNbinsX(); i++) { - y=h1->GetBinContent(i); - ey=h1->GetBinError(i); - x=h1->GetBinCenter(i); - ex=h1->GetBinWidth(i); - - // cout << " x,y = " << x << " " << y << " ex,ey = " << ex << " " << ey << endl; - - g1->SetPoint(i,x,y); - g1->SetPointError(i,ex,ey); - - } - - //g1->Print(); - - return g1; -} - -void myText(Double_t x,Double_t y,Color_t color,char *text,float size) { - - Double_t tsize=size; - TLatex l; //l.SetTextAlign(12); - l.SetTextSize(tsize); - l.SetNDC(); - l.SetTextColor(color); - l.DrawLatex(x,y,text); -} - - -void myBoxText(Double_t x, Double_t y,Double_t boxsize,Int_t mcolor,char *text,Float_t mytsize) -{ - - Double_t tsize=0.06; - - TLatex l; l.SetTextAlign(12); l.SetTextSize(mytsize); - l.SetNDC(); - l.DrawLatex(x,y,text); - - Double_t y1=y-0.25*tsize; - Double_t y2=y+0.25*tsize; - Double_t x2=x-0.3*tsize; - Double_t x1=x2-boxsize; - - printf("x1= %f x2= %f y1= %f y2= %f \n",x1,x2,y1,y2); - - TPave *mbox= new TPave(x1,y1,x2,y2,0,"NDC"); - - mbox->SetFillColor(mcolor); - mbox->SetFillStyle(1001); - mbox->Draw(); - - TLine mline; - mline.SetLineWidth(4); - mline.SetLineColor(1); - mline.SetLineStyle(1); - Double_t y_new=(y1+y2)/2.; - mline.DrawLineNDC(x1,y_new,x2,y_new); - -} - - -void myMarkerText(Double_t x,Double_t y,Int_t color,Int_t mstyle,char *text, - Float_t msize,Float_t mytsize) -{ - Double_t tsize=0.06; - TMarker *marker = new TMarker(x-(0.4*tsize),y,8); - marker->SetMarkerColor(color); marker->SetNDC(); - marker->SetMarkerStyle(mstyle); - marker->SetMarkerSize(msize); - marker->Draw(); - - TLatex l; l.SetTextAlign(12); - l.SetTextSize(mytsize); - l.SetNDC(); - l.DrawLatex(x,y,text); -} - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.h b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.h deleted file mode 100644 index be71ac787fb6..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// -// @file AtlasUtils.h -// -// -// @author M.Sutton -// -// -// $Id: AtlasUtils.h 726730 2016-02-29 08:41:06Z derue $ - - -#ifndef __ATLASUTILS_H -#define __ATLASUTILS_H - -#include "TGraphErrors.h" -#include "TGraphAsymmErrors.h" - -void ATLAS_LABEL(Double_t x,Double_t y,Color_t color=1); - -TGraphErrors* myTGraphErrorsDivide(TGraphErrors* g1,TGraphErrors* g2); - -TGraphAsymmErrors* myTGraphErrorsDivide(TGraphAsymmErrors* g1,TGraphAsymmErrors* g2); - -TGraphAsymmErrors* myMakeBand(TGraphErrors* g0, TGraphErrors* g1,TGraphErrors* g2); - -void myAddtoBand(TGraphErrors* g1, TGraphAsymmErrors* g2); - -TGraphErrors* TH1TOTGraph(TH1 *h1); - -void myText(Double_t x,Double_t y,Color_t color,char *text,float size=0.1); - -void myBoxText(Double_t x, Double_t y,Double_t boxsize,Int_t mcolor,char *text, - Float_t mytsize=0.05); - -void myMarkerText(Double_t x,Double_t y,Int_t color,Int_t mstyle,char *text,Float_t msize=2., - Float_t mytsize=0.05); - -#endif // __ATLASUTILS_H - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.py b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.py deleted file mode 100644 index d19a7dc5b445..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/AtlasUtils.py +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration - -from ROOT import * -ROOT.gROOT.LoadMacro("AtlasUtils.C") - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/EffSummary.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/EffSummary.C deleted file mode 100644 index c72f3edbe5d4..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/EffSummary.C +++ /dev/null @@ -1,595 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TH1.h" -#include "TFile.h" -#include "TCanvas.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" - -#include <string> -#include <map> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Michele Pinamonti (Univ. Udine), Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot a summary of all efficiencies -// vs different variables -// It reads as input the default efficiencies of TopFakes package -// void EffSummary() is the core of this macro -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - -class MMEffComparison { -public: - MMEffComparison(){ - // _c = new TCanvas("c","c",600,600); - _totH = 0; - _label = ""; - _dummyHist = 0; - _noYlabels = false; - }; - ~MMEffComparison(){}; - - - void SetIsReal(int isReal=0){ - _isReal = isReal; - }; - - void SetXaxis(float min=0,float max=1,string title,int njetbins=0){ - _dummyHist = new TH1F("h","h",1,min,max); - _dummyHist->GetXaxis()->SetTitle(title.c_str()); - if(njetbins>0){ - _dummyHist->GetXaxis()->SetNdivisions(njetbins); - _dummyHist->GetXaxis()->CenterLabels(); - } - }; - - void SetYaxis(float min=0,float max=1){ - _dummyHist = new TH1F("h","h",1,min,max); - //_dummyHist->GetYaxis()->SetTitle(title.c_str()); - /*if(njetbins>0){ - _dummyHist->GetYaxis()->SetNdivisions(njetbins); - _dummyHist->GetYaxis()->CenterLabels(); - }*/ - }; - - void Add(string filename,string histoname,string label,int color,int style,int color2=-1,int style2=-1){ - TFile *f = new TFile(filename.c_str()); - std::cout << " filename = " << filename << std::endl; - std::cout << " histoname = " << histoname << std::endl; - _h[_totH] = (TH1*)f->Get(histoname.c_str())->Clone(); - - // cout << "Adding " << filename << ", " << histoname << endl; - // cout << _h[_totH]->GetBinContent(1) << endl; - - if(!_dummyHist){ - _dummyHist = (TH1F*)_h[_totH]->Clone("h_dummy"); - for(int i_bin=1;i_bin<=_dummyHist->GetNbinsX();i_bin++){ - _dummyHist->SetBinContent(i_bin,0); - _dummyHist->SetBinError(i_bin,0); - } - } - - _h[_totH]->SetName(label.c_str()); - _h[_totH]->SetTitle(label.c_str()); - _h[_totH]->SetLineColor(color); - _h[_totH]->SetLineWidth(1); - // _h[_totH]->SetLineStyle(style); - - // _h[_totH]->SetMarkerSize(0); - _h[_totH]->SetMarkerSize(1.5); - _h[_totH]->SetMarkerStyle(style); - _h[_totH]->SetMarkerColor(color); - - // _h_syst_up[_totH] = (TH1*)_h[_totH]->Clone(Form("%s_syst_up",histoname.c_str())); - // _h_syst_down[_totH] = (TH1*)_h[_totH]->Clone(Form("%s_syst_down",histoname.c_str())); - - _h_syst[_totH] = new TGraphAsymmErrors(_h[_totH]->GetNbinsX()); - for(int i_bin=1;i_bin<=_h[_totH]->GetNbinsX();i_bin++){ - _h_syst[_totH]->SetPoint(i_bin-1,_h[_totH]->GetXaxis()->GetBinCenter(i_bin), _h[_totH]->GetBinContent(i_bin) ); - _h_syst[_totH]->SetPointEYhigh( i_bin-1, _h[_totH]->GetBinError(i_bin) ); - _h_syst[_totH]->SetPointEYlow( i_bin-1, _h[_totH]->GetBinError(i_bin) ); - _h_syst[_totH]->SetPointEXhigh( i_bin-1, _h[_totH]->GetXaxis()->GetBinWidth(i_bin)/2. ); - _h_syst[_totH]->SetPointEXlow( i_bin-1, _h[_totH]->GetXaxis()->GetBinWidth(i_bin)/2. ); - } - - _h_syst[_totH]->SetMarkerSize(0); - _h_syst[_totH]->SetLineColor(color); - _h_syst[_totH]->SetLineStyle(style); - - if(color2>=0) _h_syst[_totH]->SetFillColor(color2); - else _h_syst[_totH]->SetFillColor(color); - if(style2>=0) _h_syst[_totH]->SetFillStyle(style2);//3454); - else _h_syst[_totH]->SetFillStyle(3454); - // _h_syst[_totH]->SetLineWidth(2); - - _index[label] = _totH; - _totH ++; - }; - - void AddSyst(string filename,string histoname,string label){ - TFile *f = new TFile(filename.c_str()); - // cout << "Adding syst to " << filename << ", " << histoname << " -> " << _index[label] << endl; - AddSystToHist( (TH1*)f->Get(histoname.c_str()), _h_syst[_index[label]] ); - }; - - void SetLabel(string label){ - _label = label; - }; - - void Draw(){ - bool xaxisSet = false; - if(_dummyHist!=0) _dummyHist->Draw(); - for(int i=0;i<_totH;i++){ - // if(i==0 && _dummyHist==0) _h_syst[i]->Draw("E2 same"); - // else - _h_syst[i]->Draw("E2 same"); - // if(i==0 && _dummyHist==0) - // _h[i]->Draw("E same"); - // else - _h[i]->Draw("E same"); - // if(i>0 && !xaxisSet) _h[0]->GetXaxis()->SetTitle( _h[i]->GetXaxis()->GetTitle() ); - string s = _h[i]->GetXaxis()->GetTitle(); - if( s != "" ) xaxisSet = true; - } - - if(_noYlabels){ - _dummyHist->GetYaxis()->SetTitle(""); - _dummyHist->GetYaxis()->SetLabelSize(0); - } - else{ - if(_isReal==0) _dummyHist->GetYaxis()->SetTitle("#epsilon_{fake}"); - if(_isReal==1) _dummyHist->GetYaxis()->SetTitle("#epsilon_{real}"); - if(_isReal==2) _dummyHist->GetYaxis()->SetTitle("Efficiency"); - } - - // if(_isReal) _dummyHist->SetMaximum(1.65); - if(_isReal) _dummyHist->SetMaximum(1.3); - else _dummyHist->SetMaximum(1.00); - _dummyHist->SetMinimum(0); - - // fix empty bins and error bars... - for(int i=0;i<_totH;i++){ - for(int i_bin=1;i_bin<=_h[i]->GetNbinsX();i_bin++){ - // _h[i]->SetBinError(i_bin,0.0001); - if( _h[i]->GetBinContent(i_bin)<=0 ) _h_syst[i]->SetPointEYhigh(i_bin-1,0); - if( _h[i]->GetBinContent(i_bin)<=0 ) _h_syst[i]->SetPointEYlow(i_bin-1,0); - // if( _h[i]->GetTitle() ) - } - } - - gPad->RedrawAxis(); - }; - - void DrawLegend(float x0=0.2, float y0=0.7, float x1=0.9, float y1=0.9){ - TLegend *l; - if(_isReal==2) l = new TLegend(x0,y0,x1,y1); - if(_isReal==2) l->SetNColumns(3); - l->SetFillStyle(0); - l->SetBorderSize(0); - l->SetTextSize(0.06); - for(int i=0;i<_totH;i++){ - // l->AddEntry(_h_syst[i],_h[i]->GetTitle(),"lf"); - _h_forLegend[i] = (TH1F*)_h[i]->Clone(Form("histForLegend[%d]",i)); - _h_forLegend[i]->SetFillColor(_h_syst[i]->GetFillColor()); - _h_forLegend[i]->SetFillStyle(_h_syst[i]->GetFillStyle()); - l->AddEntry(_h_forLegend[i],_h[i]->GetTitle(),"lpf"); - } - l->Draw(); - } - - TH1* GetHist(int idx){ - return _h[idx]; - }; - - TH1F* GetDummyHist(){ - return _dummyHist; - }; - - bool _noYlabels; - -private: - TH1* _h[100]; - TH1* _h_forLegend[100]; - // TH1* _h_syst[100]; - TGraphAsymmErrors* _h_syst[100]; - // TH1* _h_syst_up[100]; - // TH1* _h_syst_down[100]; - int _totH; - string _label; - int _isReal; - TH1F* _dummyHist; - map<string,int> _index; -}; - -// -------------------------------------------------- - -class MMEffComparisonSet { -public: - MMEffComparisonSet(int w=600,int h=600){ - _c = new TCanvas("c","c",w,h); - _N = 0; - _idx = 0; - _ec[0] = new MMEffComparison(); - Cd(0); - }; - ~MMEffComparisonSet(){}; - - void Divide(int a=2, int b=1){ - _c->Divide(a,b, 0,0 ); - _N=a*b; - for(int i=0;i<_N;i++){ - _ec[i] = new MMEffComparison(); - if(i>0) _ec[i]->_noYlabels = true; - } - Cd(0); - }; - - void Cd(int i){ - _c->cd(i+1); - _idx = i; - }; - - void SaveAs(string name){ - _c->SaveAs(name.c_str()); - }; - - - // methods from MMEffComparison: - void SetIsReal(int isReal=0){ - _ec[_idx]->SetIsReal(isReal); - }; - - void SetXaxis(float min=0,float max=1,string title,int njetbins=0){ - _ec[_idx]->SetXaxis(min,max,title,njetbins); - }; - - void SetYaxis(float min=0,float max=1){ - _ec[_idx]->SetYaxis(min,max); - }; - - void Add(string filename,string histoname,string label,int color,int style,int color2=-1,int style2=-1){ - _ec[_idx]->Add(filename,histoname,label,color,style,color2,style2); - }; - - void AddSyst(string filename,string histoname,string label){ - _ec[_idx]->AddSyst(filename,histoname,label); - }; - - void SetLabel(string label){ - _ec[_idx]->SetLabel(label); - }; - - void Draw(){ - _ec[_idx]->Draw(); - }; - - void DrawLegend(float x0=0.2, float y0=0.7, float x1=0.9, float y1=0.9){ - _ec[_idx]->DrawLegend(x0,y0,x1,y1); - } - - TH1* GetHist(int idx){ - return _ec[_idx]->GetHist(idx); - }; - - TCanvas* GetCanvas(){ - return _c; - }; - - TH1F* GetDummyHist(){ - return _ec[_idx]->GetDummyHist(); - }; - -private: - TCanvas *_c; - - MMEffComparison *_ec[10]; - int _N; - int _idx; - -}; - -// -------------------------------------------------- - -void AddSystToHist(TH1* h, TGraphAsymmErrors* h_syst){ - float x; - int j; - float diff; - for(int i=0;i<h_syst->GetN();i++){ - x = h_syst->GetX()[i]; - j = h->GetXaxis()->FindBin(x); - diff = h->GetBinContent(j) - h_syst->GetY()[i]; - // syst cutoff ;) - //if(diff>0.2) diff = 0.2; - //if(diff<-0.2) diff = -0.2; - // -// if(x<h_syst->GetXaxis()->GetXmax() && j<=h_syst->GetN() && h_syst->GetY[j]>0 ){ - if(diff>0) h_syst->SetPointEYhigh( i, SqSum( h_syst->GetErrorYhigh(i), diff ) ); - if(diff<0) h_syst->SetPointEYlow( i, SqSum( h_syst->GetErrorYlow(i), diff ) ); -// } - } -}; - -float SqSum(float a,float b){ - return sqrt( pow(a,2) + pow(b,2) ); -}; - -// -------------------------------------------------- - - -void EffSummary(string ch="el",string var="all_1", - string jet="",string bjet="_ge1b",int isReal=2) -{ - // ch : "el" for electrons, "mu" for muons - // var: "all_1" for eta,pt,dR - // "all_2" for ptjet,njet,nbtag and dphi - // jet: jet bin - // bjet: b-jet bin - // isReal = 2 means both fake and real - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - - MMEffComparisonSet *c = new MMEffComparisonSet(1800,600*1800/1400); - - if(ch=="el"){ - string trig[] = {""}; // no trigger splitting - } - else{ - string trig[] = {"mu20i","mu50","mu20"} - } - - // define the variables - if(ch=="el"){ - if(var=="all_1"){ - // e channel - int Nvar = 3; - string vari[] = {"eta", "pt", "dR"}; - string label[] = {"|#eta(elec)| ","p_{T}(elec) [GeV] ","#DeltaR(elec,jet) "}; - float xmin[] = {0, 21, 0.}; - float xmax[] = {2.6, 149, 5.9}; - } - if(var=="all_2"){ - int Nvar = 4; - string vari[] = {"jetpt", "njet", "nbtag", "dPhi"}; - string label[] = {"p_{T}(leading jet) [GeV] ", "n_{jet} ", "n_{b-jet} ", "#Delta#phi(e,E_{T}^{miss}) " }; - float xmin[] = {0, 0.9, -0.1, -0.1}; - float xmax[] = {530, 6.1, 3.1, 3.3}; - } - } - - if(ch=="mu"){ - // mu channel - if(var=="all_1"){ - int Nvar = 3; - string vari[] = {"eta", "pt", "dR"}; - string label[] = {"|#eta(#mu)| ","p_{T}(#mu) [GeV] ","#DeltaR(#mu,jet) "}; - float xmin[] = {0, 21, 0.}; - float xmax[] = {2.6, 149, 5.9}; - } - if(var=="all_2"){ - int Nvar = 4; - string vari[] = {"jetpt", "njet", "nbtag", "dPhi"}; - string label[] = {"p_{T}(leading jet) [GeV] ", "n_{jet} ", "n_{b-jet} ", "#Delta#phi(#mu,E_{T}^{miss}) " }; - float xmin[] = {0, 0.9, -0.1, -0.1}; - float xmax[] = {530, 6.1, 3.1, 3.3}; - } - } - - - // ---- - - c->Divide(Nvar); - // c->GetCanvas()->GetPad(1)->SetRightMargin(0.3); - // c->GetCanvas()->GetPad(2)->SetRightMargin(0.5); - if(Nvar==4){ - c->GetCanvas()->GetPad(1)->SetPad(0, 0, 0.367672, 0.942544); - c->GetCanvas()->GetPad(2)->SetPad(0.367672,0, 0.57,0.942544); // w = 0.57 - 0.367672; origw = 0.983166 - 0.675419 - c->GetCanvas()->GetPad(3)->SetPad(0.57,0, 0.675419,0.942544); // w = 0.675419 - 0.57; origw = 0.983166 - 0.675419 - c->GetCanvas()->GetPad(4)->SetPad(0.675419, 0, 0.983166, 0.942544); - // 0.367672, 0, 0.675419, 0.942544 - } - else{ - cout << c->GetCanvas()->GetPad(1)->GetXlowNDC() << ", "; - cout << c->GetCanvas()->GetPad(1)->GetYlowNDC() << ", "; - cout << c->GetCanvas()->GetPad(1)->GetXlowNDC()+c->GetCanvas()->GetPad(1)->GetAbsWNDC() << ", "; - cout << c->GetCanvas()->GetPad(1)->GetYlowNDC()+c->GetCanvas()->GetPad(1)->GetAbsHNDC(); - cout << endl; - - cout << c->GetCanvas()->GetPad(2)->GetXlowNDC() << ", "; - cout << c->GetCanvas()->GetPad(2)->GetYlowNDC() << ", "; - cout << c->GetCanvas()->GetPad(2)->GetXlowNDC()+c->GetCanvas()->GetPad(2)->GetAbsWNDC() << ", "; - cout << c->GetCanvas()->GetPad(2)->GetYlowNDC()+c->GetCanvas()->GetPad(2)->GetAbsHNDC(); - cout << endl; - - cout << c->GetCanvas()->GetPad(3)->GetXlowNDC() << ", "; - cout << c->GetCanvas()->GetPad(3)->GetYlowNDC() << ", "; - cout << c->GetCanvas()->GetPad(3)->GetXlowNDC()+c->GetCanvas()->GetPad(3)->GetAbsWNDC() << ", "; - cout << c->GetCanvas()->GetPad(3)->GetYlowNDC()+c->GetCanvas()->GetPad(3)->GetAbsHNDC(); - cout << endl; - } - - for(int i=0;i<Nvar;i++){ - c->Cd(i); - c->SetYaxis(0.,1.5); - c->SetXaxis(xmin[i],xmax[i],label[i]); - if(vari[i]=="nbtag") c->SetXaxis(xmin[i],xmax[i],label[i],5); - if(vari[i]=="njet") c->SetXaxis(xmin[i],xmax[i],label[i],7); - - c->SetIsReal(isReal); - - // ================================================== - // case for electrons - if(ch=="el") { - //std::cout << " add real efficiencies " << std::endl; - // real efficiencies - c->Add("../data/R_"+ch+"_Default.root","eff_"+vari[i]+jet,"#varepsilon_{r} ",kBlack,kOpenTriangleUp,kBlack,3445); - // add systematics (CRreal) - //std::cout << " add CRreal " << std::endl; - c->AddSyst("../data/R_"+ch+"_Default_CRreal.root","eff_"+vari[i]+bjet+jet,"#varepsilon_{r} "); - - //std::cout << " add fake efficiencies " << std::endl; - // fake efficiencies - c->Add("../data/F_"+ch+"_Default.root","eff_"+vari[i]+bjet+jet,"#varepsilon_{f} ",kBlack,kFullTriangleUp,kBlack,3445); - // add systematics MCup - //std::cout << " add MCup " << std::endl; - c->AddSyst("../data/F_"+ch+"_Default_MCup.root","eff_"+vari[i]+bjet+jet,"#varepsilon_{f} "); - // add systematics MCdown - //std::cout << " add MCdown " << std::endl; - c->AddSyst("../data/F_"+ch+"_Default_MCdown.root","eff_"+vari[i]+bjet+jet,"#varepsilon_{f} "); - //std::cout << " add CRfake " << std::endl; - // add systematics CRfake - c->AddSyst("../data/F_"+ch+"_Default_CRfake.root","eff_"+vari[i]+bjet+jet,"#varepsilon_{f} "); - } - // ================================================== - // case for muons - if(ch=="mu") { - //std::cout << " add real efficiencies T&P" << std::endl; - // real efficiencies - c->Add("../data/R_"+ch+"_Default.root","eff_"+vari[i]+jet+"_"+trig[0],"#varepsilon_{r} "+trig[0],kRed,kOpenSquare,kRed-10,1001); - c->Add("../data/R_"+ch+"_Default.root","eff_"+vari[i]+jet+"_"+trig[1],"#varepsilon_{r} "+trig[1],kBlack,kOpenTriangleUp,kBlack,3445); - c->Add("../data/R_"+ch+"_Default.root","eff_"+vari[i]+jet+"_"+trig[2],"#varepsilon_{r} "+trig[2],kBlue,kOpenCircle,kBlue-7);//kAzure); - // add systematics (CRreal) - //std::cout << " add real efficiencies high MTW" << std::endl; - //std::cout << " file = " << "../data/R_"+ch+"_Default_CRreal.root" << std::endl; - c->AddSyst("../data/R_"+ch+"_Default_CRreal.root","eff_"+vari[i]+bjet+jet+"_"+trig[0],"#varepsilon_{r} "+trig[0]); - c->AddSyst("../data/R_"+ch+"_Default_CRreal.root","eff_"+vari[i]+bjet+jet+"_"+trig[1],"#varepsilon_{r} "+trig[1]); - c->AddSyst("../data/R_"+ch+"_Default_CRreal.root","eff_"+vari[i]+bjet+jet+"_"+trig[2],"#varepsilon_{r} "+trig[2]); - - //std::cout << " add fake efficiencies " << std::endl; - // fake efficiencies - c->Add("../data/F_"+ch+"_Default.root","eff_"+vari[i]+bjet+jet+"_"+trig[0],"#varepsilon_{f} "+trig[0],kRed,kFullSquare,kRed-10,1001); - c->Add("../data/F_"+ch+"_Default.root","eff_"+vari[i]+bjet+jet+"_"+trig[1],"#varepsilon_{f} "+trig[1],kBlack,kFullTriangleUp,kBlack,3445); - c->Add("../data/F_"+ch+"_Default.root","eff_"+vari[i]+bjet+jet+"_"+trig[2],"#varepsilon_{f} "+trig[2],kBlue,kFullCircle,kBlue-7); - - // add systematics MCup - c->AddSyst("../data/F_"+ch+"_Default_MCup.root","eff_"+vari[i]+bjet+jet+"_"+trig[0],"#varepsilon_{f} "+trig[0]); - c->AddSyst("../data/F_"+ch+"_Default_MCup.root","eff_"+vari[i]+bjet+jet+"_"+trig[1],"#varepsilon_{f} "+trig[1]); - c->AddSyst("../data/F_"+ch+"_Default_MCup.root","eff_"+vari[i]+bjet+jet+"_"+trig[2],"#varepsilon_{f} "+trig[2]); - - // add systematics MCdown - c->AddSyst("../data/F_"+ch+"_Default_MCdown.root","eff_"+vari[i]+bjet+jet+"_"+trig[0],"#varepsilon_{f} "+trig[0]); - c->AddSyst("../data/F_"+ch+"_Default_MCdown.root","eff_"+vari[i]+bjet+jet+"_"+trig[1],"#varepsilon_{f} "+trig[1]); - c->AddSyst("../data/F_"+ch+"_Default_MCdown.root","eff_"+vari[i]+bjet+jet+"_"+trig[2],"#varepsilon_{f} "+trig[2]); - - // add systematics CRfake - c->AddSyst("../data/F_"+ch+"_Default_CRfake.root","eff_"+vari[i]+bjet+jet+"_"+trig[0],"#varepsilon_{f} "+trig[0]); - c->AddSyst("../data/F_"+ch+"_Default_CRfake.root","eff_"+vari[i]+bjet+jet+"_"+trig[1],"#varepsilon_{f} "+trig[1]); - c->AddSyst("../data/F_"+ch+"_Default_CRfake.root","eff_"+vari[i]+bjet+jet+"_"+trig[2],"#varepsilon_{f} "+trig[2]); - } - c->Draw(); - - if(i==Nvar-1){ - if(ch=="el") c->DrawLegend(0.05,0.8, 0.95,0.95); - if(ch=="mu") c->DrawLegend(0.05,0.8, 0.95,0.95); - } - } - - // ------ - - if(Nvar==4){ - c->Cd(0); - c->GetDummyHist()->GetXaxis()->SetNdivisions(506); - // w = 0.57 - 0.367672; origw = 0.942544 - 0.367672 - c->Cd(1); - c->GetDummyHist()->GetXaxis()->SetLabelSize( ((0.983166 - 0.675419)/(0.57 - 0.367672)) * c->GetDummyHist()->GetXaxis()->GetLabelSize() ); - c->GetDummyHist()->GetXaxis()->SetTitleSize( ((0.983166 - 0.675419)/(0.57 - 0.367672)) * c->GetDummyHist()->GetXaxis()->GetTitleSize() ); - c->GetDummyHist()->GetXaxis()->SetLabelOffset(-0.015); - c->GetDummyHist()->GetXaxis()->SetTitleOffset(0.9); - // - c->Cd(2); - c->GetDummyHist()->GetXaxis()->SetLabelSize( ((0.983166 - 0.675419)/(0.675419 - 0.57)) * c->GetDummyHist()->GetXaxis()->GetLabelSize() ); - c->GetDummyHist()->GetXaxis()->SetTitleSize( ((0.983166 - 0.675419)/(0.675419 - 0.57)) * c->GetDummyHist()->GetXaxis()->GetTitleSize() ); - c->GetDummyHist()->GetXaxis()->SetLabelOffset(-0.065); - c->GetDummyHist()->GetXaxis()->SetTitleOffset(0.46); - } - - - // increase x-axis size - c->Cd(0); - c->GetDummyHist()->GetXaxis()->SetLabelSize( 0.85 * c->GetDummyHist()->GetXaxis()->GetLabelSize() ); - c->GetDummyHist()->GetXaxis()->SetTitleSize( 0.85 * c->GetDummyHist()->GetXaxis()->GetTitleSize() ); - c->GetDummyHist()->GetXaxis()->SetLabelOffset(0.012); - c->GetDummyHist()->GetXaxis()->SetTitleOffset(1.6); - for(int i=0;i<Nvar;i++){ - c->Cd(i); - c->GetDummyHist()->GetXaxis()->SetLabelSize( 1.2 * c->GetDummyHist()->GetXaxis()->GetLabelSize() ); - c->GetDummyHist()->GetXaxis()->SetTitleSize( 1.2 * c->GetDummyHist()->GetXaxis()->GetTitleSize() ); - } - - - c->Cd(0); - if(ch=="el"){ - ATLASLabel(0.25,0.93,"Work in progress"); - myText(0.25,0.87,1,"#sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - } - if(ch=="mu"){ - ATLASLabel(0.25,0.93,"Work in progress"); - myText(0.25,0.87,1,"#sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - } - - // adapt to your case - // for electrons - if (ch=="el") { - if (jet=="_1j") { - if (bjet=="_0b") - myText(0.65,0.87,1,"e+1 jet, 0 b-jet",0.045); - if (bjet=="_ge1b") - myText(0.65,0.87,1,"e+1 jet, #geq1 b-jet",0.045); - } - if (jet=="") { - if (bjet=="_0b") - myText(0.65,0.87,1,"e+#geq 1 jet, 0 b-jet",0.045); - if (bjet=="_ge1b") - myText(0.65,0.87,1,"e+#geq 1 jet, #geq1 b-jet",0.045); - } - if (jet=="_ge2j") { - if (bjet=="_0b") - myText(0.65,0.87,1,"e+#geq 2 jets, 0 b-jet",0.045); - if (bjet=="_ge1b") - myText(0.65,0.87,1,"e+#geq 2 jets, #geq1 b-jet",0.045); - } - } - // for muons - if (ch=="mu") { - if (jet=="_1j") { - if (bjet=="_0b") - myText(0.65,0.87,1,"#mu+1 jet, 0 b-jet",0.045); - if (bjet=="_ge1b") - myText(0.65,0.87,1,"#mu+1 jet, #geq1 b-jet",0.045); - } - if (jet=="") { - if (bjet=="_0b") - myText(0.65,0.87,1,"#mu+#geq 1 jet, 0 b-jet",0.045); - if (bjet=="_ge1b") - myText(0.65,0.87,1,"#mu+#geq 1 jet, #geq1 b-jet",0.045); - } - if (jet=="_ge2j") { - if (bjet=="_0b") - myText(0.65,0.87,1,"#mu+#geq 2 jets, 0 b-jet",0.045); - if (bjet=="_ge1b") - myText(0.65,0.87,1,"#mu+#geq 2 jets, #geq1 b-jet",0.045); - } - } - - string name; - if(isReal==0) name = "FakeEffComp_"+ch+"_"+var+bjet+jet; - if(isReal==1) name = "RealEffComp_"+ch+"_"+var+bjet+jet; - if(isReal==2) name = "EffComp_"+ch+"_"+var+bjet+jet; - c->SaveAs(("fig/"+name+".png").c_str()); - c->SaveAs(("fig/"+name+".eps").c_str()); - c->SaveAs(("fig/"+name+".pdf").c_str()); - - TFile *fNew = new TFile("Test.root","RECREATE"); - gPad->Write("",TObject::kOverwrite); - -} - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/FakeEffElec.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/FakeEffElec.C deleted file mode 100644 index 522561dcea07..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/FakeEffElec.C +++ /dev/null @@ -1,501 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TGraph.h" -#include "TString.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" -#include <vector> -#include <string> -#include <cmath> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot fake efficiencies vs different variables -// It reads as input the default efficiencies of TopFakes package -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - -void FakeEffElec() -{ - // choice the option you want - in which control region - //int choice = 0; // CR1 - //int choice = 1; // CR1 vs CR2 0 b-tag - //int choice = 2; // CR1 vs CR2 b-tag - //int choice = 3; // CR1 MCup/down 0 b-tag - //int choice = 4; // CR1 MCup/down b-tag - //int choice = 5; // CR1 MC WZ 0 b-tag - //int choice = 6; // CR1 MC WZ b-tag - - // set the variable one want to compare - //int var = 0; // pt - //int var = 1; // eta - //int var = 2; // dR - //int var = 3; // jetpt - //int var = 4; // dphi - //int var = 5; // met - //int var = 6; // mtw - //int var = 7; // njet - //int var = 8; // nbjet - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - gStyle->SetOptTitle(0); - - // define the class - MyEff my(1); - // uncomment if you want to do all plots in one go - for (int choice==0;choice<=6;choice++) - for (int var==0;var<=8;var++) - my.execute(var,choice); - - return; -} - -class MyEff { - -public: - - MyEff(int choice) {} - - // ======================================== - void execute(int var, int choice) - { - TGraph* plot0; - TH1F* plot[10][10]; - TString myname=""; - TString name[100]; - TString mynamehist = ""; - TFile *f[10]; - - // read input files - // CR1 - myname = "..//data/F_el_Default.root"; - f[0] = TFile::Open(myname,"old"); - // CR2 - myname = "../data/F_el_Default_CRfake.root"; - f[1] = TFile::Open(myname,"old"); - // CR1 MCup - myname = "../data/F_el_Default_MCup.root"; - f[2] = TFile::Open(myname,"old"); - // CR1 MCdown - myname = "../data/F_el_Default_MCdown.root"; - f[3] = TFile::Open(myname,"old"); - // CR1 Powheg - myname = "../data/F_el_Default_WZPowheg.root"; - f[4] = TFile::Open(myname,"old"); - // CR1 MadGraph - myname = "../data/F_el_Default_WZMG.root"; - f[5] = TFile::Open(myname,"old"); - - // loop on each files - for (int ifile=0;ifile<=5;ifile++) { - // loop on jet bins - for (int ijet=0;ijet<=3;ijet++) { - // check which variable to be used - if (var==0) mynamehist = "eff_pt"; - if (var==1) mynamehist = "eff_eta"; - if (var==2) mynamehist = "eff_dR"; - if (var==3) mynamehist = "eff_jetpt"; - if (var==4) mynamehist = "eff_dPhi"; - if (var==5) mynamehist = "eff_met"; - if (var==6) mynamehist = "eff_mtw"; - if (var==7) mynamehist = "eff_njet"; - if (var==8) mynamehist = "eff_nbtag"; - - if (var!=7) { - if (ijet==0) mynamehist += "_0b_1j"; - if (ijet==1) mynamehist += "_0b_ge2j"; - if (ijet==2) mynamehist += "_ge1b_1j"; - if (ijet==3) mynamehist += "_ge1b_ge2j"; - } else { - if (ijet==0) mynamehist += "_0b"; - if (ijet==1) mynamehist += "_0b_ge2j"; - if (ijet==2) mynamehist += "_ge1b"; - if (ijet==3) mynamehist += "_ge1b_ge2j"; - } - - std::cout << " ijet = " << ijet - << " namehist = " << mynamehist << std::endl; - plot[ifile][ijet] = (TH1F*)f[ifile]->Get(mynamehist); - //std::cout << " plot = " << plot[ifile][ijet] << std::endl; - } - } - - // =============================================== - // set the TAxis ranges - m_nlines = 2; - m_eff[0] = 0.; - m_eff[1] = 0.8; - if (var==0) {m_var[0] = 25.; m_var[1] = 150.;} // pt - if (var==1) {m_var[0] = 0.; m_var[1] = 2.3;} // eta - if (var==2) {m_var[0] = 0.; m_var[1] = 6.;} // dR - if (var==3) {m_var[0] = 25.; m_var[1] = 500.;} // jetpt - if (var==4) {m_var[0] = 0.; m_var[1] = 3.2;} // dphi - if (var==5) {m_var[0] = 0.; m_var[1] = 1000.;} // met - if (var==6) {m_var[0] = 0.; m_var[1] = 1000.;} // mtw - if (var==7) {m_var[0] = 0.; m_var[1] = 6.;} // njet - if (var==8) {m_var[0] = 0.; m_var[1] = 3.;} // nbjet - plot0 = new TGraph(m_nlines,m_var,m_eff); - - // plot the TGraph - plotGraph(var,choice,plot0,plot); - } - - // ============================================== - void plotGraph(int var,int choice,TGraph* plot0,TH1F* plot[10][10]) - { - // set the TCanvas - c1 = new TCanvas("c1"," ",0.,0.,800,600); - c1->SetFillColor(42); - c1->SetFillColor(10); - - // plot the TAxis - plot0->SetFillColor(19); - plot0->SetLineColor(0); - plot0->SetLineWidth(4); - plot0->SetMarkerColor(0); - plot0->SetMarkerStyle(20); - //plot0->GetXaxis()->CenterLabels(true); - if (var==0) plot0->GetXaxis()->SetTitle("E_{T}(elec) [GeV]"); - if (var==1) plot0->GetXaxis()->SetTitle("|#eta(elec)|"); - if (var==2) plot0->GetXaxis()->SetTitle("#DeltaR (elec, nearest jet)"); - if (var==3) plot0->GetXaxis()->SetTitle("p_{T}(leading jet) [GeV]"); - if (var==4) plot0->GetXaxis()->SetTitle("#Delta#phi (elec,E_{T}^{miss})"); - if (var==5) plot0->GetXaxis()->SetTitle("E_{T}^{miss} [GeV]"); - if (var==6) plot0->GetXaxis()->SetTitle("m_{T}(elec,E_{T}^{miss}) [GeV]"); - if (var==7) plot0->GetXaxis()->SetTitle("n_{jet}"); - if (var==8) plot0->GetXaxis()->SetTitle("n_{b-jet}"); - plot0->GetYaxis()->SetTitle("Efficiency"); - plot0->Draw("AP"); - - // ================================================================ - // plot the TGraph - if (choice==0) { // CR1 - myplot(plot[0][0],1,20); - if (var!=7) myplot(plot[0][1],2,21); // case for njet - myplot(plot[0][2],3,24); - if (var!=7) myplot(plot[0][3],4,25); // case for njet - - if (var==8) { // case for nbjet (use same colors) - myplot(plot[0][0],1,20); - myplot(plot[0][1],3,24); - myplot(plot[0][2],1,20); - myplot(plot[0][3],3,24); - } - } - if (choice==1) { // CR1 vs CR2 0 btag - myplot(plot[0][0],1,20); // 1j 0b - myplot(plot[1][0],1,24); - myplot(plot[0][1],2,21); // ge2j 0b - myplot(plot[1][1],2,25); - } - if (choice==2) { //CR1 vs CR2 btag - myplot(plot[0][2],1,20); // 1j ge1b - myplot(plot[1][2],1,24); - myplot(plot[0][3],2,21); // ge2j ge1b - myplot(plot[1][3],2,25); - } - if (choice==3) { // CR1 MCup/down 0 btag - myplot(plot[0][0],1,20); // 1j 0b - myplot(plot[2][0],1,21); - myplot(plot[3][0],1,22); - - myplot(plot[0][1],2,24); // ge2j 0b - myplot(plot[2][1],2,25); - myplot(plot[3][1],2,26); - } - if (choice==4) { // CR1 MCup/down btag - myplot(plot[0][2],1,20); // 1j b - myplot(plot[2][2],1,21); - myplot(plot[3][2],1,22); - - myplot(plot[0][3],2,24); // ge2j b - myplot(plot[2][3],2,25); - myplot(plot[3][3],2,26); - } - if (choice==5) { // CR1 MC WZ 0 btag - myplot(plot[0][0],1,20); // 1j 0b - myplot(plot[4][0],1,21); - myplot(plot[5][0],1,22); - - myplot(plot[0][1],2,24); // ge2j 0b - myplot(plot[4][1],2,25); - myplot(plot[5][1],2,26); - } - if (choice==6) { // CR1 MC WZ btag - myplot(plot[0][2],1,20); // 1j b - myplot(plot[4][2],1,21); - myplot(plot[5][2],1,22); - - myplot(plot[0][3],2,24); // ge2j b - myplot(plot[4][3],2,25); - myplot(plot[5][3],2,26); - } - - c1->Update(); - c1->GetFrame()->SetFillColor(0); - c1->GetFrame()->SetBorderSize(0); - c1->Modified(); - // plot the TLegend - plotLegend(var,choice,plot); - c1->RedrawAxis(); - - // plot the output names - TString suffix = ""; - if (var==0) suffix = "_vsEt"; - if (var==1) suffix = "_vsEta"; - if (var==2) suffix = "_vsdR"; - if (var==3) suffix = "_vsPtLeadingJet"; - if (var==4) suffix = "_vsdPhi"; - if (var==5) suffix = "_vsMET"; - if (var==6) suffix = "_vsMTW"; - if (var==7) suffix = "_vsnjet"; - if (var==8) suffix = "_vsnbjet"; - - TString format = ""; - for (int i=0;i<3;i++) { - if (i==0) format = ".eps"; - if (i==1) format = ".pdf"; - if (i==2) format = ".png"; - - if (choice==0) // CR1 - c1->SaveAs("fig/efffake_elec"+suffix+format); - if (choice==1) // CR1 vs CR2 0 btag - c1->SaveAs("fig/efffake_elec_CR12_0btag"+suffix+format); - if (choice==2) // CR1 vs CR2 ge1 btag - c1->SaveAs("fig/efffake_elec_CR12_btag"+suffix+format); - if (choice==3) // CR1 MCup/down 0 btag - c1->SaveAs("fig/efffake_elec_CR1_MCUpDown_0btag"+suffix+format); - if (choice==4) // CR1 MCup/down ge1 btag - c1->SaveAs("fig/efffake_elec_CR1_MCUpDown_btag"+suffix+format); - if (choice==5) // CR1 MC WZ 0 btag - c1->SaveAs("fig/efffake_elec_CR1_MCWZ_0btag"+suffix+format); - if (choice==6) // CR1 MC WZ ge1 btag - c1->SaveAs("fig/efffake_elec_CR1_MCWZ_btag"+suffix+format); - } - } - - // ============================================== - void myplot(TH1F* plot,int mkcolor, int mktype, float size=1.5) - { - plot->SetFillColor(19); - plot->SetLineColor(1); - plot->SetLineWidth(1.5); - plot->SetMarkerColor(mkcolor); - plot->SetMarkerStyle(mktype); - //plot->SetTitle("rel 16"); - plot->SetMarkerSize(size); - plot->Draw("P sames"); - } - - // ============================================== - void plotLegend(int var,int choice,TH1F* plot[10][10]) - { - float xlabel = 0.2; - float ylabel = 0.88; - // set the ATLAS label - ATLASLabel(xlabel,ylabel,"Work in Progress"); - // set energy and luminosity (adapt to your own case) - myText(xlabel+0.1,ylabel-0.06,1,"e+jets, #sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - - // ============================================================ - // set the TLegend (adapt to your own team) - if (choice==0) { - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (var!=7 && var!=8) { - leg->AddEntry(plot[0][0],"#epsilon_{f} CR_{1}, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[0][1],"#epsilon_{f} CR_{1}, #geq2 jets, 0 btag","ep"); - leg->AddEntry(plot[0][2],"#epsilon_{f} CR_{1}, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[0][3],"#epsilon_{f} CR_{1}, #geq2 jets, #geq1 btag","ep"); - } else if (var==7) { // case for njet - leg->AddEntry(plot[0][0],"#epsilon_{f} CR_{1} 0 btag","ep"); - leg->AddEntry(plot[0][2],"#epsilon_{f} CR_{1} #geq1 btag","ep"); - } else if (var==8) { // case for nbjet - leg->AddEntry(plot[0][0],"#epsilon_{f} CR_{1}, 1 jet","ep"); - leg->AddEntry(plot[0][1],"#epsilon_{f} CR_{1}, #geq2 jets","ep"); - } - leg->Draw(); - } - - // ============================= - if (choice==1) { // for comparison CR1 CR2 - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - leg->AddEntry(plot[0][0],"#epsilon_{f} CR_{1}, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[1][0],"#epsilon_{f} CR_{2}, 1 jet, 0 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.5,ymin2,0.6,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.04); - leg2->AddEntry(plot[0][1],"#epsilon_{f} CR_{1}, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[1][1],"#epsilon_{f} CR_{2}, #geq2 jets, 0 btag","ep"); - leg2->Draw(); - } - - // ============================= - if (choice==2) { // for comparison CR1 CR2 - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - leg->AddEntry(plot[0][2],"#epsilon_{f} CR_{1}, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[1][2],"#epsilon_{f} CR_{2}, 1 jet, #geq1 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.5,ymin2,0.6,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.04); - leg2->AddEntry(plot[0][3],"#epsilon_{f} CR_{1}, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[1][3],"#epsilon_{f} CR_{2}, #geq2 jets, #geq1 btag","ep"); - leg2->Draw(); - } - // ============================= - if (choice==3) { // for comparison CR1 MCup/down 0 btag - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.035); - leg->AddEntry(plot[0][0],"#epsilon_{f} CR_{1}, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[2][0],"#epsilon_{f} CR_{1} MCup, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[3][0],"#epsilon_{f} CR_{1} MCdown, 1 jet, 0 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.58,ymin2,0.68,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.035); - leg2->AddEntry(plot[0][1],"#epsilon_{f} CR_{1}, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[2][1],"#epsilon_{f} CR_{1} MCup, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[3][1],"#epsilon_{f} CR_{1} down, #geq2 jets, 0 btag","ep"); - leg2->Draw(); - } - - // ============================= - if (choice==4) { // for comparison CR1 MCup/down >=1 btag - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.035); - leg->AddEntry(plot[0][2],"#epsilon_{f} CR_{1}, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[2][2],"#epsilon_{f} CR_{1} MCup, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[3][2],"#epsilon_{f} CR_{1} MCdown, 1 jet, #geq1 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.58,ymin2,0.68,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.035); - leg2->AddEntry(plot[0][3],"#epsilon_{f} CR_{1}, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[2][3],"#epsilon_{f} CR_{1} MCup, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[3][3],"#epsilon_{f} CR_{1} down, #geq2 jets, #geq1 btag","ep"); - leg2->Draw(); - } - // ============================= - if (choice==5) { // for comparison CR1 MC WZ 0 btag - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.03); - leg->AddEntry(plot[0][0],"#epsilon_{f} CR_{1} Sherpa, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[4][0],"#epsilon_{f} CR_{1} Powheg, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[5][0],"#epsilon_{f} CR_{1} MadGraph, 1 jet, 0 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.58,ymin2,0.68,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.03); - leg2->AddEntry(plot[0][1],"#epsilon_{f} CR_{1} Sherpa, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[4][1],"#epsilon_{f} CR_{1} Powheg, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[5][1],"#epsilon_{f} CR_{1} MadGraph, #geq2 jets, 0 btag","ep"); - leg2->Draw(); - } - - // ============================= - if (choice==6) { // for comparison CR1 MC WZ >=1 btag - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.03); - leg->AddEntry(plot[0][2],"#epsilon_{f} CR_{1} Sherpa, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[4][2],"#epsilon_{f} CR_{1} Powheg, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[5][2],"#epsilon_{f} CR_{1} MadGraph, 1 jet, #geq1 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.58,ymin2,0.68,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.03); - leg2->AddEntry(plot[0][3],"#epsilon_{f} CR_{1} Sherpa, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[4][3],"#epsilon_{f} CR_{1} Powheg, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[5][3],"#epsilon_{f} CR_{1} MadGraph, #geq2 jets, #geq1 btag","ep"); - leg2->Draw(); - } - - } - -private: - - Float_t m_var[300]; - Float_t m_errvar[300]; - Float_t m_eff[300]; - Float_t m_erreff[300]; - - Int_t m_nlines; -}; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/FakeEffMuon.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/FakeEffMuon.C deleted file mode 100644 index eb279ab2ad20..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/FakeEffMuon.C +++ /dev/null @@ -1,564 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TGraph.h" -#include "TString.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" -#include <vector> -#include <string> -#include <cmath> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot fake efficiencies vs different variables -// It reads as input the default efficiencies of TopFakes package -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - -void FakeEffMuon() -{ - // use these options to choose the control region - //int choice = 0; // CR1 - //int choice = 1; // CR1 vs CR2 0 b-tag - //int choice = 2; // CR1 vs CR2 b-tag - //int choice = 3; // CR1 MCup/down 0 b-tag - //int choice = 4; // CR1 MCup/down b-tag - //int choice = 5; // CR1 MC WZ 0 b-tag - //int choice = 6; // CR1 MC WZ b-tag - - // choose the trigger - //int trigger = 0; // mu20i - //int trigger = 1; // mu20 - //int trigger = 2; // mu50 - - // set the variable one want to compare - //int var = 0; // pt - //int var = 1; // eta - //int var = 2; // dR - //int var = 3; // jetpt - //int var = 4; // dphi - //int var = 5; // met - //int var = 6; // mtw - //int var = 7; // njet - //int var = 8; // nbjet - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - gStyle->SetOptTitle(0); - - // define the class - MyEff my(1); - // uncomment if you want to do all plots in one go - for (int choice=0;choice<=1;choice++) - for (int trigger=0;trigger<=2;trigger++) - for (int var=0;var<=8;var++) - my.execute(var,choice,trigger); - - return; -} - -class MyEff { - -public: - - MyEff(int choice) {} - - // ======================================== - void execute(int var, int choice, int trigger) - { - TGraph* plot0; - TH1F* plot[10][20]; - TString myname=""; - TString name[100]; - TString mynamehist = ""; - TFile *f[10]; - - // read the input files - // CR1 - myname = "../data/F_mu_Default.root"; - f[0] = TFile::Open(myname,"old"); - // CR2 - myname = "../data/F_mu_Default_CRfake.root"; - f[1] = TFile::Open(myname,"old"); - // CR1 MCup - myname = "../data/F_mu_Default_MCup.root"; - f[2] = TFile::Open(myname,"old"); - // CR1 MCdown - myname = "../data/F_mu_Default_MCdown.root"; - f[3] = TFile::Open(myname,"old"); - // CR1 Powheg - myname = "../data/F_mu_Default_WZPowheg.root"; - f[4] = TFile::Open(myname,"old"); - // CR1 MadGraph - myname = "../data/F_mu_Default_WZMG.root"; - f[5] = TFile::Open(myname,"old"); - - // loop on each files - for (int ifile=0;ifile<=5;ifile++) { - // loop on all jet possibilities - for (int ijet=0;ijet<=11;ijet++) { - // check which variable to use - if (var==0) mynamehist = "eff_pt"; - if (var==1) mynamehist = "eff_eta"; - if (var==2) mynamehist = "eff_dR"; - if (var==3) mynamehist = "eff_jetpt"; - if (var==4) mynamehist = "eff_dPhi"; - if (var==5) mynamehist = "eff_met"; - if (var==6) mynamehist = "eff_mtw"; - if (var==7) mynamehist = "eff_njet"; - if (var==8) mynamehist = "eff_nbtag"; - - if (var<7) { - // mu20i - if (ijet==0) mynamehist += "_0b_1j_mu20i"; - if (ijet==1) mynamehist += "_0b_ge2j_mu20i"; - if (ijet==2) mynamehist += "_ge1b_1j_mu20i"; - if (ijet==3) mynamehist += "_ge1b_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_1j_mu20"; - if (ijet==5) mynamehist += "_0b_ge2j_mu20"; - if (ijet==6) mynamehist += "_ge1b_1j_mu20"; - if (ijet==7) mynamehist += "_ge1b_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_1j_mu50"; - if (ijet==9) mynamehist += "_0b_ge2j_mu50"; - if (ijet==10) mynamehist += "_ge1b_1j_mu50"; - if (ijet==11) mynamehist += "_ge1b_ge2j_mu50"; - } else if (var==7) { // njet - // mu20i - if (ijet==0) mynamehist += "_0b_mu20i"; - if (ijet==1) mynamehist += "_0b_ge2j_mu20i"; - if (ijet==2) mynamehist += "_ge1b_mu20i"; - if (ijet==3) mynamehist += "_ge1b_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_mu20"; - if (ijet==5) mynamehist += "_0b_ge2j_mu20"; - if (ijet==6) mynamehist += "_ge1b_mu20"; - if (ijet==7) mynamehist += "_ge1b_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_mu50"; - if (ijet==9) mynamehist += "_0b_ge2j_mu50"; - if (ijet==10) mynamehist += "_ge1b_mu50"; - if (ijet==11) mynamehist += "_ge1b_ge2j_mu50"; - } else if (var==8) { // nbjet - // mu20i - if (ijet==0) mynamehist += "_0b_1j_mu20i"; - if (ijet==1) mynamehist += "_0b_ge2j_mu20i"; - if (ijet==2) mynamehist += "_ge1b_1j_mu20i"; - if (ijet==3) mynamehist += "_ge1b_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_1j_mu20"; - if (ijet==5) mynamehist += "_0b_ge2j_mu20"; - if (ijet==6) mynamehist += "_ge1b_1j_mu20"; - if (ijet==7) mynamehist += "_ge1b_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_1j_mu50"; - if (ijet==9) mynamehist += "_0b_ge2j_mu50"; - if (ijet==10) mynamehist += "_ge1b_1j_mu50"; - if (ijet==11) mynamehist += "_ge1b_ge2j_mu50"; - } - - std::cout << " ijet = " << ijet - << " namehist = " << mynamehist << std::endl; - plot[ifile][ijet] = (TH1F*)f[ifile]->Get(mynamehist); - //std::cout << " plot = " << plot[ifile][ijet] << std::endl; - } - } - - // =============================================== - // set the TAxis ranges - m_nlines = 2; - m_eff[0] = 0.; - m_eff[1] = 1.4; - if (var==0) {m_var[0] = 25.; m_var[1] = 150.;} // pt - if (var==1) {m_var[0] = 0.; m_var[1] = 2.3;} // eta - if (var==2) {m_var[0] = 0.; m_var[1] = 6.;} // dR - if (var==3) {m_var[0] = 25.; m_var[1] = 500.;} // jetpt - if (var==4) {m_var[0] = 0.; m_var[1] = 3.2;} // dphi - if (var==5) {m_var[0] = 0.; m_var[1] = 1000.;} // met - if (var==6) {m_var[0] = 0.; m_var[1] = 1000.;} // mtw - if (var==7) {m_var[0] = 0.; m_var[1] = 6.;} // njet - if (var==8) {m_var[0] = 0.; m_var[1] = 3.;} // nbjet - plot0 = new TGraph(m_nlines,m_var,m_eff); - - // plot the TGraph - plotGraph(var,choice,trigger,plot0,plot); - } - - // ============================================== - void plotGraph(int var,int choice,int trigger, - TGraph* plot0,TH1F* plot[10][20]) - { - // set the TCanvas - c1 = new TCanvas("c1"," ",0.,0.,800,600); - c1->SetFillColor(42); - c1->SetFillColor(10); - - // plot the TAxis - plot0->SetFillColor(19); - plot0->SetLineColor(0); - plot0->SetLineWidth(4); - plot0->SetMarkerColor(0); - plot0->SetMarkerStyle(20); - //plot0->GetXaxis()->CenterLabels(true); - if (var==0) plot0->GetXaxis()->SetTitle("p_{T}(#mu) [GeV]"); - if (var==1) plot0->GetXaxis()->SetTitle("|#eta(#mu)|"); - if (var==2) plot0->GetXaxis()->SetTitle("#DeltaR (#mu, nearest jet)"); - if (var==3) plot0->GetXaxis()->SetTitle("p_{T}(leading jet) [GeV]"); - if (var==4) plot0->GetXaxis()->SetTitle("#Delta#phi (#mu,E_{T}^{miss})"); - if (var==5) plot0->GetXaxis()->SetTitle("E_{T}^{miss} [GeV]"); - if (var==6) plot0->GetXaxis()->SetTitle("m_{T}(#mu,E_{T}^{miss}) [GeV]"); - if (var==7) plot0->GetXaxis()->SetTitle("n_{jet}"); - if (var==8) plot0->GetXaxis()->SetTitle("n_{b-jet}"); - plot0->GetYaxis()->SetTitle("Efficiency"); - plot0->Draw("AP"); - - // ================================================================ - // choose the trigger - int it1 = -1; int it2 = -1; int it3 = -1; int it4 = -1; - if (trigger==0) {it1 = 0; it2 = 1; it3 = 2; it4 = 3;} // mu20i - if (trigger==1) {it1 = 4; it2 = 5; it3 = 6; it4 = 7;} // mu20 - if (trigger==2) {it1 = 8; it2 = 9; it3 = 10; it4 = 11;} // mu50 - - if (choice==0) { // CR1 - myplot(plot[0][it1],1,20); - if (var!=7) myplot(plot[0][it2],2,21); // case for njet - myplot(plot[0][it3],3,24); - if (var!=7) myplot(plot[0][it4],4,25); // case for njet - - if (var==8) { // case for nbjet (use same colors) - myplot(plot[0][it1],1,20); - myplot(plot[0][it2],3,24); - myplot(plot[0][it3],1,20); - myplot(plot[0][it4],3,24); - } - } - if (choice==1) { // CR1 vs CR2 0 btag - myplot(plot[0][it1],1,20); // 1j 0b - myplot(plot[1][it1],1,24); - myplot(plot[0][it2],2,21); // ge2j 0b - myplot(plot[1][it2],2,25); - } - if (choice==2) { //CR1 vs CR2 btag - myplot(plot[0][it3],1,20); // 1j ge1b - myplot(plot[1][it3],1,24); - myplot(plot[0][it4],2,21); // ge2j ge1b - myplot(plot[1][it4],2,25); - } - if (choice==3) { // CR1 MCup/down 0 btag - myplot(plot[0][it1],1,20); // 1j 0b - myplot(plot[2][it1],1,21); - myplot(plot[3][it1],1,22); - - myplot(plot[0][it2],2,24); // ge2j 0b - myplot(plot[2][it2],2,25); - myplot(plot[3][it2],2,26); - } - if (choice==4) { // CR1 MCup/down btag - myplot(plot[0][it3],1,20); // 1j b - myplot(plot[2][it3],1,21); - myplot(plot[3][it3],1,22); - - myplot(plot[0][it4],2,24); // ge2j b - myplot(plot[2][it4],2,25); - myplot(plot[3][it4],2,26); - } - if (choice==5) { // CR1 MC WZ 0 btag - myplot(plot[0][it1],1,20); // 1j 0b - myplot(plot[4][it1],1,21); - myplot(plot[5][it1],1,22); - - myplot(plot[0][it2],2,24); // ge2j 0b - myplot(plot[4][it2],2,25); - myplot(plot[5][it2],2,26); - } - if (choice==6) { // CR1 MC WZ btag - myplot(plot[0][it3],1,20); // 1j b - myplot(plot[4][it3],1,21); - myplot(plot[5][it3],1,22); - - myplot(plot[0][it4],2,24); // ge2j b - myplot(plot[4][it4],2,25); - myplot(plot[5][it4],2,26); - } - c1->Update(); - c1->GetFrame()->SetFillColor(0); - c1->GetFrame()->SetBorderSize(0); - c1->Modified(); - // plot the TLegend - plotLegend(var,choice,trigger,plot); - c1->RedrawAxis(); - - // set the output names - TString suffix = ""; - if (var==0) suffix = "_vsPt"; - if (var==1) suffix = "_vsEta"; - if (var==2) suffix = "_vsdR"; - if (var==3) suffix = "_vsPtLeadingJet"; - if (var==4) suffix = "_vsdPhi"; - if (var==5) suffix = "_vsMET"; - if (var==6) suffix = "_vsMTW"; - if (var==7) suffix = "_vsnjet"; - if (var==8) suffix = "_vsnbjet"; - - TString st = ""; - if (trigger==0) st = "_mu20i"; - if (trigger==1) st = "_mu20"; - if (trigger==2) st = "_mu50"; - - TString format = ""; - for (int i=0;i<3;i++) { - if (i==0) format = ".eps"; - if (i==1) format = ".pdf"; - if (i==2) format = ".png"; - - if (choice==0) // CR1 - c1->SaveAs("fig/efffake_muon"+st+suffix+format); - if (choice==1) // CR1 vs CR2 0 btag - c1->SaveAs("fig/efffake_muon"+st+"_CR12_0btag"+suffix+format); - if (choice==2) // CR1 vs CR2 ge1 btag - c1->SaveAs("fig/efffake_muon"+st+"_CR12_btag"+suffix+format); - if (choice==3) // CR1 MCup/down 0 btag - c1->SaveAs("fig/efffake_muon"+st+"_CR1_MCUpDown_0btag"+suffix+format); - if (choice==4) // CR1 MCup/down ge1 btag - c1->SaveAs("fig/efffake_muon"+st+"_CR1_MCUpDown_btag"+suffix+format); - if (choice==5) // CR1 MC WZ 0 btag - c1->SaveAs("fig/efffake_muon"+st+"_CR1_MCWZ_0btag"+suffix+format); - if (choice==6) // CR1 MC WZ ge1 btag - c1->SaveAs("fig/efffake_muon"+st+"_CR1_MCWZ_btag"+suffix+format); - } - } - - // ============================================== - void myplot(TH1F* plot,int mkcolor, int mktype, float size=1.5) - { - plot->SetFillColor(19); - plot->SetLineColor(1); - plot->SetLineWidth(1.5); - plot->SetMarkerColor(mkcolor); - plot->SetMarkerStyle(mktype); - //plot->SetTitle("rel 16"); - plot->SetMarkerSize(size); - plot->Draw("P sames"); - } - - // ============================================== - void plotLegend(int var,int choice,int trigger,TH1F* plot[10][20]) - { - float xlabel = 0.2; - float ylabel = 0.88; - // set the ATLAS label - ATLASLabel(xlabel,ylabel,"Work in Progress"); - // set energy and luminosity (adapt to your own case) - myText(xlabel+0.2,ylabel-0.06,1,"#sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - - if (trigger==0) myText(xlabel,ylabel-0.06,1,"#mu+jets mu20i",0.04); - if (trigger==1) myText(xlabel,ylabel-0.06,1,"#mu+jets mu20",0.04); - if (trigger==2) myText(xlabel,ylabel-0.06,1,"#mu+jets mu50",0.04); - - int it1 = -1; int it2 = -1; int it3 = -1; int it4 = -1; - if (trigger==0) {it1 = 0; it2 = 1; it3 = 2; it4 = 3;} // mu20i - if (trigger==1) {it1 = 4; it2 = 5; it3 = 6; it4 = 7;} // mu20 - if (trigger==2) {it1 = 8; it2 = 9; it3 = 10; it4 = 11;} // mu50 - - // ============================================================ - // set the TLegend (adapt to your own team) - if (choice==0) { - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (var!=7 && var!=8) { - leg->AddEntry(plot[0][it1],"#epsilon_{f} CR_{1}, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[0][it2],"#epsilon_{f} CR_{1}, #geq2 jets, 0 btag","ep"); - leg->AddEntry(plot[0][it3],"#epsilon_{f} CR_{1}, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[0][it4],"#epsilon_{f} CR_{1}, #geq2 jets, #geq1 btag","ep"); - } else if (var==7) { // case for njet - leg->AddEntry(plot[0][it1],"#epsilon_{f} CR_{1} 0 btag","ep"); - leg->AddEntry(plot[0][it3],"#epsilon_{f} CR_{1} #geq1 btag","ep"); - } else if (var==8) { // case for nbjet - leg->AddEntry(plot[0][it1],"#epsilon_{f} CR_{1}, 1 jet","ep"); - leg->AddEntry(plot[0][it2],"#epsilon_{f} CR_{1}, #geq2 jets","ep"); - } - leg->Draw(); - } - - // ============================= - if (choice==1) { // for comparison CR1 CR2 - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - leg->AddEntry(plot[0][it1],"#epsilon_{f} CR_{1}, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[1][it1],"#epsilon_{f} CR_{2}, 1 jet, 0 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.5,ymin2,0.6,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.04); - leg2->AddEntry(plot[0][it2],"#epsilon_{f} CR_{1}, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[1][it2],"#epsilon_{f} CR_{2}, #geq2 jets, 0 btag","ep"); - leg2->Draw(); - } - - // ============================= - if (choice==2) { // for comparison CR1 CR2 - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - leg->AddEntry(plot[0][it3],"#epsilon_{f} CR_{1}, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[1][it3],"#epsilon_{f} CR_{2}, 1 jet, #geq1 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.5,ymin2,0.6,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.04); - leg2->AddEntry(plot[0][it4],"#epsilon_{f} CR_{1}, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[1][it4],"#epsilon_{f} CR_{2}, #geq2 jets, #geq1 btag","ep"); - leg2->Draw(); - } - // ============================= - if (choice==3) { // for comparison CR1 MCup/down 0 btag - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.035); - leg->AddEntry(plot[0][it1],"#epsilon_{f} CR_{1}, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[2][it1],"#epsilon_{f} CR_{1} MCup, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[3][it1],"#epsilon_{f} CR_{1} MCdown, 1 jet, 0 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.58,ymin2,0.68,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.035); - leg2->AddEntry(plot[0][it2],"#epsilon_{f} CR_{1}, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[2][it2],"#epsilon_{f} CR_{1} MCup, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[3][it2],"#epsilon_{f} CR_{1} down, #geq2 jets, 0 btag","ep"); - leg2->Draw(); - } - - // ============================= - if (choice==4) { // for comparison CR1 MCup/down >=1 btag - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.035); - leg->AddEntry(plot[0][it3],"#epsilon_{f} CR_{1}, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[2][it3],"#epsilon_{f} CR_{1} MCup, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[3][it3],"#epsilon_{f} CR_{1} MCdown, 1 jet, #geq1 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.58,ymin2,0.68,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.035); - leg2->AddEntry(plot[0][it4],"#epsilon_{f} CR_{1}, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[2][it4],"#epsilon_{f} CR_{1} MCup, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[3][it4],"#epsilon_{f} CR_{1} down, #geq2 jets, #geq1 btag","ep"); - leg2->Draw(); - } - // ============================= - if (choice==5) { // for comparison CR1 MC WZ 0 btag - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.03); - leg->AddEntry(plot[0][it1],"#epsilon_{f} CR_{1} Sherpa, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[4][it1],"#epsilon_{f} CR_{1} Powheg, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[5][it1],"#epsilon_{f} CR_{1} MadGraph, 1 jet, 0 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.58,ymin2,0.68,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.03); - leg2->AddEntry(plot[0][it2],"#epsilon_{f} CR_{1} Sherpa, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[4][it2],"#epsilon_{f} CR_{1} Powheg, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[5][it2],"#epsilon_{f} CR_{1} MadGraph, #geq2 jets, 0 btag","ep"); - leg2->Draw(); - } - - // ============================= - if (choice==6) { // for comparison CR1 MC WZ >=1 btag - float ymin = 0.65; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.03); - leg->AddEntry(plot[0][it3],"#epsilon_{f} CR_{1} Sherpa, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[4][it3],"#epsilon_{f} CR_{1} Powheg, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[5][it3],"#epsilon_{f} CR_{1} MadGraph, 1 jet, #geq1 btag","ep"); - leg->Draw(); - - float ymin2 = 0.65; - float ymax2 = 0.8; - leg2 = new TLegend(0.58,ymin2,0.68,ymax2); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.03); - leg2->AddEntry(plot[0][it4],"#epsilon_{f} CR_{1} Sherpa, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[4][it4],"#epsilon_{f} CR_{1} Powheg, #geq2 jets, #geq1 btag","ep"); - leg2->AddEntry(plot[5][it4],"#epsilon_{f} CR_{1} MadGraph, #geq2 jets, #geq1 btag","ep"); - leg2->Draw(); - } - - } - -private: - - Float_t m_var[300]; - Float_t m_errvar[300]; - Float_t m_eff[300]; - Float_t m_erreff[300]; - - Int_t m_nlines; -}; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecHighEtmiss.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecHighEtmiss.C deleted file mode 100644 index 068c17103850..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecHighEtmiss.C +++ /dev/null @@ -1,281 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TGraph.h" -#include "TString.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" -#include <vector> -#include <string> -#include <cmath> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot real efficiencies obtained from high-MET/MTW -// method vs different variables -// It reads as input the default efficiencies of TopFakes package -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - -void RealEffElecHighEtmiss() -{ - // use this option to see results with different njet bins - //int choice = 0; - // use this option to see results with njet>=1 only - //int choice = 1; - - // set the variable one want to compare - //int var = 0; // pt - //int var = 1; // eta - //int var = 2; // dR - //int var = 3; // jetpt - //int var = 4; // dphi - //int var = 5; // met - //int var = 6; // mtw - //int var = 7; // njet - //int var = 8; // nbjet - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - gStyle->SetOptTitle(0); - - // define the class - MyEff my(1); - // uncomment if you want to do all plots in one go - for (int choice=0;choice<=1;choice++) - for (int var=0;var<=8;var++) - my.execute(var,choice); - - return; -} - -class MyEff { - -public: - - MyEff(int choice) {} - - // ======================================== - void execute(int var, int choice) - { - TGraph* plot0; - TH1F* plot[10]; - TString myname=""; - TString name[100]; - TString mynamehist = ""; - TFile *f; - - // loop on input files - myname = "../data/R_el_Default_CRreal.root"; - std::cout << " myname = " << myname << std::endl; - f = TFile::Open(myname,"old"); - - // loop on jet bins - for (int ijet=0;ijet<=3;ijet++) { - // check which variable is read - if (var==0) mynamehist = "eff_pt"; - if (var==1) mynamehist = "eff_eta"; - if (var==2) mynamehist = "eff_dR"; - if (var==3) mynamehist = "eff_jetpt"; - if (var==4) mynamehist = "eff_dPhi"; - if (var==5) mynamehist = "eff_met"; - if (var==6) mynamehist = "eff_mtw"; - if (var==7) mynamehist = "eff_njet"; - if (var==8) mynamehist = "eff_nbtag"; - - if (choice==0) { // with details on njet - if (var!=7) { // for all variables except njet - if (ijet==0) mynamehist += "_0b_1j"; - if (ijet==1) mynamehist += "_0b_ge2j"; - if (ijet==2) mynamehist += "_ge1b_1j"; - if (ijet==3) mynamehist += "_ge1b_ge2j"; - } else { // for njet - if (ijet==0) mynamehist += "_0b"; - if (ijet==1) mynamehist += "_0b_ge2j"; - if (ijet==2) mynamehist += "_ge1b"; - if (ijet==3) mynamehist += "_ge1b_ge2j"; - } - } else { // with ony njet>=1 - if (var!=7) { // for all variables except njet - if (ijet==0) mynamehist += ""; - if (ijet==1) mynamehist += ""; - if (ijet==2) mynamehist += ""; - if (ijet==3) mynamehist += ""; - } else { // for njet - if (ijet==0) mynamehist += ""; - if (ijet==1) mynamehist += ""; - if (ijet==2) mynamehist += ""; - if (ijet==3) mynamehist += ""; - } - } - std::cout << " ijet = " << ijet - << " namehist = " << mynamehist << std::endl; - plot[ijet] = (TH1F*)f->Get(mynamehist); - //std::cout << " plot = " << plot[ijet] << std::endl; - } - - // =============================================== - // define TAxis ranges - m_nlines = 2; - m_eff[0] = 0.75; - m_eff[1] = 1.1; - if (var==0) {m_var[0] = 25.; m_var[1] = 150.;} // pt - if (var==1) {m_var[0] = 0.; m_var[1] = 2.3;} // eta - if (var==2) {m_var[0] = 0.; m_var[1] = 6.;} // dR - if (var==3) {m_var[0] = 25.; m_var[1] = 500.;} // jetpt - if (var==4) {m_var[0] = 0.; m_var[1] = 3.2;} // dphi - if (var==5) {m_var[0] = 0.; m_var[1] = 1000.;} // met - if (var==6) {m_var[0] = 0.; m_var[1] = 1000.;} // mtw - if (var==7) {m_var[0] = 0.; m_var[1] = 6.;} // njet - if (var==8) {m_var[0] = 0.; m_var[1] = 3.;} // nbjet - plot0 = new TGraph(m_nlines,m_var,m_eff); - - // plot the TGraph - plotGraph(var,choice,plot0,plot); - } - - // ============================================== - void plotGraph(int var,int choice,TGraph* plot0,TH1F* plot[10]) - { - // set the TCanvas - c1 = new TCanvas("c1"," ",0.,0.,800,600); - c1->SetFillColor(42); - c1->SetFillColor(10); - - // plot the TAxis - plot0->SetFillColor(19); - plot0->SetLineColor(0); - plot0->SetLineWidth(4); - plot0->SetMarkerColor(0); - plot0->SetMarkerStyle(20); - //plot0->GetXaxis()->CenterLabels(true); - if (var==0) plot0->GetXaxis()->SetTitle("E_{T}(elec) [GeV]"); - if (var==1) plot0->GetXaxis()->SetTitle("|#eta(elec)|"); - if (var==2) plot0->GetXaxis()->SetTitle("#DeltaR (elec, nearest jet)"); - if (var==3) plot0->GetXaxis()->SetTitle("p_{T}(leading jet) [GeV]"); - if (var==4) plot0->GetXaxis()->SetTitle("#Delta#phi (elec,E_{T}^{miss})"); - if (var==5) plot0->GetXaxis()->SetTitle("E_{T}^{miss} [GeV]"); - if (var==6) plot0->GetXaxis()->SetTitle("m_{T}(elec,E_{T}^{miss}) [GeV]"); - if (var==7) plot0->GetXaxis()->SetTitle("n_{jet}"); - if (var==8) plot0->GetXaxis()->SetTitle("n_{b-jet}"); - plot0->GetYaxis()->SetTitle("Efficiency"); - plot0->Draw("AP"); - - // ================================================================ - // plot the TGraph - if (choice==0) { // with details on njet - myplot(plot[0],1,20); - if (var!=7) myplot(plot[1],2,21); // case for njet - myplot(plot[2],3,24); - if (var!=7) myplot(plot[3],4,25); // case for njet - - if (var==8) { // case for nbjet (use same colors) - myplot(plot[0],1,20); - myplot(plot[1],3,24); - myplot(plot[2],1,20); - myplot(plot[3],3,24); - } - } else { // only njet>=1 - myplot(plot[0],1,20); - } - - - c1->Update(); - c1->GetFrame()->SetFillColor(0); - c1->GetFrame()->SetBorderSize(0); - c1->Modified(); - // plot the TLegend - plotLegend(var,choice,plot); - c1->RedrawAxis(); - - // define the output name - TString suffix = ""; - if (var==0) suffix = "_vsEt"; - if (var==1) suffix = "_vsEta"; - if (var==2) suffix = "_vsdR"; - if (var==3) suffix = "_vsPtLeadingJet"; - if (var==4) suffix = "_vsdPhi"; - if (var==5) suffix = "_vsMET"; - if (var==6) suffix = "_vsMTW"; - if (var==7) suffix = "_vsnjet"; - if (var==8) suffix = "_vsnbjet"; - TString format = ""; - for (int i=0;i<3;i++) { - if (i==0) format = ".eps"; - if (i==1) format = ".pdf"; - if (i==2) format = ".png"; - if (choice==0) - c1->SaveAs("fig/effrealHighMET_elec"+suffix+format); - else - c1->SaveAs("fig/effrealHighMET_elec_ge1j"+suffix+format); - } - } - - // ============================================== - void myplot(TH1F* plot,int mkcolor, int mktype, float size=1.5) - { - plot->SetFillColor(19); - plot->SetLineColor(1); - plot->SetLineWidth(1.5); - plot->SetMarkerColor(mkcolor); - plot->SetMarkerStyle(mktype); - //plot->SetTitle("rel 16"); - plot->SetMarkerSize(size); - plot->Draw("P sames"); - } - - // ============================================== - void plotLegend(int var,int choice,TH1F* plot[10]) - { - float xlabel = 0.2; - float ylabel = 0.88; - // set the ATLAS label - ATLASLabel(xlabel,ylabel,"Work in Progress"); - // set energy and luminosity (adapt to your own case) - myText(xlabel+0.1,ylabel-0.06,1,"e+jets, #sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - - // ============================================================ - // set the TLegend (adapt to your own team) - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (choice==0) { // case with details on njet - if (var!=7 && var!=8) { - leg->AddEntry(plot[0],"#epsilon_{r} high E_{T}^{miss}, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[1],"#epsilon_{r} high E_{T}^{miss}, #geq2 jets, 0 btag","ep"); - leg->AddEntry(plot[2],"#epsilon_{r} high E_{T}^{miss}, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[3],"#epsilon_{r} high E_{T}^{miss}, #geq2 jets, #geq1 btag","ep"); - } else if (var==7) { // case for njet - leg->AddEntry(plot[0],"#epsilon_{r} high E_{T}^{miss}, 0 btag","ep"); - leg->AddEntry(plot[2],"#epsilon_{r} high E_{T}^{miss}, #geq1 btag","ep"); - } else if (var==8) { // case for nbjet - leg->AddEntry(plot[0],"#epsilon_{r} high E_{T}^{miss}, 1 jet","ep"); - leg->AddEntry(plot[1],"#epsilon_{r} high E_{T}^{miss}, #geq2 jets","ep"); - } - } else { - leg->AddEntry(plot[0],"#epsilon_{r} high E_{T}^{miss}, #geq1 jet","ep"); - } - leg->Draw(); - } - -private: - - Float_t m_var[300]; - Float_t m_errvar[300]; - Float_t m_eff[300]; - Float_t m_erreff[300]; - - Int_t m_nlines; -}; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecTP.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecTP.C deleted file mode 100644 index d4c3cad81dae..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecTP.C +++ /dev/null @@ -1,246 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TGraph.h" -#include "TString.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" -#include <vector> -#include <string> -#include <cmath> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot real efficiencies obtained from tag-and-probe -// method vs different variables -// It reads as input the default efficiencies of TopFakes package -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - - -void RealEffElecTP() -{ - // use this option to read tag-and-probe results on Z data - //int choice = 0; - // use this option to read tag-and-probe results on Z data + MC correction - //int choice = 1; - - // set the variable one want to compare - //int var = 0; // pt - //int var = 1; // eta - //int var = 2; // dR - //int var = 3; // jetpt - //int var = 4; // dphi - //int var = 5; // met - //int var = 6; // mtw - //int var = 7; // njet - //int var = 8; // nbjet - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - gStyle->SetOptTitle(0); - - // define the class - MyEff my(1); - // uncomment if you want to do all plots in one go - for (int choice=0;choice<=1;choice++) - for (int var=0;var<=8;var++) - my.execute(var,choice); - - return; -} - -class MyEff { - -public: - - MyEff(int choice){} - - // ======================================== - void execute(int var, int choice) - { - TGraph* plot0; - TH1F* plot[10]; - TString myname=""; - TString name[100]; - TString mynamehist = ""; - TFile *f; - - // read input files - if (choice==0) - myname = "../data/R_el_Default_TPNoCorr.root"; - if (choice==1) - myname = "../data/R_el_Default.root"; - std::cout << " myname = " << myname << std::endl; - f = TFile::Open(myname,"old"); - - // loop on jet bins - for (int ijet=0;ijet<=1;ijet++) { - // check which variable is read - if (var==0) mynamehist = "eff_pt"; - if (var==1) mynamehist = "eff_eta"; - if (var==2) mynamehist = "eff_dR"; - if (var==3) mynamehist = "eff_jetpt"; - if (var==4) mynamehist = "eff_dPhi"; - if (var==5) mynamehist = "eff_met"; - if (var==6) mynamehist = "eff_mtw"; - if (var==7) mynamehist = "eff_njet"; - if (var==8) mynamehist = "eff_nbtag"; - - if (var!=7) { // for all variables except njet - if (ijet==0) mynamehist += "_1j"; - if (ijet==1) mynamehist += "_ge2j"; - } else { // for njet - if (ijet==0) mynamehist += ""; - if (ijet==1) mynamehist += ""; - } - std::cout << " ijet = " << ijet - << " namehist = " << mynamehist << std::endl; - plot[ijet] = (TH1F*)f->Get(mynamehist); - //std::cout << " plot = " << plot[ijet] << std::endl; - } - - // =============================================== - // setup the TAxis ranges - m_nlines = 2; - m_eff[0] = 0.75; - m_eff[1] = 1.1; - if (var==0) {m_var[0] = 25.; m_var[1] = 150.;} // pt - if (var==1) {m_var[0] = 0.; m_var[1] = 2.3;} // eta - if (var==2) {m_var[0] = 0.; m_var[1] = 6.;} // dR - if (var==3) {m_var[0] = 25.; m_var[1] = 500.;} // jetpt - if (var==4) {m_var[0] = 0.; m_var[1] = 3.2;} // dphi - if (var==5) {m_var[0] = 0.; m_var[1] = 1000.;} // met - if (var==6) {m_var[0] = 0.; m_var[1] = 1000.;} // mtw - if (var==7) {m_var[0] = 0.; m_var[1] = 6.;} // njet - if (var==8) {m_var[0] = 0.; m_var[1] = 3.;} // nbjet - plot0 = new TGraph(m_nlines,m_var,m_eff); - - // plot the TGraph - plotGraph(var,choice,plot0,plot); - } - - // ============================================== - void plotGraph(int var,int choice,TGraph* plot0,TH1F* plot[10]) - { - // define the TCanvas - c1 = new TCanvas("c1"," ",0.,0.,800,600); - c1->SetFillColor(42); - c1->SetFillColor(10); - - // set the TAxis - plot0->SetFillColor(19); - plot0->SetLineColor(0); - plot0->SetLineWidth(4); - plot0->SetMarkerColor(0); - plot0->SetMarkerStyle(20); - //plot0->GetXaxis()->CenterLabels(true); - if (var==0) plot0->GetXaxis()->SetTitle("E_{T}(elec) [GeV]"); - if (var==1) plot0->GetXaxis()->SetTitle("|#eta(elec)|"); - if (var==2) plot0->GetXaxis()->SetTitle("#DeltaR (elec, nearest jet)"); - if (var==3) plot0->GetXaxis()->SetTitle("p_{T}(leading jet) [GeV]"); - if (var==4) plot0->GetXaxis()->SetTitle("#Delta#phi (elec,E_{T}^{miss})"); - if (var==5) plot0->GetXaxis()->SetTitle("E_{T}^{miss} [GeV]"); - if (var==6) plot0->GetXaxis()->SetTitle("m_{T}(elec,E_{T}^{miss}) [GeV]"); - if (var==7) plot0->GetXaxis()->SetTitle("n_{jet}"); - if (var==8) plot0->GetXaxis()->SetTitle("n_{b-jet}"); - plot0->GetYaxis()->SetTitle("Efficiency"); - plot0->Draw("AP"); - - // ================================================================ - // plot the TGraph - myplot(plot[0],1,20); // 1 jet - if (var!=7) { // for all variables except njet - myplot(plot[1],2,21); // >=2 jet - } - - c1->Update(); - c1->GetFrame()->SetFillColor(0); - c1->GetFrame()->SetBorderSize(0); - c1->Modified(); - // plot the TLegend - plotLegend(var,choice,plot); - c1->RedrawAxis(); - - // define the name of the output - TString suffix = ""; - if (var==0) suffix = "_vsEt"; - if (var==1) suffix = "_vsEta"; - if (var==2) suffix = "_vsdR"; - if (var==3) suffix = "_vsPtLeadingJet"; - if (var==4) suffix = "_vsdPhi"; - if (var==5) suffix = "_vsMET"; - if (var==6) suffix = "_vsMTW"; - if (var==7) suffix = "_vsnjet"; - if (var==8) suffix = "_vsnbjet"; - - TString format = ""; - for (int i=0;i<3;i++) { - if (i==0) format = ".eps"; - if (i==1) format = ".pdf"; - if (i==2) format = ".png"; - if (choice==0) c1->SaveAs("fig/effrealTPNoCorr_elec"+suffix+format); - if (choice==1) c1->SaveAs("fig/effrealTP_elec"+suffix+format); - } - } - - // ============================================== - void myplot(TH1F* plot,int mkcolor, int mktype, float size=1.5) - { - plot->SetFillColor(19); - plot->SetLineColor(1); - plot->SetLineWidth(1.5); - plot->SetMarkerColor(mkcolor); - plot->SetMarkerStyle(mktype); - //plot->SetTitle("rel 16"); - plot->SetMarkerSize(size); - plot->Draw("P sames"); - } - - // ============================================== - void plotLegend(int var,int choice,TH1F* plot[10]) - { - float xlabel = 0.2; - float ylabel = 0.88; - // set the ATLAS label - ATLASLabel(xlabel,ylabel,"Work in Progress"); - // set energy and luminosity (adapt to your own case) - myText(xlabel,ylabel-0.06,1,"e+jets, #sqrt{s}=13 TeV, 3.2 fb^{-1}",0.04); - - // ============================================================ - // set the TLegend (adapt to your own team) - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (choice==0) { - leg->AddEntry(plot[0],"#epsilon_{r} tag-and-probe (no MC Corr) 1 jet","ep"); - leg->AddEntry(plot[1],"#epsilon_{r} tag-and-probe (no MC corr) #geq2 jets","ep"); - } - if (choice==1) { - leg->AddEntry(plot[0],"#epsilon_{r} tag-and-probe 1 jet","ep"); - leg->AddEntry(plot[1],"#epsilon_{r} tag-and-probe #geq2 jets","ep"); - } - if (var!=7) leg->Draw(); - } - -private: - - Float_t m_var[300]; - Float_t m_errvar[300]; - Float_t m_eff[300]; - Float_t m_erreff[300]; - - Int_t m_nlines; -}; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecTPHighETmiss.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecTPHighETmiss.C deleted file mode 100644 index 34c8ded333f1..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffElecTPHighETmiss.C +++ /dev/null @@ -1,243 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TGraph.h" -#include "TString.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" -#include <vector> -#include <string> -#include <cmath> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot real efficiencies obtained both from -// tag-and-probe and high-MET/MTW methods vs different variables -// It reads as input the default efficiencies of TopFakes package -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - -void RealEffElecTPHighETmiss() -{ - // set the variable one want to compare - //int var = 0; // pt - //int var = 1; // eta - //int var = 2; // dR - //int var = 3; // jetpt - //int var = 4; // dphi - //int var = 5; // met - //int var = 6; // mtw - //int var = 7; // njet - //int var = 8; // nbjet - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - gStyle->SetOptTitle(0); - - // define the class - MyEff my(1); - // uncomment if you want to do all plots in one go - for (int var=0;var<=8;var++) - my.execute(var); - - return; -} - -class MyEff { - -public: - - MyEff(int choice) {} - - // ======================================== - void execute(int var) - { - TGraph* plot0; - TH1F* plot[2][10]; - TString myname=""; - TString name[100]; - TString mynamehist = ""; - TFile *f[2]; - - // read the input files - // T&P - myname = "../data/R_el_Default.root"; - f[0] = TFile::Open(myname,"old"); - // High ETmiss - myname = "../data/R_el_Default_CRreal.root"; - f[1] = TFile::Open(myname,"old"); - - // loop on files - for (int ifile=0;ifile<=1;ifile++) { - // loop on jet bins - for (int ijet=0;ijet<=1;ijet++) { - // check which variables to use - if (var==0) mynamehist = "eff_pt"; - if (var==1) mynamehist = "eff_eta"; - if (var==2) mynamehist = "eff_dR"; - if (var==3) mynamehist = "eff_jetpt"; - if (var==4) mynamehist = "eff_dPhi"; - if (var==5) mynamehist = "eff_met"; - if (var==6) mynamehist = "eff_mtw"; - if (var==7) mynamehist = "eff_njet"; - if (var==8) mynamehist = "eff_nbtag"; - - if (var!=7) { - if (ijet==0) mynamehist += "_1j"; - if (ifile==0) - if (ijet==1) mynamehist += "_ge2j"; - if (ifile==1) - if (ijet==1) mynamehist += ""; - } else { - if (ijet==0) mynamehist += ""; - if (ijet==1) mynamehist += ""; - } - - std::cout << " ijet = " << ijet - << " namehist = " << mynamehist << std::endl; - plot[ifile][ijet] = (TH1F*)f[ifile]->Get(mynamehist); - std::cout << " ifile = " << ifile << " ijet = " << ijet - << " plot = " << plot[ifile][ijet] << std::endl; - } - } - - // =============================================== - // set the TAxis ranges - m_nlines = 2; - m_eff[0] = 0.75; - m_eff[1] = 1.1; - if (var==0) {m_var[0] = 25.; m_var[1] = 150.;} // pt - if (var==1) {m_var[0] = 0.; m_var[1] = 2.3;} // eta - if (var==2) {m_var[0] = 0.; m_var[1] = 6.;} // dR - if (var==3) {m_var[0] = 25.; m_var[1] = 500.;} // jetpt - if (var==4) {m_var[0] = 0.; m_var[1] = 3.2;} // dphi - if (var==5) {m_var[0] = 0.; m_var[1] = 1000.;} // met - if (var==6) {m_var[0] = 0.; m_var[1] = 1000.;} // mtw - if (var==7) {m_var[0] = 0.; m_var[1] = 6.;} // njet - if (var==8) {m_var[0] = 0.; m_var[1] = 3.;} // nbjet - plot0 = new TGraph(m_nlines,m_var,m_eff); - - // plot the TGraph - plotGraph(var,plot0,plot); - } - - // ============================================== - void plotGraph(int var,TGraph* plot0,TH1F* plot[2][10]) - { - // set the TCanvas - c1 = new TCanvas("c1"," ",0.,0.,800,600); - c1->SetFillColor(42); - c1->SetFillColor(10); - - // set the TAxis - plot0->SetFillColor(19); - plot0->SetLineColor(0); - plot0->SetLineWidth(4); - plot0->SetMarkerColor(0); - plot0->SetMarkerStyle(20); - //plot0->GetXaxis()->CenterLabels(true); - if (var==0) plot0->GetXaxis()->SetTitle("E_{T}(elec) [GeV]"); - if (var==1) plot0->GetXaxis()->SetTitle("|#eta(elec)|"); - if (var==2) plot0->GetXaxis()->SetTitle("#DeltaR (elec, nearest jet)"); - if (var==3) plot0->GetXaxis()->SetTitle("p_{T}(leading jet) [GeV]"); - if (var==4) plot0->GetXaxis()->SetTitle("#Delta#phi (elec,E_{T}^{miss})"); - if (var==5) plot0->GetXaxis()->SetTitle("E_{T}^{miss} [GeV]"); - if (var==6) plot0->GetXaxis()->SetTitle("m_{T}(elec,E_{T}^{miss}) [GeV]"); - if (var==7) plot0->GetXaxis()->SetTitle("n_{jet}"); - if (var==8) plot0->GetXaxis()->SetTitle("n_{b-jet}"); - - plot0->GetYaxis()->SetTitle("Efficiency"); - plot0->Draw("AP"); - - // ================================================================ - // plot the TGraph - myplot(plot[0][0],1,20); - if (var!=7) { - myplot(plot[0][1],2,21); - } - myplot(plot[1][0],3,24); - - c1->Update(); - c1->GetFrame()->SetFillColor(0); - c1->GetFrame()->SetBorderSize(0); - c1->Modified(); - // plot the TLegend - plotLegend(var,plot); - c1->RedrawAxis(); - - // set the output names - TString suffix = ""; - if (var==0) suffix = "_vsEt"; - if (var==1) suffix = "_vsEta"; - if (var==2) suffix = "_vsdR"; - if (var==3) suffix = "_vsPtLeadingJet"; - if (var==4) suffix = "_vsdPhi"; - if (var==5) suffix = "_vsMET"; - if (var==6) suffix = "_vsMTW"; - if (var==7) suffix = "_vsnjet"; - if (var==8) suffix = "_vsnbjet"; - TString format = ""; - for (int i=0;i<3;i++) { - if (i==0) format = ".eps"; - if (i==1) format = ".pdf"; - if (i==2) format = ".png"; - - c1->SaveAs("fig/effrealTPHighETmiss_elec"+suffix+format); - } - } - - // ============================================== - void myplot(TH1F* plot,int mkcolor, int mktype, float size=1.5) - { - plot->SetFillColor(19); - plot->SetLineColor(1); - plot->SetLineWidth(1.5); - plot->SetMarkerColor(mkcolor); - plot->SetMarkerStyle(mktype); - //plot->SetTitle("rel 16"); - plot->SetMarkerSize(size); - plot->Draw("P sames"); - } - - // ============================================== - void plotLegend(int var,TH1F* plot[2][10]) - { - float xlabel = 0.2; - float ylabel = 0.88; - // set the ATLAS label - ATLASLabel(xlabel,ylabel,"Work in Progress"); - // set energy and luminosity (adapt to your own case) - myText(xlabel+0.1,ylabel-0.06,1,"e+jets, #sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - - // ============================================================ - // set the TLegend (adapt to your own team) - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - leg->AddEntry(plot[0][0],"#epsilon_{r} tag-and-probe 1 jet","ep"); - leg->AddEntry(plot[0][1],"#epsilon_{r} tag-and-probe #geq2 jets","ep"); - leg->AddEntry(plot[1][0],"#epsilon_{r} #epsilon_{r} high E_{T}^{miss} #geq1 jet","ep"); - if (var!=7) leg->Draw(); - } - -private: - - Float_t m_var[300]; - Float_t m_errvar[300]; - Float_t m_eff[300]; - Float_t m_erreff[300]; - - Int_t m_nlines; -}; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonHighMTW.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonHighMTW.C deleted file mode 100644 index 7c566e79a88f..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonHighMTW.C +++ /dev/null @@ -1,386 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TGraph.h" -#include "TString.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" -#include <vector> -#include <string> -#include <cmath> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot real efficiencies obtained from high-MET/MTW -// method vs different variables -// It reads as input the default efficiencies of TopFakes package -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - -void RealEffMuonHighMTW() -{ - // use this option to see results with different njet bins - //int choice = 0; - // use this option to see results with njet>=1 only - //int choice = 1; - - // choose the trigger - //int trigger = 0; // mu20i - //int trigger = 1; // mu20 - //int trigger = 2; // mu50 - - // set the variable one want to compare - //int var = 0; // pt - //int var = 1; // eta - //int var = 2; // dR - //int var = 3; // jetpt - //int var = 4; // dphi - //int var = 5; // met - //int var = 6; // mtw - //int var = 7; // njet - //int var = 8; // nbjet - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - gStyle->SetOptTitle(0); - - // define the class - MyEff my(1); - // uncomment if you want to do all plots in one go - for (int choice=0;choice<=1;choice++) - for (int trigger=0;trigger<=2;trigger++) - for (int var=0;var<=8;var++) - my.execute(var,choice,trigger); - - return; -} - -class MyEff { - -public: - - MyEff(int choice) {} - - // ======================================== - void execute(int var, int choice,int trigger) - { - TGraph* plot0; - TH1F* plot[20]; - TString myname=""; - TString name[100]; - TString mynamehist = ""; - TFile *f; - - // read input files - myname = "../data/R_mu_Default_CRreal.root"; - std::cout << " myname = " << myname << std::endl; - f = TFile::Open(myname,"old"); - - // loop on jet bins - for (int ijet=0;ijet<=11;ijet++) { - // check which variables to use - if (var==0) mynamehist = "eff_pt"; - if (var==1) mynamehist = "eff_eta"; - if (var==2) mynamehist = "eff_dR"; - if (var==3) mynamehist = "eff_jetpt"; - if (var==4) mynamehist = "eff_dPhi"; - if (var==5) mynamehist = "eff_met"; - if (var==6) mynamehist = "eff_mwt"; - if (var==7) mynamehist = "eff_njet"; - if (var==8) mynamehist = "eff_nbtag"; - - if (choice==0) { // with details on njet - if (var<7) { - // mu20i - if (ijet==0) mynamehist += "_0b_1j_mu20i"; - if (ijet==1) mynamehist += "_0b_ge2j_mu20i"; - if (ijet==2) mynamehist += "_ge1b_1j_mu20i"; - if (ijet==3) mynamehist += "_ge1b_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_1j_mu20"; - if (ijet==5) mynamehist += "_0b_ge2j_mu20"; - if (ijet==6) mynamehist += "_ge1b_1j_mu20"; - if (ijet==7) mynamehist += "_ge1b_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_1j_mu50"; - if (ijet==9) mynamehist += "_0b_ge2j_mu50"; - if (ijet==10) mynamehist += "_ge1b_1j_mu50"; - if (ijet==11) mynamehist += "_ge1b_ge2j_mu50"; - } else if (var==7) { // njet - // mu20i - if (ijet==0) mynamehist += "_0b_mu20i"; - if (ijet==1) mynamehist += "_0b_mu20i"; - if (ijet==2) mynamehist += "_ge1b_mu20i"; - if (ijet==3) mynamehist += "_ge1b_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_mu20"; - if (ijet==5) mynamehist += "_0b_mu20"; - if (ijet==6) mynamehist += "_ge1b_mu20"; - if (ijet==7) mynamehist += "_ge1b_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_mu50"; - if (ijet==9) mynamehist += "_0b_mu50"; - if (ijet==10) mynamehist += "_ge1b_mu50"; - if (ijet==11) mynamehist += "_ge1b_mu50"; - } else if (var==8) { // nbjet - // mu20i - if (ijet==0) mynamehist += "_0b_1j_mu20i"; - if (ijet==1) mynamehist += "_0b_ge2j_mu20i"; - if (ijet==2) mynamehist += "_ge1b_1j_mu20i"; - if (ijet==3) mynamehist += "_ge1b_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_1j_mu20"; - if (ijet==5) mynamehist += "_0b_ge2j_mu20"; - if (ijet==6) mynamehist += "_ge1b_1j_mu20"; - if (ijet==7) mynamehist += "_ge1b_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_1j_mu50"; - if (ijet==9) mynamehist += "_0b_ge2j_mu50"; - if (ijet==10) mynamehist += "_ge1b_1j_mu50"; - if (ijet==11) mynamehist += "_ge1b_ge2j_mu50"; - } - } - // case for njet>=1 - if (choice==1) { // with details on njet - // mu20i - if (ijet==0) mynamehist += "_0b_mu20i"; - if (ijet==1) mynamehist += "_0b_mu20i"; - if (ijet==2) mynamehist += "_ge1b_mu20i"; - if (ijet==3) mynamehist += "_ge1b_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_mu20"; - if (ijet==5) mynamehist += "_0b_mu20"; - if (ijet==6) mynamehist += "_ge1b_mu20"; - if (ijet==7) mynamehist += "_ge1b_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_mu50"; - if (ijet==9) mynamehist += "_0b_mu50"; - if (ijet==10) mynamehist += "_ge1b_mu50"; - if (ijet==11) mynamehist += "_ge1b_mu50"; - } - std::cout << " ijet = " << ijet - << " namehist = " << mynamehist << std::endl; - plot[ijet] = (TH1F*)f->Get(mynamehist); - std::cout << " ijet = " << ijet - << " plot = " << plot[ijet] << std::endl; - } - - // =============================================== - // set the TAxis ranges - m_nlines = 2; - m_eff[0] = 0.75; - m_eff[1] = 1.3; - if (var==0) {m_var[0] = 25.; m_var[1] = 150.;} // pt - if (var==1) {m_var[0] = 0.; m_var[1] = 2.3;} // eta - if (var==2) {m_var[0] = 0.; m_var[1] = 6.;} // dR - if (var==3) {m_var[0] = 25.; m_var[1] = 500.;} // jetpt - if (var==4) {m_var[0] = 0.; m_var[1] = 3.2;} // dphi - if (var==5) {m_var[0] = 0.; m_var[1] = 1000.;} // met - if (var==6) {m_var[0] = 0.; m_var[1] = 1000.;} // mtw - if (var==7) {m_var[0] = 0.; m_var[1] = 6.;} // njet - if (var==8) {m_var[0] = 0.; m_var[1] = 3.;} // nbjet - plot0 = new TGraph(m_nlines,m_var,m_eff); - - // plot the TGraph - plotGraph(var,choice,trigger,plot0,plot); - } - - // ============================================== - void plotGraph(int var,int choice,int trigger,TGraph* plot0,TH1F* plot[20]) - { - // set the TCanvas - c1 = new TCanvas("c1"," ",0.,0.,800,600); - c1->SetFillColor(42); - c1->SetFillColor(10); - - // plot the TAxis - plot0->SetFillColor(19); - plot0->SetLineColor(0); - plot0->SetLineWidth(4); - plot0->SetMarkerColor(0); - plot0->SetMarkerStyle(20); - //plot0->GetXaxis()->CenterLabels(true); - if (var==0) plot0->GetXaxis()->SetTitle("p_{T}(#mu) [GeV]"); - if (var==1) plot0->GetXaxis()->SetTitle("|#eta(#mu)|"); - if (var==2) plot0->GetXaxis()->SetTitle("#DeltaR (#mu, nearest jet)"); - if (var==3) plot0->GetXaxis()->SetTitle("p_{T}(leading jet) [GeV]"); - if (var==4) plot0->GetXaxis()->SetTitle("#Delta#phi (#mu,E_{T}^{miss})"); - if (var==5) plot0->GetXaxis()->SetTitle("E_{T}^{miss} [GeV]"); - if (var==6) plot0->GetXaxis()->SetTitle("m_{T}(#mu,E_{T}^{miss}) [GeV]"); - if (var==7) plot0->GetXaxis()->SetTitle("n_{jet}"); - if (var==8) plot0->GetXaxis()->SetTitle("n_{b-jet}"); - plot0->GetYaxis()->SetTitle("Efficiency"); - plot0->Draw("AP"); - - // ================================================================ - // choose the trigger - int it1 = -1; int it2 = -1; int it3 = -1; int it4 = -1; - if (trigger==0) {it1 = 0; it2 = 1; it3 = 2; it4 = 3;} // mu20i - if (trigger==1) {it1 = 4; it2 = 5; it3 = 6; it4 = 7;} // mu20 - if (trigger==2) {it1 = 8; it2 = 9; it3 = 10; it4 = 11;} // mu50 - - // plot the TGraph - if (choice==0) { // for different jet - myplot(plot[it1],1,20); - if (var!=7) myplot(plot[it2],2,21); // case for njet - myplot(plot[it3],3,24); - if (var!=7) myplot(plot[it4],4,25); // case for njet - - if (var==8) { // case for nbjet (use same colors) - myplot(plot[it1],1,20); - myplot(plot[it2],3,24); - myplot(plot[it3],1,20); - myplot(plot[it4],3,24); - } - } - if (choice==1) { // for njet>=1 - myplot(plot[it1],1,20); - myplot(plot[it3],3,24); - - if (var==8) { // case for nbjet (use same colors) - myplot(plot[it1],1,20); - myplot(plot[it3],1,20); - } - } - - c1->Update(); - c1->GetFrame()->SetFillColor(0); - c1->GetFrame()->SetBorderSize(0); - c1->Modified(); - // plot the TLegend - plotLegend(var,choice,trigger,plot); - c1->RedrawAxis(); - - // set the output names - TString suffix = ""; - if (var==0) suffix = "_vsPt"; - if (var==1) suffix = "_vsEta"; - if (var==2) suffix = "_vsdR"; - if (var==3) suffix = "_vsPtLeadingJet"; - if (var==4) suffix = "_vsdPhi"; - if (var==5) suffix = "_vsMET"; - if (var==6) suffix = "_vsMTW"; - if (var==7) suffix = "_vsnjet"; - if (var==8) suffix = "_vsnbjet"; - - TString st = ""; - if (trigger==0) st = "_mu20i"; - if (trigger==1) st = "_mu20"; - if (trigger==2) st = "_mu50"; - - TString format = ""; - for (int i=0;i<3;i++) { - if (i==0) format = ".eps"; - if (i==1) format = ".pdf"; - if (i==2) format = ".png"; - - if (choice==0) - c1->SaveAs("fig/effrealHighMTW_muon"+st+suffix+format); - if (choice==1) - c1->SaveAs("fig/effrealHighMTW_muon_ge1j"+st+suffix+format); - } - } - - // ============================================== - void myplot(TH1F* plot,int mkcolor, int mktype, float size=1.5) - { - plot->SetFillColor(19); - plot->SetLineColor(1); - plot->SetLineWidth(1.5); - plot->SetMarkerColor(mkcolor); - plot->SetMarkerStyle(mktype); - //plot->SetTitle("rel 16"); - plot->SetMarkerSize(size); - plot->Draw("P sames"); - } - - // ============================================== - void plotLegend(int var,int choice,int trigger,TH1F* plot[20]) - { - float xlabel = 0.2; - float ylabel = 0.88; - // set the ATLAS label - ATLASLabel(xlabel,ylabel,"Work in Progress"); - // set energy and luminosity (adapt to your own case) - myText(xlabel+0.2,ylabel-0.06,1,"#sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - - if (trigger==0) myText(xlabel,ylabel-0.06,1,"#mu+jets mu20i",0.04); - if (trigger==1) myText(xlabel,ylabel-0.06,1,"#mu+jets mu20",0.04); - if (trigger==2) myText(xlabel,ylabel-0.06,1,"#mu+jets mu50",0.04); - - int it1 = -1; int it2 = -1; int it3 = -1; int it4 = -1; - if (trigger==0) {it1 = 0; it2 = 1; it3 = 2; it4 = 3;} // mu20i - if (trigger==1) {it1 = 4; it2 = 5; it3 = 6; it4 = 7;} // mu20 - if (trigger==2) {it1 = 8; it2 = 9; it3 = 10; it4 = 11;} // mu50 - - // ============================================================ - // set the TLegend (adapt to your own team) - float ymin = 0.55; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - // ============================================================ - // set the TLegend (adapt to your own team) - - if (choice==0) { // with details on njet - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (var!=7 && var!=8) { - leg->AddEntry(plot[it1],"#epsilon_{r} High m_{T}^{W}, 1 jet, 0 btag","ep"); - leg->AddEntry(plot[it2],"#epsilon_{r} High m_{T}^{W}, #geq2 jets, 0 btag","ep"); - leg->AddEntry(plot[it3],"#epsilon_{r} High m_{T}^{W}, 1 jet, #geq1 btag","ep"); - leg->AddEntry(plot[it4],"#epsilon_{r} High m_{T}^{W}, #geq2 jets, #geq1 btag","ep"); - } else if (var==7) { // case for njet - leg->AddEntry(plot[it1],"#epsilon_{r} High m_{T}^{W}, 0 btag","ep"); - leg->AddEntry(plot[it3],"#epsilon_{r} High m_{T}^{W}, #geq1 btag","ep"); - } else if (var==8) { // case for nbjet - leg->AddEntry(plot[it1],"#epsilon_{r} High m_{T}^{W}, 1 jet","ep"); - leg->AddEntry(plot[it2],"#epsilon_{r} High m_{T}^{W}, #geq2 jets","ep"); - } - leg->Draw(); - } - - if (choice==1) { // with njet>=1 - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (var!=8) { - leg->AddEntry(plot[it1],"#epsilon_{r} High m_{T}^{W}, #geq 1 jet, 0 btag","ep"); - leg->AddEntry(plot[it3],"#epsilon_{r} High m_{T}^{W}, #geq 1 jet, #geq1 btag","ep"); - } - if (var==8) // for nbjet - leg->AddEntry(plot[it1],"#epsilon_{r} High m_{T}^{W}, #geq 1 jet","ep"); - leg->Draw(); - } - - } - -private: - - Float_t m_var[300]; - Float_t m_errvar[300]; - Float_t m_eff[300]; - Float_t m_erreff[300]; - - Int_t m_nlines; -}; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonTP.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonTP.C deleted file mode 100644 index 0f0a4a6e0c61..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonTP.C +++ /dev/null @@ -1,272 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TGraph.h" -#include "TString.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" -#include <vector> -#include <string> -#include <cmath> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot real efficiencies obtained from tag-and-probe -// method vs different variables -// It reads as input the default efficiencies of TopFakes package -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - -void RealEffMuonTP() -{ - // set the variable one want to compare - //int var = 0; // pt - //int var = 1; // eta - //int var = 2; // dR - //int var = 3; // jetpt - //int var = 4; // dphi - //int var = 5; // met - //int var = 6; // mtw - //int var = 7; // njet - //int var = 8; // nbjet - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - gStyle->SetOptTitle(0); - - // define the class - MyEff my(1); - // uncomment if you want to do all plots in one go - for (int var=0;var<=8;var++) - my.execute(var); - - return; -} - -class MyEff { - -public: - - MyEff(int choice) {} - - // ======================================== - void execute(int var) - { - TGraph* plot0; - TH1F* plot[10]; - TString myname=""; - TString name[100]; - TString mynamehist = ""; - TFile *f; - - // read input files - myname = "../data/R_mu_Default.root"; - std::cout << " myname = " << myname << std::endl; - f = TFile::Open(myname,"old"); - - // loop on all jet possibilities - for (int ijet=0;ijet<=5;ijet++) { - // check which variable is read - if (var==0) mynamehist = "eff_pt"; - if (var==1) mynamehist = "eff_eta"; - if (var==2) mynamehist = "eff_dR"; - if (var==3) mynamehist = "eff_jetpt"; - if (var==4) mynamehist = "eff_dPhi"; - if (var==5) mynamehist = "eff_met"; - if (var==6) mynamehist = "eff_mwt"; - if (var==7) mynamehist = "eff_njet"; - if (var==8) mynamehist = "eff_nbtag"; - - if (var<7) { // for all variables except njet and nbjet - if (ijet==0) mynamehist += "_1j_mu20i"; - if (ijet==1) mynamehist += "_ge2j_mu20i"; - if (ijet==2) mynamehist += "_1j_mu20"; - if (ijet==3) mynamehist += "_ge2j_mu20"; - if (ijet==4) mynamehist += "_1j_mu50"; - if (ijet==5) mynamehist += "_ge2j_mu50"; - } else if (var==7) { // njet - if (ijet==0) mynamehist += "_mu20i"; - if (ijet==1) mynamehist += "_ge2j_mu20i"; - if (ijet==2) mynamehist += "_mu20"; - if (ijet==3) mynamehist += "_ge2j_mu20"; - if (ijet==4) mynamehist += "_mu50"; - if (ijet==5) mynamehist += "_ge2j_mu50"; - } else if (var==8) { // nbjet - if (ijet==0) mynamehist += "_mu20i"; - if (ijet==1) mynamehist += "_mu20i"; - if (ijet==2) mynamehist += "_mu20"; - if (ijet==3) mynamehist += "_mu20"; - if (ijet==4) mynamehist += "_mu50"; - if (ijet==5) mynamehist += "_mu50"; - } - std::cout << " ijet = " << ijet - << " namehist = " << mynamehist << std::endl; - plot[ijet] = (TH1F*)f->Get(mynamehist); - //std::cout << " plot = " << plot[ijet] << std::endl; - } - // =============================================== - // setup the TAxis ranges - m_nlines = 2; - m_eff[0] = 0.85; - m_eff[1] = 1.2; - if (var==0) {m_var[0] = 25.; m_var[1] = 150.;} // pt - if (var==1) {m_var[0] = 0.; m_var[1] = 2.3;} // eta - if (var==2) {m_var[0] = 0.; m_var[1] = 6.;} // dR - if (var==3) {m_var[0] = 25.; m_var[1] = 500.;} // jetpt - if (var==4) {m_var[0] = 0.; m_var[1] = 3.2;} // dphi - if (var==5) {m_var[0] = 0.; m_var[1] = 1000.;} // met - if (var==6) {m_var[0] = 0.; m_var[1] = 1000.;} // mtw - if (var==7) {m_var[0] = 0.; m_var[1] = 6.;} // njet - if (var==8) {m_var[0] = 0.; m_var[1] = 3.;} // nbjet - plot0 = new TGraph(m_nlines,m_var,m_eff); - - // plot the TGraph - plotGraph(var,plot0,plot); - } - - // ============================================== - void plotGraph(int var,TGraph* plot0,TH1F* plot[10]) - { - // set the TCanvas - c1 = new TCanvas("c1"," ",0.,0.,800,600); - c1->SetFillColor(42); - c1->SetFillColor(10); - - // plot the TAxis - plot0->SetFillColor(19); - plot0->SetLineColor(0); - plot0->SetLineWidth(4); - plot0->SetMarkerColor(0); - plot0->SetMarkerStyle(20); - //plot0->GetXaxis()->CenterLabels(true); - if (var==0) plot0->GetXaxis()->SetTitle("p_{T}(#mu) [GeV]"); - if (var==1) plot0->GetXaxis()->SetTitle("|#eta(#mu)|"); - if (var==2) plot0->GetXaxis()->SetTitle("#DeltaR (#mu, nearest jet)"); - if (var==3) plot0->GetXaxis()->SetTitle("p_{T}(leading jet) [GeV]"); - if (var==4) plot0->GetXaxis()->SetTitle("#Delta#phi (#mu,E_{T}^{miss})"); - if (var==5) plot0->GetXaxis()->SetTitle("E_{T}^{miss} [GeV]"); - if (var==6) plot0->GetXaxis()->SetTitle("m_{T}(#mu,E_{T}^{miss}) [GeV]"); - if (var==7) plot0->GetXaxis()->SetTitle("n_{jet}"); - if (var==8) plot0->GetXaxis()->SetTitle("n_{b-jet}"); - plot0->GetYaxis()->SetTitle("Efficiency"); - plot0->Draw("AP"); - - // ================================================================ - // plot the TGraph - myplot(plot[0],1,20); - if (var<7) { // for all variables except njet and nbjet - myplot(plot[0],1,20); // mu20i 1 jet - myplot(plot[1],1,24); // >=2 jet - myplot(plot[2],2,21); // mu20 1 jet - myplot(plot[3],2,25); // >=2 jet - myplot(plot[4],4,22); // mu50 1 jet - myplot(plot[5],4,26); // >=2 jet - } - if (var==7) { // njet - myplot(plot[0],1,20); - myplot(plot[2],2,24); - myplot(plot[4],3,25); - } - if (var==8) { // nbjet - myplot(plot[0],1,20); - myplot(plot[2],2,24); - myplot(plot[4],3,25); - } - c1->Update(); - c1->GetFrame()->SetFillColor(0); - c1->GetFrame()->SetBorderSize(0); - c1->Modified(); - - // plot the TLegend - plotLegend(var,plot); - c1->RedrawAxis(); - - // define the output name - TString suffix = ""; - if (var==0) suffix = "_vsPt"; - if (var==1) suffix = "_vsEta"; - if (var==2) suffix = "_vsdR"; - if (var==3) suffix = "_vsPtLeadingJet"; - if (var==4) suffix = "_vsdPhi"; - if (var==5) suffix = "_vsMET"; - if (var==6) suffix = "_vsMTW"; - if (var==7) suffix = "_vsnjet"; - if (var==8) suffix = "_vsnbjet"; - - TString format = ""; - for (int i=0;i<3;i++) { - if (i==0) format = ".eps"; - if (i==1) format = ".pdf"; - if (i==2) format = ".png"; - c1->SaveAs("fig/effrealTP_muon"+suffix+format); - } - } - - // ============================================== - void myplot(TH1F* plot,int mkcolor, int mktype, float size=1.5) - { - plot->SetFillColor(19); - plot->SetLineColor(1); - plot->SetLineWidth(1.5); - plot->SetMarkerColor(mkcolor); - plot->SetMarkerStyle(mktype); - //plot->SetTitle("rel 16"); - plot->SetMarkerSize(size); - plot->Draw("P sames"); - } - - // ============================================== - void plotLegend(int var,TH1F* plot[10]) - { - float xlabel = 0.2; - float ylabel = 0.88; - // set the ATLAS label - ATLASLabel(xlabel,ylabel,"Work in Progress"); - // set energy and luminosity (adapt to your own case) - myText(xlabel+0.1,ylabel-0.06,1,"#mu+jets, #sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - - // ============================================================ - // set the TLegend (adapt to your own team) - float ymin = 0.55; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (var<7) { - leg->AddEntry(plot[0],"#epsilon_{r} tag-and-probe 1 jet mu20i","ep"); - leg->AddEntry(plot[1],"#epsilon_{r} tag-and-probe #geq2 jets mu20i","ep"); - leg->AddEntry(plot[2],"#epsilon_{r} tag-and-probe 1 jet mu20","ep"); - leg->AddEntry(plot[3],"#epsilon_{r} tag-and-probe #geq2 jets mu20","ep"); - leg->AddEntry(plot[4],"#epsilon_{r} tag-and-probe 1 jet mu50","ep"); - leg->AddEntry(plot[5],"#epsilon_{r} tag-and-probe #geq2 jets mu50","ep"); - } else if (var==7) { // njet - leg->AddEntry(plot[0],"#epsilon_{r} tag-and-probe mu20i","ep"); - leg->AddEntry(plot[2],"#epsilon_{r} tag-and-probe mu20","ep"); - leg->AddEntry(plot[4],"#epsilon_{r} tag-and-probe mu50","ep"); - } else if (var==8) { // njet - leg->AddEntry(plot[0],"#epsilon_{r} tag-and-probe mu20i","ep"); - leg->AddEntry(plot[2],"#epsilon_{r} tag-and-probe mu20","ep"); - leg->AddEntry(plot[4],"#epsilon_{r} tag-and-probe mu50","ep"); - } - leg->Draw(); - } - -private: - - Float_t m_var[300]; - Float_t m_errvar[300]; - Float_t m_eff[300]; - Float_t m_erreff[300]; - - Int_t m_nlines; -}; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonTPHighMTW.C b/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonTPHighMTW.C deleted file mode 100644 index a3afcdbb8a60..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopFakes/macros/RealEffMuonTPHighMTW.C +++ /dev/null @@ -1,506 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TGraph.h" -#include "TString.h" -#include "AtlasUtils.C" -#include "AtlasStyle.C" -#include "AtlasLabels.C" -#include <vector> -#include <string> -#include <cmath> - -///////////////////////////////////////////////////////////////////// -// CREATED : 01/02/2016 -// AUTHOR : Frederic Derue (LPNHE Paris) -// PURPOSE : ROOT macro to plot real efficiencies obtained both from -// tag-and-probe and high-MET/MTW methods vs different variables -// It reads as input the default efficiencies of TopFakes package -// MODIFICATION : -// -///////////////////////////////////////////////////////////////////// - -void RealEffMuonTPHighMTW() -{ - // use this option to see results with different njet bins - //int choice = 0; - // use this.q - // option to see results with njet>=1 only - //int choice = 1; - - // choose the trigger - //int trigger = 0; // mu20i - //int trigger = 1; // mu20 - //int trigger = 2; // mu50 - - // set the variable one want to compare - //int var = 0; // pt - //int var = 1; // eta - //int var = 2; // dR - //int var = 3; // jetpt - //int var = 4; // dphi - //int var = 5; // met - //int var = 6; // mtw - //int var = 7; // njet - //int var = 8; // nbjet - - SetAtlasStyle(); - gROOT->Reset(); - gROOT->SetStyle("ATLAS"); - gROOT->ForceStyle(); - gStyle->SetOptStat(0); - gStyle->SetOptTitle(0); - gStyle->SetOptTitle(0); - - // define the class - MyEff my(1); - // uncomment if you want to do all plots in one go - for (int choice=0;choice<=1;choice++) - for (int trigger=0;trigger<=2;trigger++) - for (int var=0;var<=8;var++) - my.execute(var,choice,trigger); - - return; -} - -class MyEff { - -public: - - MyEff(int choice) {} - - // ======================================== - void execute(int var,int choice,int trigger) - { - TGraph* plot0; - TH1F* plot[2][20]; - TString myname=""; - TString name[100]; - TString mynamehist = ""; - TFile *f[2]; - - // read input files - // T&P - myname = "../data/R_mu_Default.root"; - f[0] = TFile::Open(myname,"old"); - // High ETmiss - myname = "../data/R_mu_Default_CRreal.root"; - f[1] = TFile::Open(myname,"old"); - - // loop on all files - for (int ifile=0;ifile<=1;ifile++) { - // loop on jet bins - for (int ijet=0;ijet<=11;ijet++) { - // check which variable to be used - if (var==0) mynamehist = "eff_pt"; - if (var==1) mynamehist = "eff_eta"; - if (var==2) mynamehist = "eff_dR"; - if (var==3) mynamehist = "eff_jetpt"; - if (var==4) mynamehist = "eff_dPhi"; - if (var==5) mynamehist = "eff_met"; - if (var==6) mynamehist = "eff_mwt"; - if (var==7) mynamehist = "eff_njet"; - if (var==8) mynamehist = "eff_nbtag"; - - // case for the tag-and-probe - if (ifile==0) { - if (choice==0) { // with details on njet - if (var<7) { - // mu20i - if (ijet==0) mynamehist += "_1j_mu20i"; - if (ijet==1) mynamehist += "_ge2j_mu20i"; - if (ijet==2) mynamehist += "_1j_mu20i"; - if (ijet==3) mynamehist += "_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_1j_mu20"; - if (ijet==5) mynamehist += "_ge2j_mu20"; - if (ijet==6) mynamehist += "_1j_mu20"; - if (ijet==7) mynamehist += "_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_1j_mu50"; - if (ijet==9) mynamehist += "_ge2j_mu50"; - if (ijet==10) mynamehist += "_1j_mu50"; - if (ijet==11) mynamehist += "_ge2j_mu50"; - } else if (var==7) { // njet - // mu20i - if (ijet==0) mynamehist += "_mu20i"; - if (ijet==1) mynamehist += "_mu20i"; - if (ijet==2) mynamehist += "_mu20i"; - if (ijet==3) mynamehist += "_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_mu20"; - if (ijet==5) mynamehist += "_mu20"; - if (ijet==6) mynamehist += "_mu20"; - if (ijet==7) mynamehist += "_mu20"; - // mu50 - if (ijet==8) mynamehist += "_mu50"; - if (ijet==9) mynamehist += "_mu50"; - if (ijet==10) mynamehist += "_mu50"; - if (ijet==11) mynamehist += "_mu50"; - } else if (var==8) { // nbjet - // mu20i - if (ijet==0) mynamehist += "_1j_mu20i"; - if (ijet==1) mynamehist += "_ge2j_mu20i"; - if (ijet==2) mynamehist += "_1j_mu20i"; - if (ijet==3) mynamehist += "_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_1j_mu20"; - if (ijet==5) mynamehist += "_ge2j_mu20"; - if (ijet==6) mynamehist += "_1j_mu20"; - if (ijet==7) mynamehist += "_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_1j_mu50"; - if (ijet==9) mynamehist += "_ge2j_mu50"; - if (ijet==10) mynamehist += "_1j_mu50"; - if (ijet==11) mynamehist += "_ge2j_mu50"; - } - } - // case for njet>=1 - if (choice==1) { // with details on njet - // mu20i - if (ijet==0) mynamehist += "_mu20i"; - if (ijet==1) mynamehist += "_mu20i"; - if (ijet==2) mynamehist += "_mu20i"; - if (ijet==3) mynamehist += "_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_mu20"; - if (ijet==5) mynamehist += "_mu20"; - if (ijet==6) mynamehist += "_mu20"; - if (ijet==7) mynamehist += "_mu20"; - // mu50 - if (ijet==8) mynamehist += "_mu50"; - if (ijet==9) mynamehist += "_mu50"; - if (ijet==10) mynamehist += "_mu50"; - if (ijet==11) mynamehist += "_mu50"; - } - } - - // case for the HighMTW - if (ifile==1) { - if (choice==0) { // with details on njet - if (var<7) { - // mu20i - if (ijet==0) mynamehist += "_0b_1j_mu20i"; - if (ijet==1) mynamehist += "_0b_ge2j_mu20i"; - if (ijet==2) mynamehist += "_ge1b_1j_mu20i"; - if (ijet==3) mynamehist += "_ge1b_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_1j_mu20"; - if (ijet==5) mynamehist += "_0b_ge2j_mu20"; - if (ijet==6) mynamehist += "_ge1b_1j_mu20"; - if (ijet==7) mynamehist += "_ge1b_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_1j_mu50"; - if (ijet==9) mynamehist += "_0b_ge2j_mu50"; - if (ijet==10) mynamehist += "_ge1b_1j_mu50"; - if (ijet==11) mynamehist += "_ge1b_ge2j_mu50"; - } else if (var==7) { // njet - // mu20i - if (ijet==0) mynamehist += "_0b_mu20i"; - if (ijet==1) mynamehist += "_0b_mu20i"; - if (ijet==2) mynamehist += "_ge1b_mu20i"; - if (ijet==3) mynamehist += "_ge1b_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_mu20"; - if (ijet==5) mynamehist += "_0b_mu20"; - if (ijet==6) mynamehist += "_ge1b_mu20"; - if (ijet==7) mynamehist += "_ge1b_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_mu50"; - if (ijet==9) mynamehist += "_0b_mu50"; - if (ijet==10) mynamehist += "_ge1b_mu50"; - if (ijet==11) mynamehist += "_ge1b_mu50"; - } else if (var==8) { // nbjet - // mu20i - if (ijet==0) mynamehist += "_0b_1j_mu20i"; - if (ijet==1) mynamehist += "_0b_ge2j_mu20i"; - if (ijet==2) mynamehist += "_ge1b_1j_mu20i"; - if (ijet==3) mynamehist += "_ge1b_ge2j_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_0b_1j_mu20"; - if (ijet==5) mynamehist += "_0b_ge2j_mu20"; - if (ijet==6) mynamehist += "_ge1b_1j_mu20"; - if (ijet==7) mynamehist += "_ge1b_ge2j_mu20"; - // mu50 - if (ijet==8) mynamehist += "_0b_1j_mu50"; - if (ijet==9) mynamehist += "_0b_ge2j_mu50"; - if (ijet==10) mynamehist += "_ge1b_1j_mu50"; - if (ijet==11) mynamehist += "_ge1b_ge2j_mu50"; - } - } - // case for njet>=1 - if (choice==1) { // with details on njet - // mu20i - if (ijet==0) mynamehist += "_mu20i"; - if (ijet==1) mynamehist += "_mu20i"; - if (ijet==2) mynamehist += "_mu20i"; - if (ijet==3) mynamehist += "_mu20i"; - // mu20 - if (ijet==4) mynamehist += "_mu20"; - if (ijet==5) mynamehist += "_mu20"; - if (ijet==6) mynamehist += "_mu20"; - if (ijet==7) mynamehist += "_mu20"; - // mu50 - if (ijet==8) mynamehist += "_mu50"; - if (ijet==9) mynamehist += "_mu50"; - if (ijet==10) mynamehist += "_mu50"; - if (ijet==11) mynamehist += "_mu50"; - } - } - - std::cout << " ijet = " << ijet - << " namehist = " << mynamehist << std::endl; - plot[ifile][ijet] = (TH1F*)f[ifile]->Get(mynamehist); - std::cout << " ijet = " << ijet - << " plot = " << plot[ifile][ijet] << std::endl; - } - } - - // =============================================== - // set the TAxis range - m_nlines = 2; - m_eff[0] = 0.85; - m_eff[1] = 1.2; - if (var==0) {m_var[0] = 25.; m_var[1] = 150.;} // pt - if (var==1) {m_var[0] = 0.; m_var[1] = 2.3;} // eta - if (var==2) {m_var[0] = 0.; m_var[1] = 6.;} // dR - if (var==3) {m_var[0] = 25.; m_var[1] = 500.;} // jetpt - if (var==4) {m_var[0] = 0.; m_var[1] = 3.2;} // dphi - if (var==5) {m_var[0] = 0.; m_var[1] = 1000.;} // met - if (var==6) {m_var[0] = 0.; m_var[1] = 1000.;} // mtw - if (var==7) {m_var[0] = 0.; m_var[1] = 6.;} // njet - if (var==8) {m_var[0] = 0.; m_var[1] = 3.;} // nbjet - plot0 = new TGraph(m_nlines,m_var,m_eff); - - // plot the TGraph - plotGraph(var,choice,trigger,plot0,plot); - } - - // ============================================== - void plotGraph(int var,int choice,int trigger, - TGraph* plot0,TH1F* plot[2][20]) - { - // set the TCanvas - c1 = new TCanvas("c1"," ",0.,0.,800,600); - c1->SetFillColor(42); - c1->SetFillColor(10); - - // set the TAxis - plot0->SetFillColor(19); - plot0->SetLineColor(0); - plot0->SetLineWidth(4); - plot0->SetMarkerColor(0); - plot0->SetMarkerStyle(20); - //plot0->GetXaxis()->CenterLabels(true); - if (var==0) plot0->GetXaxis()->SetTitle("p_{T}(#mu) [GeV]"); - if (var==1) plot0->GetXaxis()->SetTitle("|#eta(#mu)|"); - if (var==2) plot0->GetXaxis()->SetTitle("#DeltaR (#mu, nearest jet)"); - if (var==3) plot0->GetXaxis()->SetTitle("p_{T}(leading jet) [GeV]"); - if (var==4) plot0->GetXaxis()->SetTitle("#Delta#phi (#mu,E_{T}^{miss})"); - if (var==5) plot0->GetXaxis()->SetTitle("E_{T}^{miss} [GeV]"); - if (var==6) plot0->GetXaxis()->SetTitle("m_{T}(#mu,E_{T}^{miss}) [GeV]"); - if (var==7) plot0->GetXaxis()->SetTitle("n_{jet}"); - if (var==8) plot0->GetXaxis()->SetTitle("n_{b-jet}"); - plot0->GetYaxis()->SetTitle("Efficiency"); - plot0->Draw("AP"); - - // ================================================================ - // choose the trigger - int it1 = -1; int it2 = -1; int it3 = -1; int it4 = -1; - if (trigger==0) {it1 = 0; it2 = 1; it3 = 2; it4 = 3;} // mu20i - if (trigger==1) {it1 = 4; it2 = 5; it3 = 6; it4 = 7;} // mu20 - if (trigger==2) {it1 = 8; it2 = 9; it3 = 10; it4 = 11;} // mu50 - - // plot the TGraph - if (choice==0) { // for different jet - // T&P - myplot(plot[0][it1],1,20); - myplot(plot[0][it2],1,24); - // High MTWW - myplot(plot[1][it1],1,21); - if (var!=7) myplot(plot[1][it2],2,22); // case for njet - myplot(plot[1][it3],3,23); - if (var!=7) myplot(plot[1][it4],4,29); // case for njet - - if (var==8) { // case for nbjet (use same colors) - myplot(plot[0][it1],1,20); - myplot(plot[0][it2],1,24); - - myplot(plot[1][it1],1,21); - myplot(plot[1][it2],3,22); - myplot(plot[1][it3],1,23); - myplot(plot[1][it4],3,29); - } - } - if (choice==1) { // for njet>=1 - if (var!=8) { - myplot(plot[0][it1],1,20); // T&P - myplot(plot[1][it1],2,21); // high MTW - } - if (var==8) { // case for nbjet (use same colors) - myplot(plot[0][it1],1,20); - myplot(plot[1][it1],2,21); - } - } - - c1->Update(); - c1->GetFrame()->SetFillColor(0); - c1->GetFrame()->SetBorderSize(0); - c1->Modified(); - // plot the TLegend - plotLegend(var,choice,trigger,plot); - c1->RedrawAxis(); - - // set the output filename - TString suffix = ""; - if (var==0) suffix = "_vsPt"; - if (var==1) suffix = "_vsEta"; - if (var==2) suffix = "_vsdR"; - if (var==3) suffix = "_vsPtLeadingJet"; - if (var==4) suffix = "_vsdPhi"; - if (var==5) suffix = "_vsMET"; - if (var==6) suffix = "_vsMTW"; - if (var==7) suffix = "_vsnjet"; - if (var==8) suffix = "_vsnbjet"; - - TString st = ""; - if (trigger==0) st = "_mu20i"; - if (trigger==1) st = "_mu20"; - if (trigger==2) st = "_mu50"; - - TString format = ""; - for (int i=0;i<3;i++) { - if (i==0) format = ".eps"; - if (i==1) format = ".pdf"; - if (i==2) format = ".png"; - - if (choice==0) - c1->SaveAs("fig/effrealTPHighMTW_muon"+st+suffix+format); - if (choice==1) - c1->SaveAs("fig/effrealTPHighMTW_muon_ge1j"+st+suffix+format); - } - } - - // ============================================== - void myplot(TH1F* plot,int mkcolor, int mktype, float size=1.5) - { - plot->SetFillColor(19); - plot->SetLineColor(1); - plot->SetLineWidth(1.5); - plot->SetMarkerColor(mkcolor); - plot->SetMarkerStyle(mktype); - //plot->SetTitle("rel 16"); - plot->SetMarkerSize(size); - plot->Draw("P sames"); - } - - // ============================================== - void plotLegend(int var,int choice,int trigger,TH1F* plot[2][20]) - { - float xlabel = 0.2; - float ylabel = 0.88; - // set the ATLAS label - ATLASLabel(xlabel,ylabel,"Work in Progress"); - // set energy and luminosity (adapt to your own case) - myText(xlabel+0.2,ylabel-0.06,1,"#sqrt{s}=13 TeV, 3.2 fb^{-1}",0.045); - - if (choice==0) myText(xlabel,ylabel-0.06,1,"#mu+jets mu20i",0.04); - if (choice==1) myText(xlabel,ylabel-0.06,1,"#mu+jets mu20",0.04); - if (choice==2) myText(xlabel,ylabel-0.06,1,"#mu+jets mu50",0.04); - - int it1 = -1; int it2 = -1; int it3 = -1; int it4 = -1; - if (trigger==0) {it1 = 0; it2 = 1; it3 = 2; it4 = 3;} // mu20i - if (trigger==1) {it1 = 4; it2 = 5; it3 = 6; it4 = 7;} // mu20 - if (trigger==2) {it1 = 8; it2 = 9; it3 = 10; it4 = 11;} // mu50 - - // ============================= - if (choice==0) { // with details on njet - if (var<7) { - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.035); - leg->AddEntry(plot[0][it1],"#epsilon_{r} tag-and-probe, 1 jet","ep"); - leg->AddEntry(plot[0][it2],"#epsilon_{r} tag-and-probe, #geq2 jets","ep"); - leg->Draw(); - - leg2 = new TLegend(0.5,ymin,0.8,ymax); - leg2->SetFillColor(0); - leg2->SetFillStyle(0); - leg2->SetBorderSize(0); - leg2->SetTextSize(0.035); - leg2->AddEntry(plot[1][it1],"#epsilon_{r} High m_{T}^{W}, 1 jet, 0 btag","ep"); - leg2->AddEntry(plot[1][it2],"#epsilon_{r} High m_{T}^{W}, #geq2 jets, 0 btag","ep"); - leg2->AddEntry(plot[1][it3],"#epsilon_{r} High m_{T}^{W}, 1 jet, #geq1 btag","ep"); - leg2->AddEntry(plot[1][it4],"#epsilon_{r} High m_{T}^{W}, #geq2 jets, #geq1 btag","ep"); - leg2->Draw(); - } - } - - // ============================================================ - // set the TLegend (adapt to your own team) - float ymin = 0.55; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - // ============================================================ - // set the TLegend (adapt to your own team) - - if (choice==0) { // with details on njet - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (var==7) { // case for njet - leg->AddEntry(plot[0][it1],"#epsilon_{r} tag-and-probe","ep"); - leg->AddEntry(plot[1][it1],"#epsilon_{r} High m_{T}^{W}, 0 btag","ep"); - leg->AddEntry(plot[1][it3],"#epsilon_{r} High m_{T}^{W}, #geq1 btag","ep"); - } else if (var==8) { // case for nbjet - leg->AddEntry(plot[0][it1],"#epsilon_{r} tag-and-probe, 1 jet","ep"); - leg->AddEntry(plot[0][it2],"#epsilon_{r} tag-and-probe, #geq2 jets","ep"); - leg->AddEntry(plot[1][it1],"#epsilon_{r} High m_{T}^{W}, 1 jet","ep"); - leg->AddEntry(plot[1][it2],"#epsilon_{r} High m_{T}^{W}, #geq2 jets","ep"); - } - leg->Draw(); - } - - if (choice==1) { // with njet>=1 - float ymin = 0.6; - float ymax = 0.8; - leg = new TLegend(0.2,ymin,0.3,ymax); - leg->SetFillColor(0); - leg->SetFillStyle(0); - leg->SetBorderSize(0); - leg->SetTextSize(0.04); - if (var!=8) { - leg->AddEntry(plot[0][it1],"#epsilon_{r} tag-and-probe, #geq 1 jet","ep"); - leg->AddEntry(plot[1][it1],"#epsilon_{r} High m_{T}^{W}, #geq 1 jet","ep"); - } - if (var==8) { // for nbjet - leg->AddEntry(plot[0][it1],"#epsilon_{r} tag-and-probe, #geq 1 jet","ep"); - leg->AddEntry(plot[1][it1],"#epsilon_{r} High m_{T}^{W}, #geq 1 jet","ep"); - } - leg->Draw(); - } - - } - -private: - - Float_t m_var[300]; - Float_t m_errvar[300]; - Float_t m_eff[300]; - Float_t m_erreff[300]; - - Int_t m_nlines; -}; -- GitLab From b1a0cbf22c15648732bc3df3582169fb67c6f378 Mon Sep 17 00:00:00 2001 From: Tomas Dado <tomas.dado@cern.ch> Date: Mon, 26 Oct 2020 13:40:54 +0100 Subject: [PATCH 02/12] First step porting AT to R22 --- .../TopDataPreparation/CMakeLists.txt | 8 +- .../TopDataPreparation/Root/LinkDef.h | 4 +- .../TopDataPreparation/Root/SamplePDF.cxx | 54 +- .../Root/SampleXsection.cxx | 247 +- .../Root/SampleXsectionSvc.cxx | 32 +- .../TopDataPreparation/SamplePDF.h | 32 +- .../TopDataPreparation/SampleXsection.h | 55 +- .../TopDataPreparation/SampleXsectionSvc.h | 61 +- .../TopDataPreparation/data/README.md | 5 + .../TopDataPreparation/python/getPDF.py | 18 +- .../TopPhys/xAOD/TopAnalysis/CMakeLists.txt | 68 +- .../Root/AnalysisTrackingHelper.cxx | 256 + .../TopAnalysis/Root/EventSaverFlatNtuple.cxx | 7696 ++++++++++++----- .../xAOD/TopAnalysis/Root/EventSaverxAOD.cxx | 232 +- .../TopAnalysis/Root/EventSaverxAODNext.cxx | 652 +- .../xAOD/TopAnalysis/Root/EventSelection.cxx | 932 +- .../Root/EventSelectionManager.cxx | 198 +- .../TopPhys/xAOD/TopAnalysis/Root/LinkDef.h | 4 +- .../xAOD/TopAnalysis/Root/MsgCategory.cxx | 6 + .../Root/ObjectLoaderStandardCuts.cxx | 138 +- .../TopPhys/xAOD/TopAnalysis/Root/Tools.cxx | 572 +- .../TopAnalysis/AnalysisTrackingHelper.h | 69 + .../TopAnalysis/TopAnalysis/EventSaverBase.h | 55 +- .../TopAnalysis/EventSaverFlatNtuple.h | 1183 ++- .../TopAnalysis/TopAnalysis/EventSaverxAOD.h | 25 +- .../TopAnalysis/EventSaverxAODNext.h | 134 +- .../TopAnalysis/TopAnalysis/EventSelection.h | 55 +- .../TopAnalysis/EventSelectionManager.h | 38 +- .../TopAnalysis/TopAnalysis/MsgCategory.h | 12 + .../TopAnalysis/ObjectLoaderBase.h | 15 +- .../TopAnalysis/ObjectLoaderStandardCuts.h | 13 +- .../xAOD/TopAnalysis/TopAnalysis/Tools.h | 107 +- .../TopAnalysis/scripts/CI_EMPFlowDatatest.py | 28 + .../TopAnalysis/scripts/CI_EMPFlowMCtest.py | 29 + .../TopAnalysis/scripts/CI_EMTopoDatatest.py | 28 + .../TopAnalysis/scripts/CI_EMTopoMCtest.py | 29 + .../xAOD/TopAnalysis/scripts/CI_test.py | 52 + ...nfigExampleMakeQuarkGluonFractionPlots.xml | 32 + .../scripts/MakeQuarkGluonFractionPlots.cxx | 771 ++ .../scripts/MakeQuarkGluonFractionPlots.h | 136 + .../TopPhys/xAOD/TopAnalysis/scripts/at-pkg | 3 - .../scripts/generate_art_configs.py | 96 + .../TopAnalysis/scripts/validation-data.py | 398 + .../xAOD/TopAnalysis/scripts/validation.py | 8 +- .../share/ART/artcut_test_410470afmc16a.txt | 666 ++ .../share/ART/artcut_test_410470afmc16d.txt | 659 ++ .../share/ART/artcut_test_410470fsmc16a.txt | 666 ++ .../ART/artcut_test_410470fsmc16apflow.txt | 666 ++ .../ART/artcut_test_410470fsmc16asysts.txt | 666 ++ .../share/ART/artcut_test_410470fsmc16d.txt | 659 ++ .../artcut_test_410470fsmc16dactualmurw.txt | 661 ++ .../ART/artcut_test_410470fsmc16dklfitter.txt | 659 ++ .../ART/artcut_test_410470fsmc16dpflow.txt | 659 ++ .../ART/artcut_test_410470fsmc16dsysts.txt | 659 ++ .../xAOD/TopAnalysis/share/example-config.txt | 286 + .../TopAnalysis/share/input-data-rel21.txt | 11 +- .../xAOD/TopAnalysis/share/input-mc-rel21.txt | 2 +- .../TopPhys/xAOD/TopAnalysis/share/nocuts.txt | 9 +- .../xAOD/TopAnalysis/share/upgrade-cuts.txt | 364 + .../share/validation-cuts-pflow.txt | 637 ++ .../TopAnalysis/share/validation-cuts.txt | 388 +- .../TopAnalysis/test/test_410470afmc16a.py | 60 + .../TopAnalysis/test/test_410470afmc16d.py | 60 + .../TopAnalysis/test/test_410470fsmc16a.py | 59 + .../test/test_410470fsmc16apflow.py | 60 + .../test/test_410470fsmc16asysts.py | 59 + .../TopAnalysis/test/test_410470fsmc16d.py | 60 + .../test/test_410470fsmc16dactualmurw.py | 60 + .../test/test_410470fsmc16dklfitter.py | 60 + .../test/test_410470fsmc16dpflow.py | 60 + .../test/test_410470fsmc16dsysts.py | 60 + .../xAOD/TopAnalysis/util/top-tool-ftag.cxx | 132 + .../xAOD/TopAnalysis/util/top-xaod.cxx | 1716 ++-- .../TopPhys/xAOD/TopCPTools/CMakeLists.txt | 25 +- .../Root/TopBoostedTaggingCPTools.cxx | 169 + .../xAOD/TopCPTools/Root/TopEgammaCPTools.cxx | 1053 ++- .../Root/TopFlavorTaggingCPTools.cxx | 576 +- .../TopCPTools/Root/TopGhostTrackCPTools.cxx | 287 +- .../TopCPTools/Root/TopIsolationCPTools.cxx | 209 +- .../xAOD/TopCPTools/Root/TopJetMETCPTools.cxx | 1005 ++- .../xAOD/TopCPTools/Root/TopMuonCPTools.cxx | 444 +- .../xAOD/TopCPTools/Root/TopOtherCPTools.cxx | 315 +- .../Root/TopOverlapRemovalCPTools.cxx | 409 +- .../xAOD/TopCPTools/Root/TopTauCPTools.cxx | 551 +- .../xAOD/TopCPTools/Root/TopToolStore.cxx | 209 +- .../xAOD/TopCPTools/Root/TopTrackCPTools.cxx | 177 + .../TopCPTools/Root/TopTriggerCPTools.cxx | 459 +- .../TopCPTools/TopBoostedTaggingCPTools.h | 38 + .../TopCPTools/TopCPTools/TopEgammaCPTools.h | 169 +- .../TopCPTools/TopFlavorTaggingCPTools.h | 76 +- .../TopCPTools/TopGhostTrackCPTools.h | 91 +- .../TopCPTools/TopIsolationCPTools.h | 36 +- .../TopCPTools/TopCPTools/TopJetMETCPTools.h | 112 +- .../TopCPTools/TopCPTools/TopMuonCPTools.h | 75 +- .../TopCPTools/TopCPTools/TopOtherCPTools.h | 48 +- .../TopCPTools/TopOverlapRemovalCPTools.h | 48 +- .../TopCPTools/TopCPTools/TopTauCPTools.h | 46 +- .../xAOD/TopCPTools/TopCPTools/TopToolStore.h | 106 +- .../TopCPTools/TopCPTools/TopTrackCPTools.h | 68 + .../TopCPTools/TopCPTools/TopTriggerCPTools.h | 55 +- .../xAOD/TopConfiguration/CMakeLists.txt | 27 +- .../Root/AodMetaDataAccess.cxx | 217 +- .../Root/ConfigurationSettings.cxx | 1056 ++- .../xAOD/TopConfiguration/Root/JsonUtils.cxx | 97 + .../xAOD/TopConfiguration/Root/LinkDef.h | 4 +- .../TopConfiguration/Root/MsgCategory.cxx | 6 + .../xAOD/TopConfiguration/Root/TopConfig.cxx | 3750 +++++--- .../Root/TopPersistentSettings.cxx | 36 +- .../xAOD/TopConfiguration/Root/TreeFilter.cxx | 53 + .../TopConfiguration/AodMetaDataAccess.h | 117 +- .../TopConfiguration/ConfigurationSettings.h | 43 +- .../TopConfiguration/JsonUtils.h | 85 + .../TopConfiguration/MsgCategory.h | 11 + .../SelectionConfigurationData.h | 10 +- .../TopConfiguration/StringData.h | 10 +- .../TopConfiguration/Tokenize.h | 85 +- .../TopConfiguration/TopConfig.h | 4070 ++++++--- .../TopConfiguration/TopPersistentSettings.h | 171 +- .../TopConfiguration/TreeFilter.h | 28 + .../xAOD/TopCorrections/CMakeLists.txt | 25 +- .../Root/BTagScaleFactorCalculator.cxx | 312 +- .../Root/ElectronScaleFactorCalculator.cxx | 1183 ++- .../Root/FwdElectronScaleFactorCalculator.cxx | 125 + .../Root/GlobalLeptonTriggerCalculator.cxx | 201 + .../Root/JetScaleFactorCalculator.cxx | 117 +- .../xAOD/TopCorrections/Root/LinkDef.h | 18 + .../xAOD/TopCorrections/Root/MsgCategory.cxx | 6 + .../Root/MuonScaleFactorCalculator.cxx | 354 +- .../Root/PDFScaleFactorCalculator.cxx | 145 +- .../Root/PhotonScaleFactorCalculator.cxx | 319 +- .../Root/PileupScaleFactorCalculator.cxx | 108 +- .../Root/ScaleFactorCalculator.cxx | 363 +- .../Root/ScaleFactorRetriever.cxx | 1030 ++- .../Root/TauScaleFactorCalculator.cxx | 230 +- .../Root/TopCorrectionsTools.cxx | 62 + .../BTagScaleFactorCalculator.h | 95 +- .../ElectronScaleFactorCalculator.h | 177 +- .../FwdElectronScaleFactorCalculator.h | 63 + .../GlobalLeptonTriggerCalculator.h | 68 + .../TopCorrections/JetScaleFactorCalculator.h | 65 +- .../TopCorrections/MsgCategory.h | 10 + .../MuonScaleFactorCalculator.h | 343 +- .../TopCorrections/PDFScaleFactorCalculator.h | 49 +- .../PhotonScaleFactorCalculator.h | 96 +- .../PileupScaleFactorCalculator.h | 48 +- .../TopCorrections/ScaleFactorCalculator.h | 89 +- .../TopCorrections/ScaleFactorRetriever.h | 652 +- .../TopCorrections/TauScaleFactorCalculator.h | 68 +- .../TopCorrections/TopCorrectionsTools.h | 21 + .../TopPhys/xAOD/TopEvent/CMakeLists.txt | 26 +- .../TopPhys/xAOD/TopEvent/Root/Event.cxx | 210 +- .../TopPhys/xAOD/TopEvent/Root/EventTools.cxx | 62 +- .../xAOD/TopEvent/Root/KLFitterResult.cxx | 359 +- .../TopPhys/xAOD/TopEvent/Root/LinkDef.h | 8 +- .../xAOD/TopEvent/Root/PseudoTopResult.cxx | 80 +- .../TopPhys/xAOD/TopEvent/Root/RCJetMC15.cxx | 653 ++ .../xAOD/TopEvent/Root/SystematicEvent.cxx | 69 +- .../xAOD/TopEvent/Root/TopEventMaker.cxx | 595 +- .../TopPhys/xAOD/TopEvent/TopEvent/Event.h | 143 +- .../xAOD/TopEvent/TopEvent/EventTools.h | 88 +- .../xAOD/TopEvent/TopEvent/KLFitterResult.h | 940 +- .../xAOD/TopEvent/TopEvent/PseudoTopResult.h | 50 +- .../xAOD/TopEvent/TopEvent/RCJetMC15.h | 161 + .../xAOD/TopEvent/TopEvent/SystematicEvent.h | 211 +- .../xAOD/TopEvent/TopEvent/TopEventMaker.h | 104 +- .../CMakeLists.txt | 23 +- .../Root/Chi2LJets.cxx | 165 +- .../Root/KLFitterRun.cxx | 45 +- .../Root/KLFitterTool.cxx | 1223 ++- .../Root/LinkDef.h | 4 +- .../Root/MT2Reco.cxx | 18 +- .../Root/NeutrinoWeighting.cxx | 133 +- .../Root/PTMaxReco.cxx | 103 +- .../Root/PseudoTopReco.cxx | 409 +- .../Root/PseudoTopRecoRun.cxx | 37 +- .../Root/Sonnenschein.cxx | 108 +- .../Root/SonnenscheinEngine.cxx | 576 +- .../TopEventReconstructionToolsLoader.cxx | 25 +- .../Root/TtresChi2.cxx | 1115 +-- .../Root/TtresNeutrinoBuilder.cxx | 463 +- .../Root/TtresdRmin.cxx | 147 +- .../TopEventReconstructionTools/Chi2LJets.h | 26 +- .../TopEventReconstructionTools/KLFitterRun.h | 31 +- .../KLFitterTool.h | 181 +- .../TopEventReconstructionTools/MT2Reco.h | 15 +- .../NeutrinoWeighting.h | 44 +- .../TopEventReconstructionTools/PTMaxReco.h | 21 +- .../PseudoTopReco.h | 133 +- .../PseudoTopRecoRun.h | 22 +- .../Sonnenschein.h | 21 +- .../SonnenscheinEngine.h | 21 +- .../TopEventReconstructionToolsLoader.h | 15 +- .../TopEventReconstructionTools/TtresChi2.h | 156 +- .../TtresNeutrinoBuilder.h | 25 +- .../TopEventReconstructionTools/TtresdRmin.h | 45 +- .../util/topreco_test_mt2.cxx | 29 +- .../TopEventSelectionTools/CMakeLists.txt | 16 +- .../Root/ExamplePlots.cxx | 362 +- .../Root/FakesMMConfigs.cxx | 8 +- .../Root/GRLSelector.cxx | 15 +- .../Root/GlobalTrigDecisionSelector.cxx | 33 + .../Root/GlobalTrigMatchSelector.cxx | 39 + .../Root/GoodCaloSelector.cxx | 15 +- .../Root/HTSelector.cxx | 41 +- .../Root/InitialSelector.cxx | 14 +- .../Root/JetCleaningSelector.cxx | 139 +- .../Root/JetFlavorPlots.cxx | 276 +- .../Root/JetFtagEffPlots.cxx | 393 + .../Root/JetNGhostSelector.cxx | 195 +- .../Root/JetResponsePlots.cxx | 152 + .../Root/KLFitterSelector.cxx | 29 +- .../TopEventSelectionTools/Root/LinkDef.h | 4 +- .../Root/METMWTSelector.cxx | 48 +- .../Root/METSelector.cxx | 24 +- .../Root/MLLSelector.cxx | 59 +- .../Root/MLLWindowSelector.cxx | 55 +- .../Root/MV2c10Selector.cxx | 29 +- .../Root/MWTSelector.cxx | 48 +- .../Root/MsgCategory.cxx | 6 + .../Root/NElectronNMuonSelector.cxx | 42 +- .../Root/NElectronNMuonTightSelector.cxx | 42 +- .../Root/NElectronSelector.cxx | 33 +- .../Root/NElectronTightSelector.cxx | 33 +- .../Root/NFwdElectronSelector.cxx | 26 + .../Root/NFwdElectronTightSelector.cxx | 32 + .../Root/NJetBtagSelector.cxx | 66 +- .../Root/NJetSelector.cxx | 33 +- .../Root/NLargeJetSelector.cxx | 18 +- .../Root/NMuonSelector.cxx | 33 +- .../Root/NMuonTightSelector.cxx | 33 +- .../Root/NPhotonSelector.cxx | 32 +- .../Root/NRCJetSelector.cxx | 30 + .../Root/NSoftMuonSelector.cxx | 28 + .../Root/NTauSelector.cxx | 33 +- .../Root/NTauTightSelector.cxx | 21 +- .../Root/NVarRCJetSelector.cxx | 40 + .../Root/NoBadMuonSelector.cxx | 29 +- .../Root/OSLeptonSelector.cxx | 52 +- .../Root/OSLeptonTightSelector.cxx | 52 +- .../Root/ParticleLevelSelector.cxx | 35 +- .../Root/PlotManager.cxx | 205 +- .../Root/PrimaryVertexSelector.cxx | 15 +- .../Root/PrintEventSelector.cxx | 30 +- .../Root/RecoLevelSelector.cxx | 35 +- .../Root/RunNumberSelector.cxx | 34 +- .../Root/SSLeptonSelector.cxx | 53 +- .../Root/SSLeptonTightSelector.cxx | 53 +- .../Root/SaveEventSelector.cxx | 14 +- .../Root/SignValueSelector.cxx | 228 +- .../Root/TopEventSelectionToolsLoader.cxx | 183 +- .../Root/TrackJetCleaningSelector.cxx | 31 + .../Root/TreeManager.cxx | 195 +- .../Root/TrigDecisionLooseSelector.cxx | 46 + .../Root/TrigDecisionSelector.cxx | 28 +- .../Root/TrigDecisionTightSelector.cxx | 46 + .../Root/TrigMatchSelector.cxx | 65 +- .../EventSelectorBase.h | 16 +- .../TopEventSelectionTools/ExamplePlots.h | 23 +- .../TopEventSelectionTools/FakesMMConfigs.h | 15 +- .../TopEventSelectionTools/GRLSelector.h | 52 +- .../GlobalTrigDecisionSelector.h | 34 + .../GlobalTrigMatchSelector.h | 34 + .../TopEventSelectionTools/GoodCaloSelector.h | 50 +- .../TopEventSelectionTools/HTSelector.h | 12 +- .../TopEventSelectionTools/InitialSelector.h | 10 +- .../JetCleaningSelector.h | 28 +- .../TopEventSelectionTools/JetFlavorPlots.h | 127 +- .../TopEventSelectionTools/JetFtagEffPlots.h | 123 + .../JetNGhostSelector.h | 81 +- .../TopEventSelectionTools/JetResponsePlots.h | 96 + .../TopEventSelectionTools/KLFitterSelector.h | 19 +- .../TopEventSelectionTools/METMWTSelector.h | 12 +- .../TopEventSelectionTools/METSelector.h | 12 +- .../TopEventSelectionTools/MLLSelector.h | 12 +- .../MLLWindowSelector.h | 15 +- .../TopEventSelectionTools/MV2c10Selector.h | 12 +- .../TopEventSelectionTools/MWTSelector.h | 12 +- .../TopEventSelectionTools/MsgCategory.h | 10 + .../NElectronNMuonSelector.h | 14 +- .../NElectronNMuonTightSelector.h | 14 +- .../NElectronSelector.h | 12 +- .../NElectronTightSelector.h | 12 +- .../NFwdElectronSelector.h | 28 + .../NFwdElectronTightSelector.h | 25 + .../TopEventSelectionTools/NJetBtagSelector.h | 15 +- .../TopEventSelectionTools/NJetSelector.h | 12 +- .../NLargeJetSelector.h | 12 +- .../TopEventSelectionTools/NMuonSelector.h | 12 +- .../NMuonTightSelector.h | 12 +- .../TopEventSelectionTools/NPhotonSelector.h | 14 +- .../TopEventSelectionTools/NRCJetSelector.h | 21 + .../NSoftMuonSelector.h | 24 + .../TopEventSelectionTools/NTauSelector.h | 12 +- .../NTauTightSelector.h | 12 +- .../NVarRCJetSelector.h | 22 + .../NoBadMuonSelector.h | 19 +- .../TopEventSelectionTools/OSLeptonSelector.h | 12 +- .../OSLeptonTightSelector.h | 12 +- .../ParticleLevelSelector.h | 59 +- .../TopEventSelectionTools/PlotManager.h | 81 +- .../PrimaryVertexSelector.h | 54 +- .../PrintEventSelector.h | 13 +- .../RecoLevelSelector.h | 59 +- .../RunNumberSelector.h | 18 +- .../TopEventSelectionTools/SSLeptonSelector.h | 12 +- .../SSLeptonTightSelector.h | 12 +- .../SaveEventSelector.h | 10 +- .../SignValueSelector.h | 50 +- .../TopEventSelectionTools/ToolLoaderBase.h | 16 +- .../TopEventSelectionToolsLoader.h | 15 +- .../TrackJetCleaningSelector.h | 30 + .../TopEventSelectionTools/TreeManager.h | 71 +- .../TrigDecisionLooseSelector.h | 63 + .../TrigDecisionSelector.h | 89 +- .../TrigDecisionTightSelector.h | 63 + .../TrigMatchSelector.h | 43 +- .../TopPhys/xAOD/TopExamples/CMakeLists.txt | 4 + .../TopPhys/xAOD/TopExamples/README.md | 40 + .../xAOD/TopExamples/Root/AnalysisTools.cxx | 93 +- .../xAOD/TopExamples/Root/ContainerNames.cxx | 24 +- .../xAOD/TopExamples/Root/DefaultPlots.cxx | 98 +- .../TopExamples/Root/DileptonAnalysis.cxx | 201 +- .../TopExamples/Root/EventLoaderDirect.cxx | 79 +- .../xAOD/TopExamples/Root/LJetsAnalysis.cxx | 105 +- .../TopExamples/Root/LJetsTtresAnalysis.cxx | 215 +- .../xAOD/TopExamples/Root/MakeTopConfig.cxx | 26 +- .../TopExamples/Root/MiniToFlatAnalysis.cxx | 28 +- .../TopExamples/Root/MinixAODAnalysis.cxx | 138 +- .../TopExamples/Root/NoSelectionAnalysis.cxx | 62 +- .../TopExamples/TopExamples/AnalysisBase.h | 24 +- .../TopExamples/TopExamples/AnalysisTools.h | 22 +- .../TopExamples/TopExamples/ContainerNames.h | 12 +- .../TopExamples/TopExamples/DefaultPlots.h | 13 +- .../TopExamples/DileptonAnalysis.h | 20 +- .../TopExamples/EventLoaderDirect.h | 17 +- .../TopExamples/TopExamples/LJetsAnalysis.h | 20 +- .../TopExamples/LJetsTtresAnalysis.h | 17 +- .../TopExamples/TopExamples/MakeTopConfig.h | 23 +- .../TopExamples/MiniToFlatAnalysis.h | 49 +- .../TopExamples/MinixAODAnalysis.h | 68 +- .../TopExamples/NoSelectionAnalysis.h | 17 +- .../xAOD/TopExamples/python/AtlasStyle.py | 4 +- .../xAOD/TopExamples/python/__init__.py | 1 - .../TopPhys/xAOD/TopExamples/python/ami.py | 282 +- .../xAOD/TopExamples/python/analysis.py | 58 +- .../TopPhys/xAOD/TopExamples/python/grid.py | 592 +- .../TopPhys/xAOD/TopExamples/python/logger.py | 4 +- .../TopPhys/xAOD/TopExamples/python/plot.py | 12 +- .../TopPhys/xAOD/TopExamples/python/web.py | 36 +- .../TopExamples/scripts/01SubmitToGrid.py | 60 +- .../xAOD/TopExamples/scripts/Data_rel21.py | 337 +- .../xAOD/TopExamples/scripts/MC16_TOPQ1.py | 206 +- .../xAOD/TopExamples/scripts/getExamples | 26 +- .../TopExamples/util/combineATOutputs.cxx | 168 + .../TopPhys/xAOD/TopHLUpgrade/CMakeLists.txt | 38 - .../TopPhys/xAOD/TopHLUpgrade/Root/LinkDef.h | 12 - .../Root/UpgradeLeptonObjectSelector.cxx | 39 - .../TopHLUpgrade/Root/UpgradeObjectLoader.cxx | 295 - .../Root/UpgradePerformanceFunctionsxAOD.cxx | 83 - .../UpgradeLeptonObjectSelector.h | 44 - .../TopHLUpgrade/UpgradeObjectLoader.h | 101 - .../UpgradePerformanceFunctionsxAOD.h | 54 - .../xAOD/TopJetSubstructure/CMakeLists.txt | 3 - .../ElectronInJetSubtractionAlgorithm.cxx | 27 +- .../Root/LargeJetTrimmer.cxx | 12 +- .../TopJetSubstructure/Root/SubjetMaker.cxx | 27 +- .../Root/TTBarElectronJetOverlap.cxx | 603 +- .../Root/TopJetSubstructure.cxx | 5 +- .../ElectronInJetSubtractionAlgorithm.h | 37 +- .../TopJetSubstructure/LargeJetTrimmer.h | 16 +- .../TopJetSubstructure/SubjetMaker.h | 16 +- .../TTBarElectronJetOverlap.h | 110 +- .../TopJetSubstructure/TopJetSubstructure.h | 18 +- .../TopObjectSelectionTools/CMakeLists.txt | 42 +- .../Root/AntiMuonMC15.cxx | 126 +- .../Root/ElectronCutBasedMC15.cxx | 63 +- .../Root/ElectronLikelihoodMC15.cxx | 286 +- .../Root/ElectronSelectionBase.cxx | 18 +- .../Root/EventCleaningSelection.cxx | 615 +- .../Root/FwdElectronSelectionBase.cxx | 20 + .../Root/IsolationTools.cxx | 246 +- .../Root/JetGhostTrackSelection.cxx | 90 + .../Root/JetGhostTrackSelectionBase.cxx | 18 + .../TopObjectSelectionTools/Root/JetMC15.cxx | 46 +- .../Root/JetSelectionBase.cxx | 18 +- .../TopObjectSelectionTools/Root/LinkDef.h | 10 +- .../Root/MsgCategory.cxx | 6 + .../TopObjectSelectionTools/Root/MuonMC15.cxx | 112 +- .../Root/MuonSelectionBase.cxx | 18 +- .../Root/OverlapRemovalASG.cxx | 84 +- .../Root/OverlapRemovalBase.cxx | 18 +- .../Root/OverlapRemovalIndices.cxx | 197 +- .../Root/PhotonMC16.cxx | 118 + .../Root/PhotonSelectionBase.cxx | 18 +- .../Root/SoftMuonMC15.cxx | 30 + .../Root/SoftMuonSelectionBase.cxx | 18 + .../TopObjectSelectionTools/Root/TauMC15.cxx | 81 +- .../Root/TauSelectionBase.cxx | 20 +- .../Root/TopObjectSelection.cxx | 1613 ++-- .../Root/TrackJetMC15.cxx | 27 +- .../Root/TrackSelection.cxx | 54 + .../Root/TrackSelectionBase.cxx | 18 + .../Root/TruthSelectionBase.cxx | 18 +- .../Root/TruthSelectionTtres.cxx | 29 +- .../TopObjectSelectionTools/AntiMuonMC15.h | 130 +- .../ElectronCutBasedMC15.h | 22 +- .../ElectronLikelihoodMC15.h | 212 +- .../ElectronSelectionBase.h | 16 +- .../EventCleaningSelection.h | 178 +- .../FwdElectronSelectionBase.h | 49 + .../TopObjectSelectionTools/IsolationTools.h | 57 +- .../JetGhostTrackSelection.h | 42 + .../JetGhostTrackSelectionBase.h | 28 + .../TopObjectSelectionTools/JetMC15.h | 143 +- .../JetSelectionBase.h | 14 +- .../TopObjectSelectionTools/MsgCategory.h | 11 + .../TopObjectSelectionTools/MuonMC15.h | 119 +- .../MuonSelectionBase.h | 21 +- .../OverlapRemovalASG.h | 143 +- .../OverlapRemovalBase.h | 36 +- .../OverlapRemovalIndices.h | 126 +- .../TopObjectSelectionTools/PhotonMC16.h | 110 + .../PhotonSelectionBase.h | 18 +- .../TopObjectSelectionTools/SoftMuonMC15.h | 51 + .../SoftMuonSelectionBase.h | 35 + .../TopObjectSelectionTools/TauMC15.h | 78 +- .../TauSelectionBase.h | 20 +- .../TopObjectSelection.h | 206 +- .../TopObjectSelectionTools/TrackJetMC15.h | 24 +- .../TopObjectSelectionTools/TrackSelection.h | 30 + .../TrackSelectionBase.h | 25 + .../TruthSelectionBase.h | 42 +- .../TruthSelectionTtres.h | 66 +- .../xAOD/TopParticleLevel/CMakeLists.txt | 31 +- .../TopParticleLevel/Root/MsgCategory.cxx | 6 + .../ParticleLevelElectronObjectSelector.cxx | 104 +- .../Root/ParticleLevelEvent.cxx | 94 + .../Root/ParticleLevelJetObjectSelector.cxx | 42 +- .../Root/ParticleLevelLoader.cxx | 1194 ++- .../Root/ParticleLevelMuonObjectSelector.cxx | 104 +- .../ParticleLevelPhotonObjectSelector.cxx | 238 +- .../Root/ParticleLevelRCJetObjectLoader.cxx | 406 + .../Root/ParticleLevelTauObjectSelector.cxx | 55 + .../xAOD/TopParticleLevel/Root/TruthTools.cxx | 1424 ++- .../TopParticleLevel/MsgCategory.h | 11 + .../TopParticleLevel/ObjectSelectorBase.h | 19 +- .../ParticleLevelElectronObjectSelector.h | 58 +- .../TopParticleLevel/ParticleLevelEvent.h | 101 +- .../ParticleLevelJetObjectSelector.h | 42 +- .../TopParticleLevel/ParticleLevelLoader.h | 187 +- .../ParticleLevelMuonObjectSelector.h | 58 +- .../ParticleLevelPhotonObjectSelector.h | 64 +- .../ParticleLevelRCJetObjectLoader.h | 139 + .../ParticleLevelTauObjectSelector.h | 36 + .../TopParticleLevel/TruthTools.h | 348 +- .../TopPhys/xAOD/TopPartons/CMakeLists.txt | 10 +- .../TopPartons/Root/CalcTTZPartonHistory.cxx | 197 + .../Root/CalcTbbarPartonHistory.cxx | 212 +- .../TopPartons/Root/CalcThqPartonHistory.cxx | 196 + .../TopPartons/Root/CalcTopPartonHistory.cxx | 820 +- .../Root/CalcTtbarGammaPartonHistory.cxx | 400 + .../Root/CalcTtbarLightPartonHistory.cxx | 165 + .../Root/CalcTtbarPartonHistory.cxx | 326 +- .../TopPartons/Root/CalcTzqPartonHistory.cxx | 208 + .../TopPartons/Root/CalcWlvPartonHistory.cxx | 131 +- .../TopPartons/Root/CalcWtbPartonHistory.cxx | 184 + .../TopPhys/xAOD/TopPartons/Root/LinkDef.h | 4 +- .../xAOD/TopPartons/Root/PartonHistory.cxx | 767 +- .../TopPartons/Root/PartonHistoryUtils.cxx | 183 + .../TopPartons/CalcTTZPartonHistory.h | 54 + .../TopPartons/CalcTbbarPartonHistory.h | 59 +- .../TopPartons/CalcThqPartonHistory.h | 61 + .../TopPartons/CalcTopPartonHistory.h | 142 +- .../TopPartons/CalcTtbarGammaPartonHistory.h | 50 + .../TopPartons/CalcTtbarLightPartonHistory.h | 48 + .../TopPartons/CalcTtbarPartonHistory.h | 59 +- .../TopPartons/CalcTzqPartonHistory.h | 64 + .../TopPartons/CalcWlvPartonHistory.h | 59 +- .../TopPartons/CalcWtbPartonHistory.h | 46 + .../TopPartons/TopPartons/PartonHistory.h | 96 +- .../TopPartons/PartonHistoryUtils.h | 56 + .../TopSystematicObjectMaker/CMakeLists.txt | 19 +- .../Root/EgammaObjectCollectionMaker.cxx | 703 +- ...lectronInJetSubtractionCollectionMaker.cxx | 138 +- .../Root/GhostTrackSystematicsMaker.cxx | 932 +- .../Root/JetObjectCollectionMaker.cxx | 1360 +-- .../Root/MissingETObjectCollectionMaker.cxx | 522 +- .../Root/MuonObjectCollectionMaker.cxx | 425 +- .../Root/ObjectCollectionMaker.cxx | 277 +- .../Root/SoftMuonObjectCollectionMaker.cxx | 196 + .../Root/TauObjectCollectionMaker.cxx | 162 +- .../Root/TrackSystematicsMaker.cxx | 487 ++ .../EgammaObjectCollectionMaker.h | 179 +- .../ElectronInJetSubtractionCollectionMaker.h | 80 +- .../GhostTrackSystematicsMaker.h | 333 +- .../JetObjectCollectionMaker.h | 258 +- .../MissingETObjectCollectionMaker.h | 108 +- .../MuonObjectCollectionMaker.h | 141 +- .../ObjectCollectionMaker.h | 75 +- .../SoftMuonObjectCollectionMaker.h | 77 + .../TauObjectCollectionMaker.h | 73 +- .../TrackSystematicsMaker.h | 152 + 502 files changed, 62944 insertions(+), 27525 deletions(-) create mode 100644 PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/data/README.md create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/AnalysisTrackingHelper.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/MsgCategory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/AnalysisTrackingHelper.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/MsgCategory.h create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMPFlowDatatest.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMPFlowMCtest.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMTopoDatatest.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMTopoMCtest.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_test.py create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/ConfigExampleMakeQuarkGluonFractionPlots.xml create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/MakeQuarkGluonFractionPlots.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/MakeQuarkGluonFractionPlots.h create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/generate_art_configs.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/validation-data.py create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470afmc16a.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470afmc16d.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16a.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16apflow.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16asysts.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16d.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dactualmurw.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dklfitter.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dpflow.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dsysts.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/example-config.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/upgrade-cuts.txt create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts-pflow.txt create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470afmc16a.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470afmc16d.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16a.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16apflow.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16asysts.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16d.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dactualmurw.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dklfitter.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dpflow.py create mode 100755 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dsysts.py create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-tool-ftag.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopBoostedTaggingCPTools.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTrackCPTools.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopBoostedTaggingCPTools.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTrackCPTools.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/JsonUtils.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/MsgCategory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TreeFilter.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/JsonUtils.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/MsgCategory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TreeFilter.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/FwdElectronScaleFactorCalculator.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/GlobalLeptonTriggerCalculator.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/LinkDef.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/MsgCategory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/TopCorrectionsTools.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/FwdElectronScaleFactorCalculator.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/GlobalLeptonTriggerCalculator.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/MsgCategory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/TopCorrectionsTools.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/RCJetMC15.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/RCJetMC15.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigDecisionSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigMatchSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetFtagEffPlots.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetResponsePlots.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MsgCategory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NFwdElectronSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NFwdElectronTightSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NRCJetSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NSoftMuonSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NVarRCJetSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrackJetCleaningSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionLooseSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionTightSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GlobalTrigDecisionSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GlobalTrigMatchSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetFtagEffPlots.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetResponsePlots.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MsgCategory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NFwdElectronSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NFwdElectronTightSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NRCJetSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NSoftMuonSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NVarRCJetSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrackJetCleaningSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionLooseSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionTightSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopExamples/README.md create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopExamples/util/combineATOutputs.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/CMakeLists.txt delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/LinkDef.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradeLeptonObjectSelector.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradeObjectLoader.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradePerformanceFunctionsxAOD.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradeLeptonObjectSelector.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradeObjectLoader.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradePerformanceFunctionsxAOD.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/FwdElectronSelectionBase.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetGhostTrackSelection.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetGhostTrackSelectionBase.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MsgCategory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/PhotonMC16.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/SoftMuonMC15.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/SoftMuonSelectionBase.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackSelection.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackSelectionBase.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/FwdElectronSelectionBase.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetGhostTrackSelection.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetGhostTrackSelectionBase.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MsgCategory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/PhotonMC16.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/SoftMuonMC15.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/SoftMuonSelectionBase.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackSelection.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackSelectionBase.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/MsgCategory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelEvent.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelRCJetObjectLoader.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelTauObjectSelector.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/MsgCategory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelRCJetObjectLoader.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelTauObjectSelector.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTTZPartonHistory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcThqPartonHistory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarGammaPartonHistory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarLightPartonHistory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTzqPartonHistory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcWtbPartonHistory.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/PartonHistoryUtils.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTTZPartonHistory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcThqPartonHistory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarGammaPartonHistory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarLightPartonHistory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTzqPartonHistory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcWtbPartonHistory.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/PartonHistoryUtils.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/SoftMuonObjectCollectionMaker.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/TrackSystematicsMaker.cxx create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/SoftMuonObjectCollectionMaker.h create mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/TrackSystematicsMaker.h diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/CMakeLists.txt b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/CMakeLists.txt index 9d568ba0a74c..006d0fda5b55 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/CMakeLists.txt @@ -1,15 +1,15 @@ +# Auto-generated on: 2017-03-09 17:44:33.125987 # Declare the name of this package: -atlas_subdir( TopDataPreparation ) +atlas_subdir( TopDataPreparation None ) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopDataPreparation _cintDictSource - ROOT_HEADERS TopDataPreparation/SampleXsection.h - TopDataPreparation/SampleXsectionSvc.h Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) # Build a library that other components can link against: atlas_add_library( TopDataPreparation Root/*.cxx Root/*.h Root/*.icc diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/LinkDef.h index 287a5ea504c1..a28d094e3236 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/LinkDef.h +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/LinkDef.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifdef __CINT__ #pragma extra_include "TopDataPreparation/SampleXsection.h"; diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SamplePDF.cxx b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SamplePDF.cxx index 8536dec6b3f4..551b7f53d517 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SamplePDF.cxx +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SamplePDF.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include <fstream> #include <sstream> @@ -12,28 +12,30 @@ using namespace std; -SamplePDF &SamplePDF::operator=(const SamplePDF &xs) -{ - if (this!=&xs) { - m_PDFs=xs.m_PDFs; +SamplePDF& SamplePDF::operator = (const SamplePDF& xs) { + if (this != &xs) { + m_PDFs = xs.m_PDFs; } return *this; } -bool SamplePDF::readFromFile(const char *fName) -{ +bool SamplePDF::readFromFile(const char* fName) { ifstream in(fName); - if (!in) {cerr << "SamplePDF::readFromFile : issue with " << fName << endl; return false;} - for( ; !in.eof() ; ) { + if (!in) { + cerr << "SamplePDF::readFromFile : issue with " << fName << endl; + return false; + } + + for (; !in.eof(); ) { string line; - if (!getline(in,line)) break; - if (!line.empty() && line[0]!='#') { + if (!getline(in, line)) break; + if (!line.empty() && line[0] != '#') { istringstream istr(line); - int dsid, PDFid=-1; + int dsid, PDFid = -1; istr >> dsid >> PDFid; //cout << dsid << "\t" << PDFid << endl; - setSample(dsid,PDFid); + setSample(dsid, PDFid); } } @@ -41,21 +43,21 @@ bool SamplePDF::readFromFile(const char *fName) return true; } -void SamplePDF::setSample(const int dsid, const int PDFid) -{ - if (dsid<0) return; - map<int, int >::const_iterator it=m_PDFs.find(dsid); - if (it!=m_PDFs.end()) { - cerr << "ERROR!! SamplePDF::setSample: duplicate entry ! DSID= " << dsid <<endl; - //cerr << "ERROR!! SamplePDF::setSample: xSect=" << xSect << "\told xSect=" << it->second.first <<endl; +void SamplePDF::setSample(const int dsid, const int PDFid) { + if (dsid < 0) return; + + map<int, int >::const_iterator it = m_PDFs.find(dsid); + if (it != m_PDFs.end()) { + cerr << "ERROR!! SamplePDF::setSample: duplicate entry ! DSID= " << dsid << endl; + //cerr << "ERROR!! SamplePDF::setSample: xSect=" << xSect << "\told xSect=" << it->second.first + // <<endl; } - m_PDFs[dsid]=PDFid; + m_PDFs[dsid] = PDFid; } +int SamplePDF::getPDFid(const int dsid) const { + map<int, int >::const_iterator it = m_PDFs.find(dsid); + if (it != m_PDFs.end()) return it->second; -int SamplePDF::getPDFid(const int dsid) const -{ - map<int,int >::const_iterator it=m_PDFs.find(dsid); - if (it!=m_PDFs.end()) return it->second; return unknown; } diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SampleXsection.cxx b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SampleXsection.cxx index 92c97f4ca9e7..f7a15ec031ef 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SampleXsection.cxx +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SampleXsection.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include <fstream> #include <sstream> @@ -12,64 +12,57 @@ using namespace std; -SampleXsection &SampleXsection::operator=(const SampleXsection &xs) -{ - if (this!=&xs) { - m_Xsects=xs.m_Xsects; - m_Uncert=xs.m_Uncert; +SampleXsection& SampleXsection::operator = (const SampleXsection& xs) { + if (this != &xs) { + m_Xsects = xs.m_Xsects; + m_Uncert = xs.m_Uncert; } return *this; } -bool SampleXsection::readFromFile(const char *fName) -{ +bool SampleXsection::readFromFile(const char* fName) { ifstream in(fName); + if (!in) return false; - for( ; !in.eof() ; ) { + for (; !in.eof(); ) { string line; - if (!getline(in,line)) break; - if (!line.empty() && line[0]!='#') { + if (!getline(in, line)) break; + if (!line.empty() && line[0] != '#') { istringstream istr(line); - int dsid=-1; - double xSect,kFact,xSectDw,xSectUp; + int dsid = -1; + double xSect, kFact, xSectDw, xSectUp; string s_shower, s_xSectDw, s_xSectUp; showering shower; istr >> dsid >> xSect >> kFact >> s_shower >> s_xSectDw >> s_xSectUp; - if(!s_shower.empty() && s_shower[0]!='#') { - if (s_shower=="pythia") shower=pythia; - else if (s_shower=="herwig") shower=herwig; - else if (s_shower=="sherpa") shower=sherpa; - else if (s_shower=="sherpa21") shower=sherpa21; - else if (s_shower=="pythia8") shower=pythia8; - else if (s_shower=="herwigpp") shower=herwigpp; - else { - cerr << "ERROR!! TopDataPreparation::SampleXsection::readFromFile: unknown showering (which is needed for btagging SF!!!) : " << s_shower << " for DSID= " << dsid <<endl; - shower=unknown; - } - //cout << "INFO SampleXsection::readFromFile: showering : " << s_shower << " -> " << shower << " for DSIS= " <<dsid <<endl; - - if(!s_xSectDw.empty() && s_xSectDw[0]!='#') { + if (!s_shower.empty() && s_shower[0] != '#') { + shower = stringToShower(s_shower); + if (shower == showering::unknown) { + cerr << + "ERROR!! TopDataPreparation::SampleXsection::readFromFile: unknown showering (which is needed for btagging SF!!!) : " + << s_shower << " for DSID= " << dsid << endl; + } + + if (!s_xSectDw.empty() && s_xSectDw[0] != '#') { xSectDw = atof(s_xSectDw.c_str()); - if(!s_xSectUp.empty()){ + if (!s_xSectUp.empty()) { xSectUp = atof(s_xSectUp.c_str()); - }else{ - cerr << "ERROR!! SampleXsection::readFromFile: xSectDw of "<<dsid<<" is defined ( "<<s_xSectDw<<" ), but not xSectUp" <<endl; - xSectUp=-1.; - } - //cout << " xSectDw= " << xSectDw << "\txSectUp= " << xSectUp << endl; - } - else { - xSectDw=-1.; - xSectUp=-1.; + } else { + cerr << "ERROR!! SampleXsection::readFromFile: xSectDw of " << dsid << " is defined ( " << s_xSectDw << + " ), but not xSectUp" << endl; + xSectUp = -1.; + } + } else { + xSectDw = -1.; + xSectUp = -1.; } }// !s_showering.empty() - else{ - xSectDw=-1.; - xSectUp=-1.; - shower = unknown; + else { + xSectDw = -1.; + xSectUp = -1.; + shower = unknown; } - setSample(dsid,xSect,kFact,shower,xSectDw,xSectUp); + setSample(dsid, xSect, kFact, shower, xSectDw, xSectUp); } } @@ -77,95 +70,149 @@ bool SampleXsection::readFromFile(const char *fName) return true; } -void SampleXsection::setSample(const int dsid,const double xSect,const double kFact, const showering shower, const double xSectDw, const double xSectUp) -{ - if (dsid<0) return; - map<int,pair<double,double> >::const_iterator it=m_Xsects.find(dsid); - if (it!=m_Xsects.end()) { - cerr << "ERROR!! SampleXsection::setSample: duplicate entry ! DSID= " << dsid <<endl; - //cerr << "ERROR!! SampleXsection::setSample: xSect=" << xSect << "\told xSect=" << it->second.first <<endl; +void SampleXsection::setSample(const int dsid, const double xSect, const double kFact, const showering shower, + const double xSectDw, const double xSectUp) { + if (dsid < 0) return; + + map<int, pair<double, double> >::const_iterator it = m_Xsects.find(dsid); + if (it != m_Xsects.end()) { + cerr << "ERROR!! SampleXsection::setSample: duplicate entry ! DSID= " << dsid << endl; + //cerr << "ERROR!! SampleXsection::setSample: xSect=" << xSect << "\told xSect=" << + // it->second.first <<endl; } - m_Xsects[dsid]=pair<double,double>(xSect,kFact); - m_Uncert[dsid]=pair<double,double>(xSectDw,xSectUp); - m_Showering[dsid]=shower; + m_Xsects[dsid] = pair<double, double>(xSect, kFact); + m_Uncert[dsid] = pair<double, double>(xSectDw, xSectUp); + m_Showering[dsid] = shower; } -double SampleXsection::getRawXsection(const int dsid) const -{ - map<int,pair<double,double> >::const_iterator it=m_Xsects.find(dsid); - if (it!=m_Xsects.end()) return it->second.first; +double SampleXsection::getRawXsection(const int dsid) const { + map<int, pair<double, double> >::const_iterator it = m_Xsects.find(dsid); + if (it != m_Xsects.end()) return it->second.first; + return -1; } -double SampleXsection::getKfactor(const int dsid) const -{ - map<int,pair<double,double> >::const_iterator it=m_Xsects.find(dsid); - if (it!=m_Xsects.end()) return it->second.second; +double SampleXsection::getKfactor(const int dsid) const { + map<int, pair<double, double> >::const_iterator it = m_Xsects.find(dsid); + if (it != m_Xsects.end()) return it->second.second; + return -1; } -double SampleXsection::getXsection(const int dsid) const -{ - map<int,pair<double,double> >::const_iterator it=m_Xsects.find(dsid); - if (it!=m_Xsects.end()) return (it->second.first)*(it->second.second); +double SampleXsection::getXsection(const int dsid) const { + map<int, pair<double, double> >::const_iterator it = m_Xsects.find(dsid); + if (it != m_Xsects.end()) return (it->second.first) * (it->second.second); + return -1; } -double SampleXsection::getXsectionDown(const int dsid) const -{ - map<int,pair<double,double> >::const_iterator it=m_Uncert.find(dsid); - if (it!=m_Uncert.end()) return it->second.first; +double SampleXsection::getXsectionDown(const int dsid) const { + map<int, pair<double, double> >::const_iterator it = m_Uncert.find(dsid); + if (it != m_Uncert.end()) return it->second.first; + return -1; } -double SampleXsection::getXsectionUp(const int dsid) const -{ - map<int,pair<double,double> >::const_iterator it=m_Uncert.find(dsid); - if (it!=m_Uncert.end()) return it->second.second; +double SampleXsection::getXsectionUp(const int dsid) const { + map<int, pair<double, double> >::const_iterator it = m_Uncert.find(dsid); + if (it != m_Uncert.end()) return it->second.second; + return -1; } -pair<double,double> SampleXsection::getXsectionDownUp(const int dsid) const -{ - map<int,pair<double,double> >::const_iterator it=m_Uncert.find(dsid); - if (it!=m_Uncert.end()) return it->second; - pair<double,double> temp=pair<double,double>(-1,-1); +pair<double, double> SampleXsection::getXsectionDownUp(const int dsid) const { + map<int, pair<double, double> >::const_iterator it = m_Uncert.find(dsid); + if (it != m_Uncert.end()) return it->second; + + pair<double, double> temp = pair<double, double>(-1, -1); return temp; } -SampleXsection::showering SampleXsection::getShowering(const int dsid) const -{ - map<int,showering >::const_iterator it=m_Showering.find(dsid); - if (it!=m_Showering.end()) return it->second; +SampleXsection::showering SampleXsection::getShowering(const int dsid) const { + map<int, showering >::const_iterator it = m_Showering.find(dsid); + if (it != m_Showering.end()) { + + showering shower = it->second; + // apply the translation of set + shower = applyTranslation(shower); + + return shower; + } + return unknown; } -int SampleXsection::getShoweringIndex(const int dsid) const +std::string SampleXsection::getShoweringString(const int dsid) const { - - // A.Knue: labelling taken from here: https://twiki.cern.ch/twiki/bin/view/AtlasProtected/BTagCalib2015#Pre_Recommendations_for_MC15_Bas + return showerToString(getShowering(dsid)); +} + +int SampleXsection::getShoweringIndex(const int dsid) const { + // A.Knue: labelling taken from here: + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/BTagCalib2015#Pre_Recommendations_for_MC15_Bas showering shower = getShowering(dsid); - if(shower == showering::pythia) - return 0; - else if (shower == showering::herwigpp || shower == showering::herwig)// use the herwig++ maps for the few fortran herwig samples we may have + if (shower == showering::pythia) return 0; + else if (shower == showering::herwigpp || shower == showering::herwig) // use the herwig++ maps for the few fortran + // herwig samples we may have return 1; - else if (shower == showering::pythia8) - return 2; - else if (shower == showering::sherpa) - return 3; - else if (shower == showering::sherpa21) - return 4; - else{ - - std::cout << "===========================================================================================================================================" << std::endl; - std::cout << "ERROR:TopDataPreparation: The DSID " << dsid << " does not have a showering algorithm defined!!! This is needed for MC/MC SF!!! ---> EXIT." << std::endl; + else if (shower == showering::pythia8) return 2; + else if (shower == showering::sherpa) return 3; + else if (shower == showering::sherpa21) return 4; + else if (shower == showering::amcatnlopythia8) return 5; + else if (shower == showering::herwigpp713) return 6; + else if (shower == showering::sherpa228) return 7; + else { + std::cout << + "===========================================================================================================================================" + << std::endl; + std::cout << "ERROR:TopDataPreparation: The DSID " << dsid << + " does not have a showering algorithm defined!!! This is needed for MC/MC SF!!! ---> EXIT." << std::endl; std::cout << "\t" << std::endl; exit(1); - } - + return 0; +} + +SampleXsection::showering SampleXsection::applyTranslation(const SampleXsection::showering shower) const { + const std::string& stringName = showerToString(shower); + + // check the map + auto itr = m_translator.find(stringName); + if (itr == m_translator.end()) { + return shower; + } else { + // need to apply the translation + return stringToShower(itr->second); + } +} + +std::string SampleXsection::showerToString(const SampleXsection::showering shower) const { + if (shower == showering::pythia) return "pythia"; + else if (shower == showering::herwig) return "herwig"; + else if (shower == showering::herwigpp) return "herwig"; + else if (shower == showering::sherpa) return "sherpa"; + else if (shower == showering::sherpa21) return "sherpa21"; + else if (shower == showering::pythia8) return "pythia8"; + else if (shower == showering::amcatnlopythia8) return "amcatnlopythia8"; + else if (shower == showering::herwigpp713) return "herwigpp713"; + else if (shower == showering::sherpa228) return "sherpa228"; + + return ""; +} +SampleXsection::showering SampleXsection::stringToShower(const std::string& name) const { + if (name == "pythia") return showering::pythia; + else if (name == "herwig") return showering::herwig; + else if (name == "sherpa") return showering::sherpa; + else if (name == "sherpa21") return showering::sherpa21; + else if (name == "pythia8") return showering::pythia8; + else if (name == "herwigpp") return showering::herwigpp; + else if (name == "amcatnlopythia8") return showering::amcatnlopythia8; + else if (name == "herwigpp713") return showering::herwigpp713; + else if (name == "sherpa228") return showering::sherpa228; + + return showering::unknown; } diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SampleXsectionSvc.cxx b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SampleXsectionSvc.cxx index 579bf401cd9e..49009041bb8c 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SampleXsectionSvc.cxx +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/Root/SampleXsectionSvc.cxx @@ -1,22 +1,22 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopDataPreparation/SampleXsectionSvc.h" #include <iostream> #include <cstdlib> -SampleXsectionSvc *SampleXsectionSvc::s_instance = 0; +SampleXsectionSvc* SampleXsectionSvc::s_instance = 0; -SampleXsectionSvc::SampleXsectionSvc(std::string inputFile): +SampleXsectionSvc::SampleXsectionSvc(std::string inputFile) : m_inputFile(inputFile), m_sampleXsection(0) { } //------------------------------------------------------------------------------- -SampleXsectionSvc::~SampleXsectionSvc(){ - if(m_sampleXsection) delete m_sampleXsection; +SampleXsectionSvc::~SampleXsectionSvc() { + if (m_sampleXsection) delete m_sampleXsection; } //------------------------------------------------------------------------------- @@ -24,19 +24,17 @@ SampleXsectionSvc::~SampleXsectionSvc(){ int SampleXsectionSvc::initialize() { m_sampleXsection = new SampleXsection(); - char *rootcoreDir = getenv("ROOTCOREBIN"); + char* rootcoreDir = getenv("ROOTCOREBIN"); if (!m_sampleXsection->readFromFile(m_inputFile.c_str())) { - if(rootcoreDir) {// if file can't be read, maybe it's in the common directory + if (rootcoreDir) {// if file can't be read, maybe it's in the common directory std::string fullpath = std::string(rootcoreDir) + "/data/TopDataPreparation/"; fullpath += m_inputFile; if (!m_sampleXsection->readFromFile(fullpath.c_str())) { std::cerr << "SampleXsection::unable to read input file " << fullpath << std::endl; return 1; - } - else return 0;//all OK - } - else {// if common directory can't be found, then surrender + } else return 0; //all OK + } else {// if common directory can't be found, then surrender std::cerr << "SampleXsection::unable to read input file " << m_inputFile << std::endl; return 1; } @@ -47,16 +45,16 @@ int SampleXsectionSvc::initialize() { //---------------------------------------------------------------- -SampleXsectionSvc *SampleXsectionSvc::svc(std::string inputFile) { - if(s_instance == 0) { +SampleXsectionSvc* SampleXsectionSvc::svc(std::string inputFile) { + if (s_instance == 0) { s_instance = new SampleXsectionSvc(inputFile); - - if(s_instance->initialize() != 0) { + + if (s_instance->initialize() != 0) { std::cerr << "Error: initialize failed. Could not create SampleXsectionSvc." << std::endl; delete s_instance; s_instance = 0; } } - + return s_instance; } diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SamplePDF.h b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SamplePDF.h index 5f43a4be67aa..015fd40121ca 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SamplePDF.h +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SamplePDF.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SAMPLEPDF_H #define SAMPLEPDF_H @@ -8,31 +8,29 @@ #include <map> /** @class SamplePDFSvc - ** - ** @author David Calvet <calvet@in2p3.fr> - ** - ** @brief A class to provide access to Monte Carlo sample luminosity information. - ** +** +** @author David Calvet <calvet@in2p3.fr> +** +** @brief A class to provide access to Monte Carlo sample luminosity information. +** */ class SamplePDF { - public: - - enum showering{ pythia=0, herwig=1, sherpa=2, pythia8=4, herwigpp=5, sherpa21=6, unknown=10}; - + enum showering { + pythia=0, herwig=1, sherpa=2, pythia8=4, herwigpp=5, sherpa21=6, unknown=10 + }; + inline SamplePDF() : m_PDFs() {} - inline SamplePDF(const SamplePDF &xs) : m_PDFs(xs.m_PDFs) {} + inline SamplePDF(const SamplePDF& xs) : m_PDFs(xs.m_PDFs) {} inline ~SamplePDF() {} - SamplePDF &operator=(const SamplePDF &xs); + SamplePDF& operator = (const SamplePDF& xs); - bool readFromFile(const char *fName); - void setSample(const int dsid,const int PDFid); + bool readFromFile(const char* fName); + void setSample(const int dsid, const int PDFid); int getPDFid(const int dsid) const; - private: - std::map<int, int > m_PDFs; }; diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SampleXsection.h b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SampleXsection.h index 97a3cc91981a..924d47658c07 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SampleXsection.h +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SampleXsection.h @@ -1,49 +1,66 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef SAMPLEXSECTION_H #define SAMPLEXSECTION_H #include <map> +#include <string> +#include <unordered_map> /** @class SampleXsectionSvc - ** - ** @author David Calvet <calvet@in2p3.fr> - ** - ** @brief A class to provide access to Monte Carlo sample luminosity information. - ** +** +** @author David Calvet <calvet@in2p3.fr> +** +** @brief A class to provide access to Monte Carlo sample luminosity information. +** */ class SampleXsection { - public: - - enum showering{ pythia=0, herwig=1, sherpa=2, pythia8=4, herwigpp=5, sherpa21=6, unknown=10}; + enum showering { + pythia=0, + herwig=1, + sherpa=2, + pythia8=4, + herwigpp=5, + sherpa21=6, + amcatnlopythia8=7, + herwigpp713=8, + sherpa228=9, + unknown=10 + }; inline SampleXsection() : m_Xsects() {} - inline SampleXsection(const SampleXsection &xs) : m_Xsects(xs.m_Xsects) {} + inline SampleXsection(const SampleXsection& xs) : m_Xsects(xs.m_Xsects) {} inline ~SampleXsection() {} - SampleXsection &operator=(const SampleXsection &xs); + SampleXsection& operator = (const SampleXsection& xs); - bool readFromFile(const char *fName); - void setSample(const int dsid,const double xSect,const double kFact,const showering shower, const double xSectDw, const double xSectUp); + bool readFromFile(const char* fName); + void setSample(const int dsid, const double xSect, const double kFact, const showering shower, const double xSectDw, + const double xSectUp); double getRawXsection(const int dsid) const; double getKfactor(const int dsid) const; double getXsection(const int dsid) const; double getXsectionUp(const int dsid) const; double getXsectionDown(const int dsid) const; - std::pair<double,double> getXsectionDownUp(const int dsid) const; + std::pair<double, double> getXsectionDownUp(const int dsid) const; showering getShowering(const int dsid) const; + std::string getShoweringString(const int dsid) const; int getShoweringIndex(const int dsid) const; + void setTranslator(const std::unordered_map<std::string, std::string>& map) {m_translator = map;} private: + std::map<int, std::pair<double, double> > m_Xsects; + std::map<int, std::pair<double, double> > m_Uncert; + std::map<int, showering > m_Showering; + std::unordered_map<std::string, std::string> m_translator; - std::map<int,std::pair<double,double> > m_Xsects; - std::map<int,std::pair<double,double> > m_Uncert; - std::map<int,showering > m_Showering; - + showering applyTranslation(const showering shower) const; + std::string showerToString(const showering shower) const; + showering stringToShower(const std::string& name) const; }; #endif // SAMPLEXSECTION_H diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SampleXsectionSvc.h b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SampleXsectionSvc.h index 6ebb586dcfe5..2d8ed248862f 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SampleXsectionSvc.h +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/TopDataPreparation/SampleXsectionSvc.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SAMPLEXSECTIONSVC_H #define SAMPLEXSECTIONSVC_H @@ -10,51 +10,48 @@ #include "TopDataPreparation/SampleXsection.h" /** @class SampleXsectionSvc - ** - ** @author W. H. Bell <W.Bell@cern.ch> - ** - ** @brief Singleton class providing access to SampleXsection - ** - ** The files associated with SampleXsection are read once when the unique instance is created. - ** This happens on the first call to - ** SampleXsection::svc(std::string inputFile), - ** which also return a pointer to the instance. Subsequently it is sufficient - ** to call SampleXsectionSvc::svc() without any arguments. - */ +** +** @author W. H. Bell <W.Bell@cern.ch> +** +** @brief Singleton class providing access to SampleXsection +** +** The files associated with SampleXsection are read once when the unique instance is created. +** This happens on the first call to +** SampleXsection::svc(std::string inputFile), +** which also return a pointer to the instance. Subsequently it is sufficient +** to call SampleXsectionSvc::svc() without any arguments. +*/ class SampleXsectionSvc { - public: +public: /** Return a pointer to the unique instance, initialize if necessary. * @param inputFile name of the input file. * @return pointer to SampleXsectionSvc instance, NULL on failure. - */ - static SampleXsectionSvc *svc(std::string inputFile); + */ + static SampleXsectionSvc* svc(std::string inputFile); /** Return a pointer to the unique instance, or NULL if not initialized. * @return pointer to SampleXsectionSvc instance. */ - static SampleXsectionSvc *svc() { return s_instance; } + static SampleXsectionSvc* svc() {return s_instance;} /** Provide access to the WhichPeriod object held by the instance. * @return pointer to the initialized WhichPeriod object. */ - const SampleXsection* sampleXsection() const { return m_sampleXsection; } - - - private: - + const SampleXsection* sampleXsection() const {return m_sampleXsection;} +private: /** Singleton pattern: Private constructor. */ - SampleXsectionSvc(std::string inputFile=""); - + SampleXsectionSvc(std::string inputFile = ""); + /** Singleton pattern: Private destructor. */ ~SampleXsectionSvc(); - + /** Singleton pattern: Copy constructor is private and undefined. */ - SampleXsectionSvc(const SampleXsectionSvc &); + SampleXsectionSvc(const SampleXsectionSvc&); /** Singleton pattern: Assignment operator is private and undefined. */ - SampleXsectionSvc &operator=(const SampleXsectionSvc &); - + SampleXsectionSvc& operator = (const SampleXsectionSvc&); + /** A pointer to carry the address of the unique instance. */ - static SampleXsectionSvc *s_instance; - + static SampleXsectionSvc* s_instance; + /** A member function to setup the WhichPeriod object. */ int initialize(void); @@ -62,9 +59,7 @@ class SampleXsectionSvc { std::string m_inputFile; /** The SampleXsection instance. */ - SampleXsection *m_sampleXsection; + SampleXsection* m_sampleXsection; }; #endif - - diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/data/README.md b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/data/README.md new file mode 100644 index 000000000000..ef6b19f71523 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/data/README.md @@ -0,0 +1,5 @@ +# 29 Jan 2018 - Important functional update for R21 + + * The files in this directory have now been moved to /cvmfs/atlas.cern.ch/repo/sw/database/GroupData/dev/AnalysisTop/TopDataPreparation. + * Requests to update these files should proceed as usual via the ANALYSISTO Jira, but changes can now be propagated via cvmfs, rather than via new releases. + diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/python/getPDF.py b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/python/getPDF.py index 580dc0d9862c..9dbb32c120a9 100755 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/python/getPDF.py +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/python/getPDF.py @@ -7,7 +7,7 @@ import os def getWikiFile(): WikiFile = "svn+ssh://svn.cern.ch/reps/atlasphys/Physics/Top/Software/Production/TopMC12twiki/status/" com = "svn co "+WikiFile - print com + print(com) os.system(com) @@ -31,9 +31,9 @@ def producePDFfile(fileout_name='PDF-MC12-8TeV.data'): if DSID>="110899" and DSID<="110910": PDF = "21000" else: - print "wrong format for",line[:-1] - print "-->",PDF,"====" - print "\n" + print("wrong format for",line[:-1]) + print("-->",PDF,"====") + print("\n") continue else : # good format @@ -43,9 +43,9 @@ def producePDFfile(fileout_name='PDF-MC12-8TeV.data'): if dico.has_key(DSID): if dico[DSID] != PDF: - print DSID,"already exists" - print "\told:",dico[DSID] - print "\tnew:",PDF + print(DSID,"already exists") + print("\told:",dico[DSID]) + print("\tnew:",PDF) else : dico[DSID]=PDF out = DSID+"\t"+PDF @@ -53,13 +53,13 @@ def producePDFfile(fileout_name='PDF-MC12-8TeV.data'): for sample in ["110906", "110909"]: if not dico.has_key(sample): - print "adding missing sample",sample,"by hand" + print("adding missing sample",sample,"by hand") out = sample+"\t21000" fileout.write(out+"\n") for sample in ["203307", "203308", "203309", "203310", "203311", "203312", "203313", "203314", "203315", "203316", "203317", "203318"]: if not dico.has_key(sample): - print "adding missing sample",sample,"by hand" + print("adding missing sample",sample,"by hand") out = sample+"\t10042" fileout.write(out+"\n") diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt index 61452def1bec..14b4788f5a0a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt @@ -1,6 +1,7 @@ +# Auto-generated on: 2017-03-08 14:47:33.629640 # Declare the name of this package: -atlas_subdir( TopAnalysis ) +atlas_subdir( TopAnalysis None ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -11,6 +12,7 @@ atlas_depends_on_subdirs( PUBLIC xAODJet xAODMissingET xAODCutFlow + xAODMetaData AsgTools AthContainers PATInterfaces @@ -23,24 +25,27 @@ atlas_depends_on_subdirs( PUBLIC TopPartons TopObjectSelectionTools TopSystematicObjectMaker - TopFakes - TopDataPreparation - TopHLUpgrade ) + TopDataPreparation + #TopHLUpgrade + Tools/PathResolver + #FakeBkgTools + ) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) +# Custom definitions needed for this package: +add_definitions( -g ) + # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopAnalysis _cintDictSource - ROOT_HEADERS TopAnalysis/ObjectLoaderStandardCuts.h - TopAnalysis/EventSaverFlatNtuple.h TopAnalysis/EventSaverxAOD.h - TopAnalysis/EventSaverxAODNext.h Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) # Build a library that other components can link against: atlas_add_library( TopAnalysis Root/*.cxx Root/*.h Root/*.icc TopAnalysis/*.h TopAnalysis/*.icc TopAnalysis/*/*.h - TopAnalysis/*/*.icc ${_cintDictSource} + TopAnalysis/*/*.icc ${_cintDictSource} PUBLIC_HEADERS TopAnalysis LINK_LIBRARIES xAODCore xAODRootAccess @@ -49,6 +54,7 @@ atlas_add_library( TopAnalysis Root/*.cxx Root/*.h Root/*.icc xAODJet xAODMissingET xAODCutFlow + xAODMetaData AsgTools AthContainers PATInterfaces @@ -61,9 +67,10 @@ atlas_add_library( TopAnalysis Root/*.cxx Root/*.h Root/*.icc TopPartons TopObjectSelectionTools TopSystematicObjectMaker - TopFakes - TopDataPreparation - TopHLUpgrade + TopDataPreparation + #TopHLUpgrade + PathResolver + #FakeBkgToolsLib ${ROOT_LIBRARIES} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) @@ -83,6 +90,37 @@ atlas_add_executable( top-xaod xAODJet xAODMissingET xAODCutFlow + xAODMetaData + AsgTools + AthContainers + PATInterfaces + TopCPTools + TopEventSelectionTools + TopConfiguration + TopCorrections + TopEvent + TopParticleLevel + TopPartons + TopObjectSelectionTools + TopSystematicObjectMaker + TopDataPreparation + #TopHLUpgrade + PathResolver + ${ROOT_LIBRARIES} + TopAnalysis + #FakeBkgToolsLib + ) + +atlas_add_executable( top-tool-ftag + util/top-tool-ftag.cxx + LINK_LIBRARIES xAODCore + xAODRootAccess + xAODEgamma + xAODMuon + xAODJet + xAODMissingET + xAODCutFlow + xAODMetaData AsgTools AthContainers PATInterfaces @@ -95,9 +133,9 @@ atlas_add_executable( top-xaod TopPartons TopObjectSelectionTools TopSystematicObjectMaker - TopFakes - TopDataPreparation - TopHLUpgrade + TopDataPreparation + #TopHLUpgrade + PathResolver ${ROOT_LIBRARIES} TopAnalysis ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/AnalysisTrackingHelper.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/AnalysisTrackingHelper.cxx new file mode 100644 index 000000000000..36d1d944df1b --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/AnalysisTrackingHelper.cxx @@ -0,0 +1,256 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopAnalysis/AnalysisTrackingHelper.h" + +#include "TopConfiguration/ConfigurationSettings.h" +#include "TopConfiguration/JsonUtils.h" +#include "TopConfiguration/TopConfig.h" +#include "TopEvent/EventTools.h" + +#include "AsgTools/AsgTool.h" +#include "AsgTools/PropertyMgr.h" +#include "AsgTools/ToolStore.h" +#include "xAODCore/tools/IOStats.h" +#include "xAODCore/tools/ReadStats.h" + +#include <TTree.h> + +#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/optional.hpp> +#include <boost/regex.hpp> +#include <boost/scope_exit.hpp> + +#include <cstdlib> +#include <fstream> +#include <functional> +#include <set> +#include <sstream> +#include <stdexcept> + +namespace { +/** + * @brief List all tools registered in asg::ToolStore. + */ + std::vector<std::string> listToolStore() { + std::stringstream buffer; + { + auto&& stdoutbuf = std::cout.rdbuf(buffer.rdbuf()); + BOOST_SCOPE_EXIT(&stdoutbuf) { + std::cout.rdbuf(stdoutbuf); + } BOOST_SCOPE_EXIT_END + asg::ToolStore::dumpToolConfig(); + } + std::vector<std::string> result; + { + boost::regex re("(\\S+)\\s+=\\s+[^/]+/\\1\\s*"); + for (std::string line; std::getline(buffer, line); ) { + boost::cmatch m; + if (boost::regex_match(line.c_str(), m, re)) { + result.push_back(m[1]); + } + } + } + return result; + } +} + +namespace top { + AnalysisTrackingHelper::AnalysisTrackingHelper() : + m_finished(false) + { } + + + AnalysisTrackingHelper::~AnalysisTrackingHelper() { } + + + void AnalysisTrackingHelper::addInputFile(std::string const& path, unsigned long long entriesProcessed) { + top::check(!m_finished, "AnalysisTrackingHelper::addInputFile called on finished instance"); + char* fullpath = realpath(path.c_str(), NULL); + BOOST_SCOPE_EXIT(fullpath) { + free(fullpath); + } BOOST_SCOPE_EXIT_END + m_inputFiles.emplace_back((fullpath == nullptr ? path.c_str() : fullpath), entriesProcessed); + } + + void AnalysisTrackingHelper::setTopConfig(std::shared_ptr<top::TopConfig> const& topConfig) { + top::check(!m_finished, "AnalysisTrackingHelper::setTopConfig called on finished instance"); + m_topConfig = topConfig; + } + + void AnalysisTrackingHelper::writeTree(std::string const& treename) { + finish(); + TTree* t = new TTree(treename.c_str(), ""); + t->SetAutoSave(0); + t->SetAutoFlush(0); + t->Branch("jsonData", &m_json, 262144); + t->Fill(); + t->Write(); + } + + void AnalysisTrackingHelper::finish() { + std::ostringstream out; + + std::string const json_null("null"); + out << "{\n"; + { + // Store settings from configuration file: + out << json_dump("configSettings") << ": {"; + auto const& config = *top::ConfigurationSettings::get(); + char const* sep = "\n "; + for (auto&& kv : config.stringData()) { + if (!kv.second.m_set) continue; + out << sep << json_dump(kv.first) << ": " << json_dump(kv.second.m_data); + sep = ",\n "; + } + out << "},\n"; + } + { + // Store small subset of environment variables: + out << json_dump("environment") << ": {"; + char const* sep = "\n "; + auto dumpEnvVar = [&](char const* name) { + char const* value = std::getenv(name); + + out << sep << json_dump(name) << ": " << (value == nullptr ? json_null : json_dump(value)); + sep = ",\n "; + }; + dumpEnvVar("AnalysisBase_DIR"); + dumpEnvVar("AnalysisBase_VERSION"); + dumpEnvVar("AnalysisBaseExternals_DIR"); + dumpEnvVar("AnalysisBaseExternals_VERSION"); + dumpEnvVar("AnalysisTop_DIR"); + dumpEnvVar("AnalysisTop_VERSION"); + dumpEnvVar("AtlasVersion"); + dumpEnvVar("HOSTNAME"); + dumpEnvVar("PanDA_TaskID"); + dumpEnvVar("PandaID"); + out << "},\n"; + } + { + // Store metadata of inputs: + out << json_dump("inputConfig") << ": {\n"; + out << " " << json_dump("amiTag") << ": " << json_dump(m_topConfig->getAmiTag()) << ",\n"; + out << " " << json_dump("derivationFormat") << ": " << json_dump(m_topConfig->getDerivationStream()) << ",\n"; + out << " " << json_dump("dsid") << ": " << json_dump(m_topConfig->getDSID()) << ",\n"; + out << " " << json_dump("isMC") << ": " << json_dump(m_topConfig->isMC()) << ",\n"; + out << " " << json_dump("isAtlFast2") << ": " << json_dump(m_topConfig->isAFII()) << "\n"; + out << " " << json_dump("BtagCDIPath") << ": " << json_dump(m_topConfig->bTaggingCDIPath()) << "\n"; + out << "},\n"; + } + { + // List paths of loaded libraries, grouping them by directory: + bool ok; + std::map<std::string, std::set<std::string> > libs; + try { + boost::regex reLine("\\s*(?:\\S+\\s+){5}(/.*)"); + boost::cmatch m; + std::ifstream stream("/proc/self/maps", std::ios_base::in | std::ios_base::binary); + for (std::string line; std::getline(stream, line); ) { + if (boost::regex_match(line.c_str(), m, reLine)) { + std::string const& path = m[1]; + size_t i = path.rfind('/'); + assert(i != std::string::npos); + std::string const& basename = path.substr(i + 1); + if (boost::starts_with(basename, "lib")) { + std::string dirpath = path.substr(0, (i ? i : 1)); + libs[dirpath].insert(basename); + } + } + } + stream.close(); + ok = true; + } + catch (std::exception const&) { + ok = false; + } + // Store sorted list of loaded libraries (if listing was successful): + if (ok) { + out << json_dump("images") << ": ["; + char const* sep1 = "\n "; + for (auto&& lib : libs) { + out << sep1 << "[" << json_dump(lib.first) << ", ["; + sep1 = ",\n "; + char const* sep2 = "\n "; + for (auto&& basename : lib.second) { + out << sep2 << json_dump(basename); + sep2 = ",\n "; + } + out << "]]"; + } + out << "],\n"; + } + } + { + // Store information about processed input files: + out << json_dump("inputFiles") << ": ["; + char const* sep = "\n "; + for (auto const& inputFile : m_inputFiles) { + out << sep << "[" << json_dump(inputFile.path) << "," << json_dump(inputFile.entriesProcessed) << "]"; + sep = ",\n "; + } + out << "],\n"; + } + { + // Store various PerfStats: + auto&& readStats = xAOD::IOStats::instance().stats(); + out << json_dump("perfStats") << ": {\n"; + { + out << " " << json_dump("readEntriesByContainer") << ": {"; + char const* sep = "\n "; + for (auto&& kv : readStats.containers()) { + xAOD::BranchStats const& bs = kv.second; + if (boost::ends_with(bs.GetName(), "TDS") || boost::ends_with(bs.GetName(), "Aux.")) continue; + if (bs.readEntries()) { + out << sep << json_dump(bs.GetName()) << ": " << json_dump(bs.readEntries()); + sep = ",\n "; + } + } + out << "},\n"; + } + { + out << " " << json_dump("readEntriesByBranch") << ": {"; + char const* sep = "\n "; + for (auto&& kv : readStats.branches()) { + for (xAOD::BranchStats const* bs : kv.second) { + if (bs && bs->readEntries()) { + out << sep << json_dump(bs->GetName()) << ": " << json_dump(bs->readEntries()); + sep = ",\n "; + } + } + } + out << "},\n"; + } + out << " " << json_dump("totalEntries") << ": " << json_dump(readStats.nEvents()) << "},\n"; + } + { + // Store configuration of all (CP) tools: + out << json_dump("toolConfig") << ": {"; + PropertyValueJsonDumper json_dump_prop; + char const* toolsep = "\n "; + for (std::string const& toolname : listToolStore()) { + auto&& tool = asg::ToolStore::get<asg::AsgTool>(toolname); + if (tool == nullptr) continue; + if (boost::starts_with(tool->name(), "top::")) continue; + out << toolsep << json_dump(tool->name()) << ": {"; + auto&& props = *tool->getPropertyMgr(); + char const* propsep = "\n "; + for (auto&& prop : props.getProperties()) { + if (!prop.second->isValid()) continue; + auto&& jvalue = json_dump_prop(prop.second); + if (jvalue == boost::none) continue; + out << propsep << json_dump(prop.first) << ": " << *jvalue; + propsep = ",\n "; + } + out << "}"; + toolsep = ",\n "; + } + out << "},\n"; + } + out << json_dump("format") << ": " << json_dump(1) << "\n}\n"; + out.str().swap(m_json); + m_finished = true; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverFlatNtuple.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverFlatNtuple.cxx index 07f2e141fb42..a038ef355770 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverFlatNtuple.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverFlatNtuple.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopAnalysis/EventSaverFlatNtuple.h" @@ -8,2684 +8,5590 @@ #include "TopEvent/EventTools.h" #include "TopConfiguration/TopConfig.h" #include "TopEventSelectionTools/TreeManager.h" +#include "TopParticleLevel/TruthTools.h" +#include "xAODMissingET/MissingETContainer.h" #include "AthContainers/AuxTypeRegistry.h" #include "TFile.h" #include <cmath> #include <iostream> +#include <regex> #include <boost/algorithm/string.hpp> #include "TopParticleLevel/ParticleLevelEvent.h" -#include "TopFakes/TopFakesMMWeightCalculator.h" +//#include "FakeBkgTools/AsymptMatrixTool.h" -namespace top { +#include "xAODTracking/TrackParticlexAODHelpers.h" - EventSaverFlatNtuple::EventSaverFlatNtuple() : - asg::AsgTool( "top::EventSaverFlatNtuple" ), - m_config(nullptr), - m_sfRetriever(nullptr), - m_outputFile(nullptr), - m_truthTreeManager(nullptr), - m_particleLevelTreeManager(nullptr), - - m_weight_mc(0.), - m_weight_pileup(0.), - - // cumulative SF - m_weight_leptonSF(0.), - - m_weight_leptonSF_EL_SF_Trigger_UP(0.), - m_weight_leptonSF_EL_SF_Trigger_DOWN(0.), - m_weight_leptonSF_EL_SF_Reco_UP(0.), - m_weight_leptonSF_EL_SF_Reco_DOWN(0.), - m_weight_leptonSF_EL_SF_ID_UP(0.), - m_weight_leptonSF_EL_SF_ID_DOWN(0.), - m_weight_leptonSF_EL_SF_Isol_UP(0.), - m_weight_leptonSF_EL_SF_Isol_DOWN(0.), - - m_weight_leptonSF_MU_SF_Trigger_STAT_UP(0.), - m_weight_leptonSF_MU_SF_Trigger_STAT_DOWN(0.), - m_weight_leptonSF_MU_SF_Trigger_SYST_UP(0.), - m_weight_leptonSF_MU_SF_Trigger_SYST_DOWN(0.), - // Muon ID SF systematics (regular) - m_weight_leptonSF_MU_SF_ID_STAT_UP(0.), - m_weight_leptonSF_MU_SF_ID_STAT_DOWN(0.), - m_weight_leptonSF_MU_SF_ID_SYST_UP(0.), - m_weight_leptonSF_MU_SF_ID_SYST_DOWN(0.), - // Muon ID SF systematics (low pt) - m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP(0.), - m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN(0.), - m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP(0.), - m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN(0.), - // Muon isolation SF systematics - m_weight_leptonSF_MU_SF_Isol_STAT_UP(0.), - m_weight_leptonSF_MU_SF_Isol_STAT_DOWN(0.), - m_weight_leptonSF_MU_SF_Isol_SYST_UP(0.), - m_weight_leptonSF_MU_SF_Isol_SYST_DOWN(0.), - m_weight_leptonSF_MU_SF_TTVA_STAT_UP(0.), - m_weight_leptonSF_MU_SF_TTVA_STAT_DOWN(0.), - m_weight_leptonSF_MU_SF_TTVA_SYST_UP(0.), - m_weight_leptonSF_MU_SF_TTVA_SYST_DOWN(0.), - - // individual components electrons - m_weight_indiv_SF_EL_Trigger(0.), - m_weight_indiv_SF_EL_Trigger_UP(0.), - m_weight_indiv_SF_EL_Trigger_DOWN(0.), - m_weight_indiv_SF_EL_Reco(0.), - m_weight_indiv_SF_EL_Reco_UP(0.), - m_weight_indiv_SF_EL_Reco_DOWN(0.), - m_weight_indiv_SF_EL_ID(0.), - m_weight_indiv_SF_EL_ID_UP(0.), - m_weight_indiv_SF_EL_ID_DOWN(0.), - m_weight_indiv_SF_EL_Isol(0.), - m_weight_indiv_SF_EL_Isol_UP(0.), - m_weight_indiv_SF_EL_Isol_DOWN(0.), - m_weight_indiv_SF_EL_ChargeID(0.), - m_weight_indiv_SF_EL_ChargeID_UP(0.), - m_weight_indiv_SF_EL_ChargeID_DOWN(0.), - m_weight_indiv_SF_EL_ChargeMisID(0.), - m_weight_indiv_SF_EL_ChargeMisID_STAT_UP(0.), - m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN(0.), - m_weight_indiv_SF_EL_ChargeMisID_SYST_UP(0.), - m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN(0.), - - m_weight_indiv_SF_MU_Trigger(0.), - m_weight_indiv_SF_MU_Trigger_STAT_UP(0.), - m_weight_indiv_SF_MU_Trigger_STAT_DOWN(0.), - m_weight_indiv_SF_MU_Trigger_SYST_UP(0.), - m_weight_indiv_SF_MU_Trigger_SYST_DOWN(0.), - // Muon ID SF systematics (regular) - m_weight_indiv_SF_MU_ID(0.), - m_weight_indiv_SF_MU_ID_STAT_UP(0.), - m_weight_indiv_SF_MU_ID_STAT_DOWN(0.), - m_weight_indiv_SF_MU_ID_SYST_UP(0.), - m_weight_indiv_SF_MU_ID_SYST_DOWN(0.), - // Muon ID SF systematics (low pt) - m_weight_indiv_SF_MU_ID_STAT_LOWPT_UP(0.), - m_weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN(0.), - m_weight_indiv_SF_MU_ID_SYST_LOWPT_UP(0.), - m_weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN(0.), - // Muon isolation SF systematics - m_weight_indiv_SF_MU_Isol(0.), - m_weight_indiv_SF_MU_Isol_SYST_UP(0.), - m_weight_indiv_SF_MU_Isol_SYST_DOWN(0.), - m_weight_indiv_SF_MU_Isol_STAT_UP(0.), - m_weight_indiv_SF_MU_Isol_STAT_DOWN(0.), - m_weight_indiv_SF_MU_TTVA(0.), - m_weight_indiv_SF_MU_TTVA_SYST_UP(0.), - m_weight_indiv_SF_MU_TTVA_SYST_DOWN(0.), - m_weight_indiv_SF_MU_TTVA_STAT_UP(0.), - m_weight_indiv_SF_MU_TTVA_STAT_DOWN(0.), - - m_fakesMM_weights(), - - m_eventNumber(0), - m_runNumber(0), - m_randomRunNumber(0), - m_mcChannelNumber(0), - - m_mu_original(0.), - m_mu(0.), - - m_backgroundFlags(0), - m_hasBadMuon(0), - m_makeRCJets(false), - m_makeVarRCJets(false), - m_met_met(0.), - m_met_phi(0.) - { +namespace top { + EventSaverFlatNtuple::EventSaverFlatNtuple() : + asg::AsgTool("top::EventSaverFlatNtuple"), + m_config(nullptr), + m_sfRetriever(nullptr), + m_outputFile(nullptr), + m_truthTreeManager(nullptr), + m_particleLevelTreeManager(nullptr), + + m_weight_mc(0.), + m_weight_pileup(0.), + + m_weight_fwdElSF(0.), + m_weight_fwdElSF_FWDEL_SF_ID_UP(0.), + m_weight_fwdElSF_FWDEL_SF_ID_DOWN(0.), + + // cumulative SF + m_weight_leptonSF(0.), + + m_weight_leptonSF_EL_SF_Trigger_UP(0.), + m_weight_leptonSF_EL_SF_Trigger_DOWN(0.), + m_weight_leptonSF_EL_SF_Reco_UP(0.), + m_weight_leptonSF_EL_SF_Reco_DOWN(0.), + m_weight_leptonSF_EL_SF_ID_UP(0.), + m_weight_leptonSF_EL_SF_ID_DOWN(0.), + m_weight_leptonSF_EL_SF_Isol_UP(0.), + m_weight_leptonSF_EL_SF_Isol_DOWN(0.), + + m_weight_leptonSF_MU_SF_Trigger_STAT_UP(0.), + m_weight_leptonSF_MU_SF_Trigger_STAT_DOWN(0.), + m_weight_leptonSF_MU_SF_Trigger_SYST_UP(0.), + m_weight_leptonSF_MU_SF_Trigger_SYST_DOWN(0.), + // Muon ID SF systematics (regular) + m_weight_leptonSF_MU_SF_ID_STAT_UP(0.), + m_weight_leptonSF_MU_SF_ID_STAT_DOWN(0.), + m_weight_leptonSF_MU_SF_ID_SYST_UP(0.), + m_weight_leptonSF_MU_SF_ID_SYST_DOWN(0.), + // Muon ID SF systematics (low pt) + m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP(0.), + m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN(0.), + m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP(0.), + m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN(0.), + // Muon isolation SF systematics + m_weight_leptonSF_MU_SF_Isol_STAT_UP(0.), + m_weight_leptonSF_MU_SF_Isol_STAT_DOWN(0.), + m_weight_leptonSF_MU_SF_Isol_SYST_UP(0.), + m_weight_leptonSF_MU_SF_Isol_SYST_DOWN(0.), + m_weight_leptonSF_MU_SF_TTVA_STAT_UP(0.), + m_weight_leptonSF_MU_SF_TTVA_STAT_DOWN(0.), + m_weight_leptonSF_MU_SF_TTVA_SYST_UP(0.), + m_weight_leptonSF_MU_SF_TTVA_SYST_DOWN(0.), + // Special global lepton trigger SF + systematics + m_weight_globalLeptonTriggerSF(0.), + m_weight_globalLeptonTriggerSF_EL_Trigger_UP(0.), + m_weight_globalLeptonTriggerSF_EL_Trigger_DOWN(0.), + m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_UP(0.), + m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_DOWN(0.), + m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_UP(0.), + m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_DOWN(0.), + m_weight_oldTriggerSF(0.), + m_weight_oldTriggerSF_EL_Trigger_UP(0.), + m_weight_oldTriggerSF_EL_Trigger_DOWN(0.), + m_weight_oldTriggerSF_MU_Trigger_STAT_UP(0.), + m_weight_oldTriggerSF_MU_Trigger_STAT_DOWN(0.), + m_weight_oldTriggerSF_MU_Trigger_SYST_UP(0.), + m_weight_oldTriggerSF_MU_Trigger_SYST_DOWN(0.), + + // individual components electrons + m_weight_indiv_SF_EL_Reco(0.), + m_weight_indiv_SF_EL_Reco_UP(0.), + m_weight_indiv_SF_EL_Reco_DOWN(0.), + m_weight_indiv_SF_EL_ID(0.), + m_weight_indiv_SF_EL_ID_UP(0.), + m_weight_indiv_SF_EL_ID_DOWN(0.), + m_weight_indiv_SF_EL_Isol(0.), + m_weight_indiv_SF_EL_Isol_UP(0.), + m_weight_indiv_SF_EL_Isol_DOWN(0.), + m_weight_indiv_SF_EL_ChargeID(0.), + m_weight_indiv_SF_EL_ChargeID_UP(0.), + m_weight_indiv_SF_EL_ChargeID_DOWN(0.), + m_weight_indiv_SF_EL_ChargeMisID(0.), + m_weight_indiv_SF_EL_ChargeMisID_STAT_UP(0.), + m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN(0.), + m_weight_indiv_SF_EL_ChargeMisID_SYST_UP(0.), + m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN(0.), + + // Muon ID SF systematics (regular) + m_weight_indiv_SF_MU_ID(0.), + m_weight_indiv_SF_MU_ID_STAT_UP(0.), + m_weight_indiv_SF_MU_ID_STAT_DOWN(0.), + m_weight_indiv_SF_MU_ID_SYST_UP(0.), + m_weight_indiv_SF_MU_ID_SYST_DOWN(0.), + // Muon ID SF systematics (low pt) + m_weight_indiv_SF_MU_ID_STAT_LOWPT_UP(0.), + m_weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN(0.), + m_weight_indiv_SF_MU_ID_SYST_LOWPT_UP(0.), + m_weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN(0.), + // Muon isolation SF systematics + m_weight_indiv_SF_MU_Isol(0.), + m_weight_indiv_SF_MU_Isol_SYST_UP(0.), + m_weight_indiv_SF_MU_Isol_SYST_DOWN(0.), + m_weight_indiv_SF_MU_Isol_STAT_UP(0.), + m_weight_indiv_SF_MU_Isol_STAT_DOWN(0.), + m_weight_indiv_SF_MU_TTVA(0.), + m_weight_indiv_SF_MU_TTVA_SYST_UP(0.), + m_weight_indiv_SF_MU_TTVA_SYST_DOWN(0.), + m_weight_indiv_SF_MU_TTVA_STAT_UP(0.), + m_weight_indiv_SF_MU_TTVA_STAT_DOWN(0.), + + m_ASMsize(0.), + m_ASMweights(), + m_ASMweights_Syst(), + m_ASMweights_Systname(), + + m_eventNumber(0), + m_runNumber(0), + m_randomRunNumber(0), + m_mcChannelNumber(0), + + m_mu_original(0.), + m_mu(0.), + m_mu_actual_original(0.), + m_mu_actual(0.), + + m_backgroundFlags(0), + m_hasBadMuon(0), + m_makeRCJets(false), + m_makeVarRCJets(false), + m_useRCJSS(false), + m_useRCAdditionalJSS(false), + m_useVarRCJSS(false), + m_useVarRCAdditionalJSS(false), + m_useElectronChargeIDSelection(false), + m_met_met(0.), + m_met_phi(0.), + m_met_met_withLooseObjects(0.), + m_met_phi_withLooseObjects(0.) { + m_weight_leptonSF_EL_SF_CorrModel_Reco_UP = std::vector<float>(); + m_weight_leptonSF_EL_SF_CorrModel_Reco_DOWN = std::vector<float>(); + m_weight_leptonSF_EL_SF_CorrModel_ID_UP = std::vector<float>(); + m_weight_leptonSF_EL_SF_CorrModel_ID_DOWN = std::vector<float>(); + m_weight_leptonSF_EL_SF_CorrModel_Iso_UP = std::vector<float>(); + m_weight_leptonSF_EL_SF_CorrModel_Iso_DOWN = std::vector<float>(); + } + + EventSaverFlatNtuple::~EventSaverFlatNtuple() { + for (std::unordered_map<std::string, int*>::iterator i = m_extraTruthVars_int.begin(); + i != m_extraTruthVars_int.end(); ++i) + delete (*i).second; + + for (std::unordered_map<std::string, float*>::iterator i = m_extraTruthVars_float.begin(); + i != m_extraTruthVars_float.end(); ++i) + delete (*i).second; + } + + std::shared_ptr<top::TopConfig> EventSaverFlatNtuple::topConfig() { + return m_config; + } + + std::vector<std::shared_ptr<top::TreeManager> > EventSaverFlatNtuple::treeManagers() { + return m_treeManagers; + } + + std::shared_ptr<top::TreeManager> EventSaverFlatNtuple::truthTreeManager() { + return m_truthTreeManager; + } + + std::shared_ptr<top::TreeManager> EventSaverFlatNtuple::particleLevelTreeManager() { + return m_particleLevelTreeManager; + } + + //std::shared_ptr<top::ScaleFactorRetriever> EventSaverFlatNtuple::scaleFactorRetriever() + top::ScaleFactorRetriever* EventSaverFlatNtuple::scaleFactorRetriever() { + return m_sfRetriever; + } + + std::shared_ptr<top::TreeManager> EventSaverFlatNtuple::upgradeTreeManager() { + return m_upgradeTreeManager; + } + + std::vector<top::TreeManager::BranchFilter>& EventSaverFlatNtuple::branchFilters() { + return m_branchFilters; + } + + void EventSaverFlatNtuple::initialize(std::shared_ptr<top::TopConfig> config, TFile* file, + const std::vector<std::string>& extraBranches) { + m_config = config; + m_outputFile = file; + m_extraBranches = extraBranches; + m_selectionDecisions.resize(m_extraBranches.size()); + + // set the branch filters + branchFilters().push_back(std::bind(&EventSaverFlatNtuple::filterBranches, this, std::placeholders::_1, + std::placeholders::_2)); + + // fixed-R re-clustering (RC) + if (config->useRCJets()) { + m_makeRCJets = true; + m_useRCJSS = config->useRCJetSubstructure(); + m_useRCAdditionalJSS = config->useRCJetAdditionalSubstructure(); } - EventSaverFlatNtuple::~EventSaverFlatNtuple() - { - for (std::unordered_map<std::string,int*>::iterator i=m_extraTruthVars_int.begin();i!=m_extraTruthVars_int.end();++i) - delete (*i).second; + // variable-R re-clustering (VarRC) + if (config->useVarRCJets()) { + m_makeVarRCJets = true; + m_VarRCjetBranches.clear(); // clear map of branches just in case + m_VarRCjetsubBranches.clear(); + m_VarRCjetBranchesParticle.clear(); + m_VarRCjetsubBranchesParticle.clear(); + + + boost::split(m_VarRCJetRho, config->VarRCJetRho(), boost::is_any_of(",")); + boost::split(m_VarRCJetMassScale, config->VarRCJetMassScale(), boost::is_any_of(",")); + + m_useVarRCJSS = config->useVarRCJetSubstructure(); + m_useVarRCAdditionalJSS = config->useVarRCJetAdditionalSubstructure(); + } // end make VarRC jets - for (std::unordered_map<std::string,float*>::iterator i=m_extraTruthVars_float.begin();i!=m_extraTruthVars_float.end();++i) - delete (*i).second; + if (config->useElectronChargeIDSelection()) { + m_useElectronChargeIDSelection = true; } - std::shared_ptr<top::TopConfig> EventSaverFlatNtuple::topConfig() - { - return m_config; + //make a tree for each systematic + std::string nominalTTreeName("SetMe"), nominalLooseTTreeName("SetMe"); + if (m_config->doTightEvents() && !m_config->HLLHC()) { + for (auto treeName : *config->systAllTTreeNames()) { + if (treeName.first == m_config->nominalHashValue() || m_config->doTightSysts()) { + m_treeManagers.push_back(std::shared_ptr<top::TreeManager>(new top::TreeManager(treeName.second, file, + m_config-> + outputFileNEventAutoFlush(), + m_config-> + outputFileBasketSizePrimitive(), + m_config-> + outputFileBasketSizeVector()))); + m_treeManagers.back()->branchFilters() = branchFilters(); + if (treeName.first == m_config->nominalHashValue()) { + nominalTTreeName = treeName.second; + } + } + } } - std::vector<std::shared_ptr<top::TreeManager>> EventSaverFlatNtuple::treeManagers() - { - return m_treeManagers; + if (m_config->doLooseEvents()) { + for (auto treeName : *config->systAllTTreeNames()) { + if (treeName.first == m_config->nominalHashValue() || m_config->doLooseSysts()) { + m_treeManagers.push_back(std::shared_ptr<top::TreeManager>(new top::TreeManager(treeName.second + "_Loose", + file, + m_config-> + outputFileNEventAutoFlush(), + m_config->outputFileBasketSizePrimitive(), + m_config-> + outputFileBasketSizeVector()))); + m_treeManagers.back()->branchFilters() = branchFilters(); + if (treeName.first == m_config->nominalHashValue()) { + nominalLooseTTreeName = treeName.second + "_Loose"; + } + } + } } - std::shared_ptr<top::TreeManager> EventSaverFlatNtuple::truthTreeManager() - { - return m_truthTreeManager; + // Truth tree + if (m_config->isMC()) { + if (asg::ToolStore::contains<ScaleFactorRetriever>("top::ScaleFactorRetriever")) { + m_sfRetriever = asg::ToolStore::get<ScaleFactorRetriever>("top::ScaleFactorRetriever"); + } else { + top::ScaleFactorRetriever* topSFR = new top::ScaleFactorRetriever("top::ScaleFactorRetriever"); + top::check(asg::setProperty(topSFR, "config", m_config), "Failed to set config"); + top::check(topSFR->initialize(), "Failed to initalialise"); + m_sfRetriever = topSFR; + } + + m_truthTreeManager = + std::shared_ptr<top::TreeManager>(new top::TreeManager("truth", file, m_config->outputFileNEventAutoFlush(), + m_config->outputFileBasketSizePrimitive(), + m_config->outputFileBasketSizeVector())); + m_truthTreeManager->branchFilters() = branchFilters(); + m_truthTreeManager->makeOutputVariable(m_weight_mc, "weight_mc"); + m_truthTreeManager->makeOutputVariable(m_eventNumber, "eventNumber"); + m_truthTreeManager->makeOutputVariable(m_runNumber, "runNumber"); + m_truthTreeManager->makeOutputVariable(m_mu, "mu"); + m_truthTreeManager->makeOutputVariable(m_mu_actual, "mu_actual"); + m_truthTreeManager->makeOutputVariable(m_weight_pileup, "weight_pileup"); + if (m_config->isMC() && m_config->doPileupReweighting()) m_truthTreeManager->makeOutputVariable(m_randomRunNumber, + "randomRunNumber"); + + m_truthTreeManager->makeOutputVariable(m_mcChannelNumber, "mcChannelNumber"); + + // Only if you really really want it - this is BIG + if (m_config->useTruthParticles() && m_config->doTruthBlockInfo()) { + m_truthTreeManager->makeOutputVariable(m_mc_pt, "mc_pt"); + m_truthTreeManager->makeOutputVariable(m_mc_eta, "mc_eta"); + m_truthTreeManager->makeOutputVariable(m_mc_phi, "mc_phi"); + m_truthTreeManager->makeOutputVariable(m_mc_e, "mc_e"); + m_truthTreeManager->makeOutputVariable(m_mc_pdgId, "mc_pdgId"); + m_truthTreeManager->makeOutputVariable(m_mc_charge, "mc_charge"); + m_truthTreeManager->makeOutputVariable(m_mc_status, "mc_status"); + m_truthTreeManager->makeOutputVariable(m_mc_barcode, "mc_barcode"); + } + + // PDF information + if (m_config->doTruthPDFInfo()) { + if (m_config->doTruthPDFInfoInNominalTrees()) {//if PDF info requested to be saved in nominal trees of truth one + for (auto systematicTree : m_treeManagers) {//loop on systematic trees to only get the nominal ones + if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName) { + systematicTree->makeOutputVariable(m_PDFinfo_X1, "PDFinfo_X1"); + systematicTree->makeOutputVariable(m_PDFinfo_X2, "PDFinfo_X2"); + systematicTree->makeOutputVariable(m_PDFinfo_PDGID1, "PDFinfo_PDGID1"); + systematicTree->makeOutputVariable(m_PDFinfo_PDGID2, "PDFinfo_PDGID2"); + systematicTree->makeOutputVariable(m_PDFinfo_Q, "PDFinfo_Q"); + systematicTree->makeOutputVariable(m_PDFinfo_XF1, "PDFinfo_XF1"); + systematicTree->makeOutputVariable(m_PDFinfo_XF2, "PDFinfo_XF2"); + } + } + } else { + m_truthTreeManager->makeOutputVariable(m_PDFinfo_X1, "PDFinfo_X1"); + m_truthTreeManager->makeOutputVariable(m_PDFinfo_X2, "PDFinfo_X2"); + m_truthTreeManager->makeOutputVariable(m_PDFinfo_PDGID1, "PDFinfo_PDGID1"); + m_truthTreeManager->makeOutputVariable(m_PDFinfo_PDGID2, "PDFinfo_PDGID2"); + m_truthTreeManager->makeOutputVariable(m_PDFinfo_Q, "PDFinfo_Q"); + m_truthTreeManager->makeOutputVariable(m_PDFinfo_XF1, "PDFinfo_XF1"); + m_truthTreeManager->makeOutputVariable(m_PDFinfo_XF2, "PDFinfo_XF2"); + } + } + + // MC Generator weights + if (m_config->doMCGeneratorWeights()) { + if (m_config->doMCGeneratorWeightsInNominalTrees()) {//if MCGeneratorWeights requested to be saved in nominal + // trees of truth one + for (auto systematicTree : m_treeManagers) {//loop on systematic trees to only get the nominal ones + if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName) { + systematicTree->makeOutputVariable(m_mc_generator_weights, "mc_generator_weights"); + } + } + } else { + m_truthTreeManager->makeOutputVariable(m_mc_generator_weights, "mc_generator_weights"); + } + } + + if (m_config->saveLHAPDFEvent()) { + for (const auto& pdfset : m_config->LHAPDFSets()) + m_PDF_eventWeights[ pdfset ] = std::vector<float>(); + + for (auto& pdf : m_PDF_eventWeights) { + if (m_config->doLHAPDFInNominalTrees()) {//if PDF weights requested to be saved in nominal trees instead of + // truth one + for (auto systematicTree : m_treeManagers) {//loop on systematic trees to only get the nominal ones + if (systematicTree->name() == nominalTTreeName || + systematicTree->name() == + nominalLooseTTreeName) systematicTree->makeOutputVariable(pdf.second, pdf.first); + } + } else { + m_truthTreeManager->makeOutputVariable(pdf.second, pdf.first); + } + } + } } - std::shared_ptr<top::TreeManager> EventSaverFlatNtuple::particleLevelTreeManager() - { - return m_particleLevelTreeManager; + if (m_config->useLargeRJets()) { + for (const std::pair<std::string, std::string>& taggerName : m_config->boostedJetTaggers()) + m_boostedJetTaggersNames.push_back(taggerName.first + "_" + taggerName.second); + for (const std::pair<std::string, std::string>& taggerSF : m_config->boostedTaggerSFnames()) + m_boostedJetTaggersNamesCalibrated.push_back(taggerSF.first); } - std::shared_ptr<top::ScaleFactorRetriever> EventSaverFlatNtuple::scaleFactorRetriever() - { - return m_sfRetriever; + if (m_config->useJets()) { + for (const std::string& algo : m_config->bTagAlgo_available()) { + if (DLx.count(algo) == 0) { + DLx.emplace(algo, SG::AuxElement::ConstAccessor<float>("AnalysisTop_" + algo)); + m_jet_DLx[algo] = std::vector<float>(); + m_jet_DLx_pb[algo] = std::vector<float>(); + m_jet_DLx_pc[algo] = std::vector<float>(); + m_jet_DLx_pu[algo] = std::vector<float>(); + } + } } - std::vector<top::TreeManager::BranchFilter> & EventSaverFlatNtuple::branchFilters() - { - return m_branchFilters; + if (m_config->useTrackJets()) { + for (const std::string& algo : m_config->bTagAlgo_available_trkJet()) { + if (DLx.count(algo) == 0) { + DLx.emplace(algo, SG::AuxElement::ConstAccessor<float>("AnalysisTop_" + algo)); + m_tjet_DLx[algo] = std::vector<float>(); + m_tjet_DLx_pb[algo] = std::vector<float>(); + m_tjet_DLx_pc[algo] = std::vector<float>(); + m_tjet_DLx_pu[algo] = std::vector<float>(); + } + } } - void EventSaverFlatNtuple::initialize(std::shared_ptr<top::TopConfig> config, TFile* file, const std::vector<std::string>& extraBranches) { - m_config = config; - m_outputFile = file; - m_extraBranches = extraBranches; - m_selectionDecisions.resize(m_extraBranches.size()); + //loop over systematics and attach variables + for (auto systematicTree : m_treeManagers) { + if (m_config->isMC()) { + systematicTree->makeOutputVariable(m_weight_mc, "weight_mc"); + //some event weights + systematicTree->makeOutputVariable(m_weight_pileup, "weight_pileup"); + systematicTree->makeOutputVariable(m_weight_leptonSF, "weight_leptonSF"); + + if (m_config->useFwdElectrons()) systematicTree->makeOutputVariable(m_weight_fwdElSF, "weight_fwdElSF"); + + if (m_config->usePhotons()) systematicTree->makeOutputVariable(m_weight_photonSF, "weight_photonSF"); + + if (m_config->useTaus()) systematicTree->makeOutputVariable(m_weight_tauSF, + "weight_tauSF"); + + if (m_config->useGlobalTriggerConfiguration()) systematicTree->makeOutputVariable( + m_weight_globalLeptonTriggerSF, "weight_globalLeptonTriggerSF"); + systematicTree->makeOutputVariable(m_weight_oldTriggerSF, "weight_oldTriggerSF"); + + // nominal b-tagging SFs + for (auto& tagWP : m_config->bTagWP_available()) { + // skip uncalibrated though available WPs + if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), + tagWP) == m_config->bTagWP_calibrated().end()) continue; + m_weight_bTagSF[tagWP] = 0.; + systematicTree->makeOutputVariable(m_weight_bTagSF[tagWP], "weight_bTagSF_" + shortBtagWP(tagWP)); + if (m_config->storePerJetBtagSFs() && m_config->isMC()) { + m_perjet_weight_bTagSF[tagWP] = std::vector<float>(); + m_perjet_weight_bTagSF_eigen_B_up[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_bTagSF_eigen_B_down[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_bTagSF_eigen_C_up[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_bTagSF_eigen_C_down[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_bTagSF_eigen_Light_up[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_bTagSF_eigen_Light_down[tagWP] = std::vector<std::vector<float> >(); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF[tagWP], + "weight_perjet_bTagSF_" + shortBtagWP(tagWP)); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_eigen_B_up[tagWP], "weight_perjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_B_up"); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_eigen_B_down[tagWP], "weight_perjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_B_down"); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_eigen_C_up[tagWP], "weight_perjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_C_up"); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_eigen_C_down[tagWP], "weight_perjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_C_down"); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_eigen_Light_up[tagWP], "weight_perjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_Light_up"); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_eigen_Light_down[tagWP], "weight_perjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_Light_down"); + for (const std::string& name : m_config->btagging_namedSysts(tagWP)) { + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_named_up[tagWP][name], "weight_perjet_bTagSF_" + shortBtagWP( + tagWP) + "_" + betterBtagNamedSyst(name) + "_up"); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_named_down[tagWP][name], "weight_perjet_bTagSF_" + shortBtagWP( + tagWP) + "_" + betterBtagNamedSyst(name) + "_down"); + } + } + } + if (m_config->useTrackJets()) { + for (auto& tagWP : m_config->bTagWP_available_trkJet()) { + // skip uncalibrated though available WPs + if (std::find(m_config->bTagWP_calibrated_trkJet().begin(), m_config->bTagWP_calibrated_trkJet().end(), + tagWP) == m_config->bTagWP_calibrated_trkJet().end()) continue; + m_weight_trackjet_bTagSF[tagWP] = 0.; + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF[tagWP], + "weight_trackjet_bTagSF_" + shortBtagWP(tagWP)); + if (m_config->storePerJetBtagSFs() && m_config->isMC()) { + m_perjet_weight_trackjet_bTagSF[tagWP] = std::vector<float>(); + m_perjet_weight_trackjet_bTagSF_eigen_B_up[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_trackjet_bTagSF_eigen_B_down[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_trackjet_bTagSF_eigen_C_up[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_trackjet_bTagSF_eigen_C_down[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_trackjet_bTagSF_eigen_Light_up[tagWP] = std::vector<std::vector<float> >(); + m_perjet_weight_trackjet_bTagSF_eigen_Light_down[tagWP] = std::vector<std::vector<float> >(); + systematicTree->makeOutputVariable(m_perjet_weight_trackjet_bTagSF[tagWP], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP)); + systematicTree->makeOutputVariable(m_perjet_weight_trackjet_bTagSF_eigen_B_up[tagWP], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_B_up"); + systematicTree->makeOutputVariable(m_perjet_weight_trackjet_bTagSF_eigen_B_down[tagWP], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_B_down"); + systematicTree->makeOutputVariable(m_perjet_weight_trackjet_bTagSF_eigen_C_up[tagWP], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_C_up"); + systematicTree->makeOutputVariable(m_perjet_weight_trackjet_bTagSF_eigen_C_down[tagWP], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_C_down"); + systematicTree->makeOutputVariable(m_perjet_weight_trackjet_bTagSF_eigen_Light_up[tagWP], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_Light_up"); + systematicTree->makeOutputVariable(m_perjet_weight_trackjet_bTagSF_eigen_Light_down[tagWP], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_Light_down"); + for (const std::string& name : m_config->trkjet_btagging_namedSysts(tagWP)) { + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_named_up[tagWP][name], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_" + betterBtagNamedSyst(name) + "_up"); + systematicTree->makeOutputVariable(m_perjet_weight_bTagSF_named_down[tagWP][name], "weight_perjet_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_" + betterBtagNamedSyst(name) + "_down"); + } + } + } + } - // fixed-R re-clustering (RC) - if (config->useRCJets() == true){ - m_makeRCJets = true; - m_rc = std::unique_ptr<RCJetMC15> ( new RCJetMC15( "RCJetMC15" ) ); - top::check(m_rc->setProperty( "config" , config ) , "Failed to set config property of RCJetMC15"); - top::check(m_rc->initialize(),"Failed to initialize RCJetMC15"); - } - // variable-R re-clustering (VarRC) - if (config->useVarRCJets() == true){ - m_makeVarRCJets = true; - m_VarRCjetBranches.clear(); // clear map of branches just in case - m_VarRCjetsubBranches.clear(); - - boost::split(m_VarRCJetRho, config->VarRCJetRho(), boost::is_any_of(",")); - boost::split(m_VarRCJetMassScale, config->VarRCJetMassScale(), boost::is_any_of(",")); - - for (auto& rho : m_VarRCJetRho){ - for (auto& mass_scale : m_VarRCJetMassScale){ - std::replace( rho.begin(), rho.end(), '.', '_'); - std::string name = rho+mass_scale; - m_VarRC[name] = std::unique_ptr<RCJetMC15> ( new RCJetMC15( "VarRCJetMC15_"+name ) ); - top::check(m_VarRC[name]->setProperty( "config" , config ) , "Failed to set config property of VarRCJetMC15"); - top::check(m_VarRC[name]->setProperty( "VarRCjets", true ) , "Failed to set VarRCjets property of VarRCJetMC15"); - top::check(m_VarRC[name]->setProperty( "VarRCjets_rho", rho ) , "Failed to set VarRCjets rho property of VarRCJetMC15"); - top::check(m_VarRC[name]->setProperty( "VarRCjets_mass_scale", mass_scale ) , "Failed to set VarRCjets mass scale property of VarRCJetMC15"); - top::check(m_VarRC[name]->initialize(),"Failed to initialize VarRCJetMC15"); - } // end loop over mass scale parameters (e.g., top mass, w mass, etc.) - } // end loop over mass scale multiplies (e.g., 1.,2.,etc.) - } // end make VarRC jets - - - //make a tree for each systematic - std::string nominalTTreeName("SetMe"),nominalLooseTTreeName("SetMe"); - if (!m_config->doLooseTreeOnly() && !m_config->HLLHC()) { - for (auto treeName : *config->systAllTTreeNames()) { - m_treeManagers.push_back(std::shared_ptr<top::TreeManager>( new top::TreeManager(treeName.second, file , m_config->outputFileSetAutoFlushZero()) ) ); - m_treeManagers.back()->branchFilters() = branchFilters(); - if (treeName.first == m_config->nominalHashValue()) { - nominalTTreeName = treeName.second; - } + systematicTree->makeOutputVariable(m_weight_jvt, "weight_jvt"); + if (m_config->getfJVTWP() != "None") systematicTree->makeOutputVariable(m_weight_forwardjvt, "weight_forwardjvt"); + + if (m_config->isSherpa22Vjets()) systematicTree->makeOutputVariable(m_weight_sherpa_22_vjets, + "weight_sherpa_22_vjets"); + + if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName) { + systematicTree->makeOutputVariable(m_weight_pileup_UP, "weight_pileup_UP"); + systematicTree->makeOutputVariable(m_weight_pileup_DOWN, "weight_pileup_DOWN"); + + if (m_config->useFwdElectrons()) { + systematicTree->makeOutputVariable(m_weight_fwdElSF_FWDEL_SF_ID_UP, "weight_fwdElSF_FWDEL_SF_ID_UP"); + systematicTree->makeOutputVariable(m_weight_fwdElSF_FWDEL_SF_ID_DOWN, "weight_fwdElSF_FWDEL_SF_ID_DOWN"); + } + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Trigger_UP, "weight_leptonSF_EL_SF_Trigger_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Trigger_DOWN, + "weight_leptonSF_EL_SF_Trigger_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Reco_UP, "weight_leptonSF_EL_SF_Reco_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Reco_DOWN, "weight_leptonSF_EL_SF_Reco_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_ID_UP, "weight_leptonSF_EL_SF_ID_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_ID_DOWN, "weight_leptonSF_EL_SF_ID_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Isol_UP, "weight_leptonSF_EL_SF_Isol_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Isol_DOWN, "weight_leptonSF_EL_SF_Isol_DOWN"); + + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_CorrModel_Reco_UP, + "weight_leptonSF_EL_SF_" + m_config->electronEfficiencySystematicModel() + + "_Reco_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_CorrModel_Reco_DOWN, + "weight_leptonSF_EL_SF_" + m_config->electronEfficiencySystematicModel() + + "_Reco_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_CorrModel_ID_UP, + "weight_leptonSF_EL_SF_" + m_config->electronEfficiencySystematicModel() + + "_ID_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_CorrModel_ID_DOWN, + "weight_leptonSF_EL_SF_" + m_config->electronEfficiencySystematicModel() + + "_ID_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_CorrModel_Iso_UP, + "weight_leptonSF_EL_SF_" + m_config->electronEfficiencySystematicModel() + + "_Iso_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_CorrModel_Iso_DOWN, + "weight_leptonSF_EL_SF_" + m_config->electronEfficiencySystematicModel() + + "_Iso_DOWN"); + } + + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Trigger_STAT_UP, + "weight_leptonSF_MU_SF_Trigger_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Trigger_STAT_DOWN, + "weight_leptonSF_MU_SF_Trigger_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Trigger_SYST_UP, + "weight_leptonSF_MU_SF_Trigger_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Trigger_SYST_DOWN, + "weight_leptonSF_MU_SF_Trigger_SYST_DOWN"); + // Muon ID SF systematics (regular) + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_STAT_UP, "weight_leptonSF_MU_SF_ID_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_STAT_DOWN, + "weight_leptonSF_MU_SF_ID_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_SYST_UP, "weight_leptonSF_MU_SF_ID_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_SYST_DOWN, + "weight_leptonSF_MU_SF_ID_SYST_DOWN"); + // Muon ID SF systematics (low pt) + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP, + "weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN, + "weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP, + "weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN, + "weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN"); + // Muon isolation SF systematics + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Isol_STAT_UP, + "weight_leptonSF_MU_SF_Isol_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Isol_STAT_DOWN, + "weight_leptonSF_MU_SF_Isol_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Isol_SYST_UP, + "weight_leptonSF_MU_SF_Isol_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Isol_SYST_DOWN, + "weight_leptonSF_MU_SF_Isol_SYST_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_TTVA_STAT_UP, + "weight_leptonSF_MU_SF_TTVA_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_TTVA_STAT_DOWN, + "weight_leptonSF_MU_SF_TTVA_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_TTVA_SYST_UP, + "weight_leptonSF_MU_SF_TTVA_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_TTVA_SYST_DOWN, + "weight_leptonSF_MU_SF_TTVA_SYST_DOWN"); + // Special global lepton trigger SF when requested + if (m_config->useGlobalTriggerConfiguration()) { + systematicTree->makeOutputVariable(m_weight_globalLeptonTriggerSF_EL_Trigger_UP, + "weight_globalLeptonTriggerSF_EL_Trigger_UP"); + systematicTree->makeOutputVariable(m_weight_globalLeptonTriggerSF_EL_Trigger_DOWN, + "weight_globalLeptonTriggerSF_EL_Trigger_DOWN"); + systematicTree->makeOutputVariable(m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_UP, + "weight_globalLeptonTriggerSF_MU_Trigger_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_DOWN, + "weight_globalLeptonTriggerSF_MU_Trigger_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_UP, + "weight_globalLeptonTriggerSF_MU_Trigger_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_DOWN, + "weight_globalLeptonTriggerSF_MU_Trigger_SYST_DOWN"); + } + systematicTree->makeOutputVariable(m_weight_oldTriggerSF_EL_Trigger_UP, "weight_oldTriggerSF_EL_Trigger_UP"); + systematicTree->makeOutputVariable(m_weight_oldTriggerSF_EL_Trigger_DOWN, + "weight_oldTriggerSF_EL_Trigger_DOWN"); + systematicTree->makeOutputVariable(m_weight_oldTriggerSF_MU_Trigger_STAT_UP, + "weight_oldTriggerSF_MU_Trigger_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_oldTriggerSF_MU_Trigger_STAT_DOWN, + "weight_oldTriggerSF_MU_Trigger_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_oldTriggerSF_MU_Trigger_SYST_UP, + "weight_oldTriggerSF_MU_Trigger_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_oldTriggerSF_MU_Trigger_SYST_DOWN, + "weight_oldTriggerSF_MU_Trigger_SYST_DOWN"); + + // write also out the individual components: + + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Reco, "weight_indiv_SF_EL_Reco"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Reco_UP, "weight_indiv_SF_EL_Reco_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Reco_DOWN, "weight_indiv_SF_EL_Reco_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ID, "weight_indiv_SF_EL_ID"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ID_UP, "weight_indiv_SF_EL_ID_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ID_DOWN, "weight_indiv_SF_EL_ID_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Isol, "weight_indiv_SF_EL_Isol"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Isol_UP, "weight_indiv_SF_EL_Isol_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Isol_DOWN, "weight_indiv_SF_EL_Isol_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeID, "weight_indiv_SF_EL_ChargeID"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeID_UP, "weight_indiv_SF_EL_ChargeID_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeID_DOWN, "weight_indiv_SF_EL_ChargeID_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID, "weight_indiv_SF_EL_ChargeMisID"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID_STAT_UP, + "weight_indiv_SF_EL_ChargeMisID_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN, + "weight_indiv_SF_EL_ChargeMisID_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID_SYST_UP, + "weight_indiv_SF_EL_ChargeMisID_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN, + "weight_indiv_SF_EL_ChargeMisID_SYST_DOWN"); + + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID, "weight_indiv_SF_MU_ID"); + // Muon ID SF systematics (regular) + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_STAT_UP, "weight_indiv_SF_MU_ID_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_STAT_DOWN, "weight_indiv_SF_MU_ID_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_SYST_UP, "weight_indiv_SF_MU_ID_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_SYST_DOWN, "weight_indiv_SF_MU_ID_SYST_DOWN"); + // Muon ID SF systematics (low pt) + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_STAT_LOWPT_UP, + "weight_indiv_SF_MU_ID_STAT_LOWPT_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN, + "weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_SYST_LOWPT_UP, + "weight_indiv_SF_MU_ID_SYST_LOWPT_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN, + "weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN"); + // Muon isolation SF systematics + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol, "weight_indiv_SF_MU_Isol"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol_STAT_UP, "weight_indiv_SF_MU_Isol_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol_STAT_DOWN, "weight_indiv_SF_MU_Isol_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol_SYST_UP, "weight_indiv_SF_MU_Isol_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol_SYST_DOWN, "weight_indiv_SF_MU_Isol_SYST_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA, "weight_indiv_SF_MU_TTVA"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA_STAT_UP, "weight_indiv_SF_MU_TTVA_STAT_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA_STAT_DOWN, "weight_indiv_SF_MU_TTVA_STAT_DOWN"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA_SYST_UP, "weight_indiv_SF_MU_TTVA_SYST_UP"); + systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA_SYST_DOWN, "weight_indiv_SF_MU_TTVA_SYST_DOWN"); + + if (m_config->useTaus()) { + // Tau-electron overlap removal + for (top::topSFSyst i = top::topSFSyst(top::topSFSyst::TAU_SF_NOMINAL + 1); i < top::topSFSyst::TAU_SF_END; + i = top::topSFSyst(i + 1)) { + if (top::tauSF_alias.find(i) == top::tauSF_alias.end()) continue; + if (m_config->tauSFDoRNNID() == false && top::tauSF_name.at(i).Contains("RNN")) continue; + if (m_config->tauSFDoBDTID() == false && top::tauSF_name.at(i).Contains("JETID")) continue; + m_weight_tauSF_variations[i] = 1; + systematicTree->makeOutputVariable(m_weight_tauSF_variations[i], ("weight_tauSF_" + top::tauSF_alias.at( + i)).Data()); + } + } + + if (m_config->usePhotons()) { + systematicTree->makeOutputVariable(m_weight_photonSF_ID_UP, + "weight_photonSF_ID_UP"); + systematicTree->makeOutputVariable(m_weight_photonSF_ID_DOWN, + "weight_photonSF_ID_DOWN"); + systematicTree->makeOutputVariable(m_weight_photonSF_effIso_UP, + "weight_photonSF_effIso_UP"); + systematicTree->makeOutputVariable(m_weight_photonSF_effIso_DOWN, + "weight_photonSF_effIso_DOWN"); } + + systematicTree->makeOutputVariable(m_weight_jvt_up, "weight_jvt_UP"); + systematicTree->makeOutputVariable(m_weight_jvt_down, "weight_jvt_DOWN"); + if (m_config->getfJVTWP() != "None") { + systematicTree->makeOutputVariable(m_weight_forwardjvt_up, "weight_forwardjvt_UP"); + systematicTree->makeOutputVariable(m_weight_forwardjvt_down, "weight_forwardjvt_DOWN"); + } } - if (m_config->doLooseEvents()) { - for (auto treeName : *config->systAllTTreeNames()) { - m_treeManagers.push_back(std::shared_ptr<top::TreeManager>( new top::TreeManager(treeName.second+"_Loose", file , m_config->outputFileSetAutoFlushZero()) ) ); - m_treeManagers.back()->branchFilters() = branchFilters(); - if (treeName.first == m_config->nominalHashValue()) { - nominalLooseTTreeName = treeName.second+"_Loose"; - } + // for b-tagging SFs, can also have systematic-shifted in systematics trees + if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName || + m_config->dumpBtagSystsInSystTrees()) { + // b-tagging SFs: eigenvectors and named systematics + for (auto& tagWP : m_config->bTagWP_available()) { + // skip uncalibrated though available WPs + if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), + tagWP) == m_config->bTagWP_calibrated().end()) continue; + // up + systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_B_up[tagWP], "weight_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_B_up"); + systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_C_up[tagWP], "weight_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_C_up"); + systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_Light_up[tagWP], + "weight_bTagSF_" + shortBtagWP(tagWP) + "_eigenvars_Light_up"); + // down + systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_B_down[tagWP], "weight_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_B_down"); + systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_C_down[tagWP], "weight_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_C_down"); + systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_Light_down[tagWP], + "weight_bTagSF_" + shortBtagWP(tagWP) + "_eigenvars_Light_down"); + // named systematics + for (auto name : m_config->btagging_namedSysts(tagWP)) { + systematicTree->makeOutputVariable(m_weight_bTagSF_named_up[tagWP][name], + "weight_bTagSF_" + shortBtagWP(tagWP) + "_" + betterBtagNamedSyst( + name) + "_up"); + systematicTree->makeOutputVariable(m_weight_bTagSF_named_down[tagWP][name], "weight_bTagSF_" + shortBtagWP( + tagWP) + "_" + betterBtagNamedSyst(name) + "_down"); } + } + if (m_config->useTrackJets()) { + for (auto& tagWP : m_config->bTagWP_available_trkJet()) { + // skip uncalibrated though available WPs + if (std::find(m_config->bTagWP_calibrated_trkJet().begin(), m_config->bTagWP_calibrated_trkJet().end(), + tagWP) == m_config->bTagWP_calibrated_trkJet().end()) continue; + // up + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_B_up[tagWP], "weight_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_B_up"); + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_C_up[tagWP], "weight_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_C_up"); + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_Light_up[tagWP], "weight_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_Light_up"); + // down + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_B_down[tagWP], "weight_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_B_down"); + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_C_down[tagWP], "weight_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_C_down"); + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_Light_down[tagWP], "weight_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_eigenvars_Light_down"); + // named systematics + for (auto name : m_config->trkjet_btagging_namedSysts(tagWP)) { + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_named_up[tagWP][name], "weight_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_" + betterBtagNamedSyst(name) + "_up"); + systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_named_down[tagWP][name], "weight_trackjet_bTagSF_" + shortBtagWP( + tagWP) + "_" + betterBtagNamedSyst(name) + "_down"); + } + } + } + } + } + + ///-- weights for matrix-method fakes estimate by IFF --/// + if (!m_config->isMC() && systematicTree->name() == nominalLooseTTreeName && m_config->doFakesMMWeightsIFF()) { + // std::vector<CP::AsymptMatrixTool*> fakesMMWeightCalcIFF; + // while (asg::ToolStore::contains<CP::AsymptMatrixTool>("AsymptMatrixTool_" + std::to_string (m_ASMsize))) { + // fakesMMWeightCalcIFF.push_back(asg::ToolStore::get<CP::AsymptMatrixTool>("AsymptMatrixTool_" + std::to_string (m_ASMsize))); + // ++m_ASMsize; + // } + // std::string ASMweights_branch_name = "ASM_weight"; + // std::string ASMweights_Syst_branch_name = "ASM_weight_Syst"; + // std::string ASMweights_Systname_branch_name = "ASM_weight_Systname"; + // systematicTree->makeOutputVariable(m_ASMweights, ASMweights_branch_name); + // m_ASMweights_Syst.resize(m_ASMsize); + // m_ASMweights_Systname.resize(m_ASMsize); + // for (int mmi = 0; mmi < m_ASMsize; ++mmi) { + // systematicTree->makeOutputVariable(m_ASMweights_Syst[mmi], + // ASMweights_Syst_branch_name + "_" + std::to_string(mmi)); + // systematicTree->makeOutputVariable(m_ASMweights_Systname[mmi], ASMweights_Systname_branch_name + "_" + std::to_string( + // mmi)); + // } + } + + /// Bootstrapping poisson weights + if (m_config->saveBootstrapWeights()) { + systematicTree->makeOutputVariable(m_weight_poisson, "weight_poisson"); + } + + //event info + systematicTree->makeOutputVariable(m_eventNumber, "eventNumber"); + systematicTree->makeOutputVariable(m_runNumber, "runNumber"); + if (m_config->isMC() && m_config->doPileupReweighting()) systematicTree->makeOutputVariable(m_randomRunNumber, + "randomRunNumber"); + systematicTree->makeOutputVariable(m_mcChannelNumber, "mcChannelNumber"); + systematicTree->makeOutputVariable(m_mu, "mu"); + systematicTree->makeOutputVariable(m_mu_actual, "mu_actual"); + if (!m_config->isMC()) { + systematicTree->makeOutputVariable(m_mu_original, "mu_original_xAOD"); + systematicTree->makeOutputVariable(m_mu_actual_original, "mu_actual_original_xAOD"); + } + systematicTree->makeOutputVariable(m_backgroundFlags, "backgroundFlags"); + if (m_config->useMuons()) systematicTree->makeOutputVariable(m_hasBadMuon, "hasBadMuon"); + + //electrons + if (m_config->useElectrons()) { + systematicTree->makeOutputVariable(m_el_pt, "el_pt"); + systematicTree->makeOutputVariable(m_el_eta, "el_eta"); + systematicTree->makeOutputVariable(m_el_cl_eta, "el_cl_eta"); + systematicTree->makeOutputVariable(m_el_phi, "el_phi"); + systematicTree->makeOutputVariable(m_el_e, "el_e"); + systematicTree->makeOutputVariable(m_el_charge, "el_charge"); + systematicTree->makeOutputVariable(m_el_topoetcone20, "el_topoetcone20"); + systematicTree->makeOutputVariable(m_el_ptvarcone20, "el_ptvarcone20"); + if (systematicTree->name().find("Loose") != std::string::npos) { + systematicTree->makeOutputVariable(m_el_isTight, "el_isTight"); } + systematicTree->makeOutputVariable(m_el_CF, "el_CF"); + systematicTree->makeOutputVariable(m_el_d0sig, "el_d0sig"); + systematicTree->makeOutputVariable(m_el_delta_z0_sintheta, "el_delta_z0_sintheta"); + if (m_useElectronChargeIDSelection) { + systematicTree->makeOutputVariable(m_el_ECIDS, "el_ECIDS"); + systematicTree->makeOutputVariable(m_el_ECIDSResult, "el_ECIDSResult"); + } + if (m_config->isMC()) { + systematicTree->makeOutputVariable(m_el_true_type, "el_true_type"); + systematicTree->makeOutputVariable(m_el_true_origin, "el_true_origin"); + systematicTree->makeOutputVariable(m_el_true_firstEgMotherTruthType, "el_true_firstEgMotherTruthType"); + systematicTree->makeOutputVariable(m_el_true_firstEgMotherTruthOrigin, "el_true_firstEgMotherTruthOrigin"); + systematicTree->makeOutputVariable(m_el_true_firstEgMotherPdgId, "el_true_firstEgMotherPdgId"); + systematicTree->makeOutputVariable(m_el_true_isPrompt, "el_true_isPrompt"); + systematicTree->makeOutputVariable(m_el_true_isChargeFl, "el_true_isChargeFl"); + } + if (m_config->enablePromptLeptonImprovedVetoStudies()) { + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonRNN_conversion, "PLIV_el_PromptLeptonRNN_conversion"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonRNN_non_prompt_b, "PLIV_el_PromptLeptonRNN_non_prompt_b"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonRNN_non_prompt_c, "PLIV_el_PromptLeptonRNN_non_prompt_c"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonRNN_prompt, "PLIV_el_PromptLeptonRNN_prompt"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_MVAXBin, "PLIV_el_PromptLeptonImprovedInput_MVAXBin"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_TrackJetNTrack, "PLIV_el_PromptLeptonImprovedInput_TrackJetNTrack"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_topoetcone30rel, "PLIV_el_PromptLeptonImprovedInput_topoetcone30rel"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_ptvarcone30rel, "PLIV_el_PromptLeptonImprovedInput_ptvarcone30rel"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_PtFrac, "PLIV_el_PromptLeptonImprovedInput_PtFrac"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_DRlj, "PLIV_el_PromptLeptonImprovedInput_DRlj"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_CaloClusterSumEtRel, "PLIV_el_PromptLeptonImprovedInput_CaloClusterSumEtRel"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_PtRel, "PLIV_el_PromptLeptonImprovedInput_PtRel"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx, "PLIV_el_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedVetoBARR, "PLIV_el_PromptLeptonImprovedVetoBARR"); + systematicTree->makeOutputVariable(m_PLIV_el_PromptLeptonImprovedVetoECAP, "PLIV_el_PromptLeptonImprovedVetoECAP"); + } + } - // Truth tree + //forward electrons + if (m_config->useFwdElectrons()) { + systematicTree->makeOutputVariable(m_fwdel_pt, "fwdel_pt"); + systematicTree->makeOutputVariable(m_fwdel_eta, "fwdel_eta"); + systematicTree->makeOutputVariable(m_fwdel_phi, "fwdel_phi"); + systematicTree->makeOutputVariable(m_fwdel_e, "fwdel_e"); + systematicTree->makeOutputVariable(m_fwdel_etcone20, "fwdel_etcone20"); + systematicTree->makeOutputVariable(m_fwdel_etcone30, "fwdel_etcone30"); + systematicTree->makeOutputVariable(m_fwdel_etcone40, "fwdel_etcone40"); + if (systematicTree->name().find("Loose") != std::string::npos) { + systematicTree->makeOutputVariable(m_fwdel_isTight, "fwdel_isTight"); + } + }//end of fwd electrons branches + + //muons + if (m_config->useMuons()) { + systematicTree->makeOutputVariable(m_mu_pt, "mu_pt"); + systematicTree->makeOutputVariable(m_mu_eta, "mu_eta"); + systematicTree->makeOutputVariable(m_mu_phi, "mu_phi"); + systematicTree->makeOutputVariable(m_mu_e, "mu_e"); + systematicTree->makeOutputVariable(m_mu_charge, "mu_charge"); + systematicTree->makeOutputVariable(m_mu_topoetcone20, "mu_topoetcone20"); + systematicTree->makeOutputVariable(m_mu_ptvarcone30, "mu_ptvarcone30"); + if (systematicTree->name().find("Loose") != std::string::npos) { + systematicTree->makeOutputVariable(m_mu_isTight, "mu_isTight"); + } + systematicTree->makeOutputVariable(m_mu_d0sig, "mu_d0sig"); + systematicTree->makeOutputVariable(m_mu_delta_z0_sintheta, "mu_delta_z0_sintheta"); if (m_config->isMC()) { + systematicTree->makeOutputVariable(m_mu_true_type, "mu_true_type"); + systematicTree->makeOutputVariable(m_mu_true_origin, "mu_true_origin"); + systematicTree->makeOutputVariable(m_mu_true_isPrompt, "mu_true_isPrompt"); + } + if (m_config->enablePromptLeptonImprovedVetoStudies()) { + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonRNN_non_prompt_b, "PLIV_mu_PromptLeptonRNN_non_prompt_b"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonRNN_non_prompt_c, "PLIV_mu_PromptLeptonRNN_non_prompt_c"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonRNN_prompt, "PLIV_mu_PromptLeptonRNN_prompt"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonImprovedInput_MVAXBin, "PLIV_mu_PromptLeptonImprovedInput_MVAXBin"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonImprovedInput_topoetcone30rel, "PLIV_mu_PromptLeptonImprovedInput_topoetcone30rel"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonImprovedInput_PtFrac, "PLIV_mu_PromptLeptonImprovedInput_PtFrac"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonImprovedInput_DRlj, "PLIV_mu_PromptLeptonImprovedInput_DRlj"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel, "PLIV_mu_PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonImprovedInput_CaloClusterERel, "PLIV_mu_PromptLeptonImprovedInput_CaloClusterERel"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest, "PLIV_mu_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest"); + systematicTree->makeOutputVariable(m_PLIV_mu_PromptLeptonImprovedVeto, "PLIV_mu_PromptLeptonImprovedVeto"); + } + } - m_sfRetriever = std::unique_ptr<top::ScaleFactorRetriever> ( new top::ScaleFactorRetriever( m_config ) ); - - m_truthTreeManager = std::shared_ptr<top::TreeManager>( new top::TreeManager( "truth" , file , m_config->outputFileSetAutoFlushZero()) ); - m_truthTreeManager->branchFilters() = branchFilters(); - m_truthTreeManager->makeOutputVariable(m_weight_mc, "weight_mc"); - m_truthTreeManager->makeOutputVariable(m_eventNumber, "eventNumber"); - m_truthTreeManager->makeOutputVariable(m_runNumber, "runNumber"); - m_truthTreeManager->makeOutputVariable(m_mu, "mu"); - m_truthTreeManager->makeOutputVariable(m_weight_pileup, "weight_pileup"); - if (m_config->isMC() && m_config->doPileupReweighting()) m_truthTreeManager->makeOutputVariable(m_randomRunNumber, "randomRunNumber"); - m_truthTreeManager->makeOutputVariable(m_mcChannelNumber, "mcChannelNumber"); - - // Only if you really really want it - this is BIG - if (m_config->useTruthParticles() && m_config->doTruthBlockInfo() ) { - m_truthTreeManager->makeOutputVariable(m_mc_pt, "mc_pt"); - m_truthTreeManager->makeOutputVariable(m_mc_eta, "mc_eta"); - m_truthTreeManager->makeOutputVariable(m_mc_phi, "mc_phi"); - m_truthTreeManager->makeOutputVariable(m_mc_e, "mc_e"); - m_truthTreeManager->makeOutputVariable(m_mc_pdgId, "mc_pdgId"); - } + //soft muons + if (m_config->useSoftMuons()) { + systematicTree->makeOutputVariable(m_softmu_pt, "softmu_pt"); + systematicTree->makeOutputVariable(m_softmu_eta, "softmu_eta"); + systematicTree->makeOutputVariable(m_softmu_phi, "softmu_phi"); + systematicTree->makeOutputVariable(m_softmu_e, "softmu_e"); + systematicTree->makeOutputVariable(m_softmu_charge, "softmu_charge"); + systematicTree->makeOutputVariable(m_softmu_d0, "softmu_d0"); + systematicTree->makeOutputVariable(m_softmu_d0sig, "softmu_d0sig"); + systematicTree->makeOutputVariable(m_softmu_delta_z0_sintheta, "softmu_delta_z0_sintheta"); + if (m_config->isMC()) { + systematicTree->makeOutputVariable(m_softmu_true_type, "softmu_true_type"); + systematicTree->makeOutputVariable(m_softmu_true_origin, "softmu_true_origin"); + systematicTree->makeOutputVariable(m_softmu_SF_ID, "softmu_SF_ID"); + + if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName) { + systematicTree->makeOutputVariable(m_softmu_SF_ID_STAT_UP, "softmu_SF_ID_STAT_UP"); + systematicTree->makeOutputVariable(m_softmu_SF_ID_STAT_DOWN, "softmu_SF_ID_STAT_DOWN"); + systematicTree->makeOutputVariable(m_softmu_SF_ID_SYST_UP, "softmu_SF_ID_SYST_UP"); + systematicTree->makeOutputVariable(m_softmu_SF_ID_SYST_DOWN, "softmu_SF_ID_SYST_DOWN"); + systematicTree->makeOutputVariable(m_softmu_SF_ID_STAT_LOWPT_UP, "softmu_SF_ID_STAT_LOWPT_UP"); + systematicTree->makeOutputVariable(m_softmu_SF_ID_STAT_LOWPT_DOWN, "softmu_SF_ID_STAT_LOWPT_DOWN"); + systematicTree->makeOutputVariable(m_softmu_SF_ID_SYST_LOWPT_UP, "softmu_SF_ID_SYST_LOWPT_UP"); + systematicTree->makeOutputVariable(m_softmu_SF_ID_SYST_LOWPT_DOWN, "softmu_SF_ID_SYST_LOWPT_DOWN"); + } + if(m_config->softmuonAdditionalTruthInfo()) + { + if(m_config->softmuonAdditionalTruthInfoCheckPartonOrigin()) systematicTree->makeOutputVariable(m_softmu_parton_origin_flag, "softmu_parton_origin_flag"); + systematicTree->makeOutputVariable(m_softmu_particle_origin_flag, "softmu_particle_origin_flag"); + systematicTree->makeOutputVariable(m_softmu_parent_pdgid,"softmu_parent_pdgid"); + systematicTree->makeOutputVariable(m_softmu_b_hadron_parent_pdgid,"softmu_b_hadron_parent_pdgid"); + systematicTree->makeOutputVariable(m_softmu_c_hadron_parent_pdgid,"softmu_c_hadron_parent_pdgid"); + } + }//end of if (m_config->isMC()) + }//end of if (m_config->useSoftMuons()) + + //photons + if (m_config->usePhotons()) { + systematicTree->makeOutputVariable(m_ph_pt, "ph_pt"); + systematicTree->makeOutputVariable(m_ph_eta, "ph_eta"); + systematicTree->makeOutputVariable(m_ph_phi, "ph_phi"); + systematicTree->makeOutputVariable(m_ph_e, "ph_e"); + systematicTree->makeOutputVariable(m_ph_iso, "ph_iso"); + } - // PDF information - if (m_config->doTruthPDFInfo()) { - if (m_config->doTruthPDFInfoInNominalTrees()) {//if PDF info requested to be saved in nominal trees of truth one - for (auto systematicTree : m_treeManagers) {//loop on systematic trees to only get the nominal ones - if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName) { - systematicTree->makeOutputVariable(m_PDFinfo_X1,"PDFinfo_X1"); - systematicTree->makeOutputVariable(m_PDFinfo_X2,"PDFinfo_X2"); - systematicTree->makeOutputVariable(m_PDFinfo_PDGID1,"PDFinfo_PDGID1"); - systematicTree->makeOutputVariable(m_PDFinfo_PDGID2,"PDFinfo_PDGID2"); - systematicTree->makeOutputVariable(m_PDFinfo_Q,"PDFinfo_Q"); - systematicTree->makeOutputVariable(m_PDFinfo_XF1,"PDFinfo_XF1"); - systematicTree->makeOutputVariable(m_PDFinfo_XF2,"PDFinfo_XF2"); - } - } - } - else { - m_truthTreeManager->makeOutputVariable(m_PDFinfo_X1,"PDFinfo_X1"); - m_truthTreeManager->makeOutputVariable(m_PDFinfo_X2,"PDFinfo_X2"); - m_truthTreeManager->makeOutputVariable(m_PDFinfo_PDGID1,"PDFinfo_PDGID1"); - m_truthTreeManager->makeOutputVariable(m_PDFinfo_PDGID2,"PDFinfo_PDGID2"); - m_truthTreeManager->makeOutputVariable(m_PDFinfo_Q,"PDFinfo_Q"); - m_truthTreeManager->makeOutputVariable(m_PDFinfo_XF1,"PDFinfo_XF1"); - m_truthTreeManager->makeOutputVariable(m_PDFinfo_XF2,"PDFinfo_XF2"); - } - } + //taus + if (m_config->useTaus()) { + systematicTree->makeOutputVariable(m_tau_pt, "tau_pt"); + systematicTree->makeOutputVariable(m_tau_eta, "tau_eta"); + systematicTree->makeOutputVariable(m_tau_phi, "tau_phi"); + systematicTree->makeOutputVariable(m_tau_charge, "tau_charge"); + } - // MC Generator weights - if (m_config->doMCGeneratorWeights()) { - if (m_config->doMCGeneratorWeightsInNominalTrees()) {//if MCGeneratorWeights requested to be saved in nominal trees of truth one - for (auto systematicTree : m_treeManagers) {//loop on systematic trees to only get the nominal ones - if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName) { - systematicTree->makeOutputVariable(m_mc_generator_weights,"mc_generator_weights"); - } - } - } - else { - m_truthTreeManager->makeOutputVariable(m_mc_generator_weights,"mc_generator_weights"); - } - } + //jets + if (m_config->useJets()) { + systematicTree->makeOutputVariable(m_jet_pt, "jet_pt"); + systematicTree->makeOutputVariable(m_jet_eta, "jet_eta"); + systematicTree->makeOutputVariable(m_jet_phi, "jet_phi"); + systematicTree->makeOutputVariable(m_jet_e, "jet_e"); + if (m_config->bTagAlgo_MV2c10_used()) { + systematicTree->makeOutputVariable(m_jet_mv2c10, "jet_mv2c10"); + } + systematicTree->makeOutputVariable(m_jet_jvt, "jet_jvt"); + if (m_config->doForwardJVTinMET() || m_config->getfJVTWP() != "None") { + systematicTree->makeOutputVariable(m_jet_fjvt, "jet_forwardjvt"); + systematicTree->makeOutputVariable(m_jet_passfjvt, "jet_passforwardjvt"); + } + if (m_config->isMC() && m_config->jetStoreTruthLabels()) { + systematicTree->makeOutputVariable(m_jet_truthflav, "jet_truthflav"); + systematicTree->makeOutputVariable(m_jet_truthPartonLabel, "jet_truthPartonLabel"); + systematicTree->makeOutputVariable(m_jet_isTrueHS, "jet_isTrueHS"); + systematicTree->makeOutputVariable(m_jet_HadronConeExclExtendedTruthLabelID, "jet_truthflavExtended"); + } - if( m_config->saveLHAPDFEvent() ){ - for( const auto& pdfset : m_config->LHAPDFSets() ) - m_PDF_eventWeights[ pdfset ] = std::vector<float>(); - - for( auto& pdf : m_PDF_eventWeights ) { - if (m_config->doLHAPDFInNominalTrees()) {//if PDF weights requested to be saved in nominal trees instead of truth one - for (auto systematicTree : m_treeManagers) {//loop on systematic trees to only get the nominal ones - if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName) - systematicTree->makeOutputVariable( pdf.second, pdf.first ); - } - } - else { - m_truthTreeManager->makeOutputVariable( pdf.second, pdf.first ); - } - } - } + if (m_config->useJetGhostTrack()) { + systematicTree->makeOutputVariable(m_jet_ghostTrack_pt, "jet_ghostTrack_pt"); + systematicTree->makeOutputVariable(m_jet_ghostTrack_eta, "jet_ghostTrack_eta"); + systematicTree->makeOutputVariable(m_jet_ghostTrack_phi, "jet_ghostTrack_phi"); + systematicTree->makeOutputVariable(m_jet_ghostTrack_e, "jet_ghostTrack_e"); + systematicTree->makeOutputVariable(m_jet_ghostTrack_d0, "jet_ghostTrack_d0"); + systematicTree->makeOutputVariable(m_jet_ghostTrack_z0, "jet_ghostTrack_z0"); + systematicTree->makeOutputVariable(m_jet_ghostTrack_qOverP, "jet_ghostTrack_qOverP"); } - //loop over systematics and attach variables - for (auto systematicTree : m_treeManagers) { - if (m_config->isMC()) { + for (auto& tagWP : m_config->bTagWP_available()) { + if (tagWP.find("Continuous") == std::string::npos) systematicTree->makeOutputVariable(m_jet_isbtagged[tagWP], "jet_isbtagged_" + shortBtagWP( + tagWP)); + else systematicTree->makeOutputVariable(m_jet_tagWeightBin[tagWP], "jet_tagWeightBin_" + tagWP); + } - systematicTree->makeOutputVariable(m_weight_mc, "weight_mc"); + for (const std::string& algo : m_config->bTagAlgo_available()) { + systematicTree->makeOutputVariable(m_jet_DLx[algo], "jet_" + algo); + systematicTree->makeOutputVariable(m_jet_DLx_pb[algo], "jet_" + algo + "_pb"); + systematicTree->makeOutputVariable(m_jet_DLx_pc[algo], "jet_" + algo + "_pc"); + systematicTree->makeOutputVariable(m_jet_DLx_pu[algo], "jet_" + algo + "_pu"); + } + } - //some event weights - systematicTree->makeOutputVariable(m_weight_pileup, "weight_pileup"); - systematicTree->makeOutputVariable(m_weight_leptonSF , "weight_leptonSF"); + // fail-JVT jets + if (m_config->saveFailJVTJets()) { + systematicTree->makeOutputVariable(m_failJvt_jet_pt, "failJvt_jet_pt"); + systematicTree->makeOutputVariable(m_failJvt_jet_eta, "failJvt_jet_eta"); + systematicTree->makeOutputVariable(m_failJvt_jet_phi, "failJvt_jet_phi"); + systematicTree->makeOutputVariable(m_failJvt_jet_e, "failJvt_jet_e"); + systematicTree->makeOutputVariable(m_failJvt_jet_jvt, "failJvt_jet_jvt"); + if (m_config->doForwardJVTinMET() || m_config->getfJVTWP() != "None") { + systematicTree->makeOutputVariable(m_failJvt_jet_fjvt, "failJvt_jet_forwardjvt"); + systematicTree->makeOutputVariable(m_failJvt_jet_passfjvt, "failJvt_jet_passforwardjvt"); + } + if (m_config->isMC() && m_config->jetStoreTruthLabels()) { + systematicTree->makeOutputVariable(m_failJvt_jet_truthflav, "failJvt_jet_truthflav"); + systematicTree->makeOutputVariable(m_failJvt_jet_truthPartonLabel, "failJvt_jet_truthPartonLabel"); + systematicTree->makeOutputVariable(m_failJvt_jet_isTrueHS, "failJvt_jet_isTrueHS"); + systematicTree->makeOutputVariable(m_failJvt_jet_HadronConeExclExtendedTruthLabelID, + "failJvt_jet_truthflavExtended"); + } - if (m_config->usePhotons()) - systematicTree->makeOutputVariable(m_weight_photonSF, - "weight_photonSF"); + if (m_config->useJetGhostTrack()) { + systematicTree->makeOutputVariable(m_failJvt_jet_ghostTrack_pt, "failJvt_jet_ghostTrack_pt"); + systematicTree->makeOutputVariable(m_failJvt_jet_ghostTrack_eta, "failJvt_jet_ghostTrack_eta"); + systematicTree->makeOutputVariable(m_failJvt_jet_ghostTrack_phi, "failJvt_jet_ghostTrack_phi"); + systematicTree->makeOutputVariable(m_failJvt_jet_ghostTrack_e, "failJvt_jet_ghostTrack_e"); + systematicTree->makeOutputVariable(m_failJvt_jet_ghostTrack_d0, "failJvt_jet_ghostTrack_d0"); + systematicTree->makeOutputVariable(m_failJvt_jet_ghostTrack_z0, "failJvt_jet_ghostTrack_z0"); + systematicTree->makeOutputVariable(m_failJvt_jet_ghostTrack_qOverP, "failJvt_jet_ghostTrack_qOverP"); + } + } - if (m_config->useTaus()) - systematicTree->makeOutputVariable(m_weight_tauSF, - "weight_tauSF"); + // fail-FJVT jets + if (m_config->getfJVTWP() != "None" && m_config->saveFailForwardJVTJets()) { + systematicTree->makeOutputVariable(m_failFJvt_jet_pt, "failforwardJvt_jet_pt"); + systematicTree->makeOutputVariable(m_failFJvt_jet_eta, "failforwardJvt_jet_eta"); + systematicTree->makeOutputVariable(m_failFJvt_jet_phi, "failforwardJvt_jet_phi"); + systematicTree->makeOutputVariable(m_failFJvt_jet_e, "failforwardJvt_jet_e"); + systematicTree->makeOutputVariable(m_failFJvt_jet_jvt, "failforwardJvt_jet_jvt"); + systematicTree->makeOutputVariable(m_failFJvt_jet_fjvt, "failforwardJvt_jet_forwardjvt"); + systematicTree->makeOutputVariable(m_failFJvt_jet_passjvt, "failforwardJvt_jet_passjvt"); + + if (m_config->isMC() && m_config->jetStoreTruthLabels()) { + systematicTree->makeOutputVariable(m_failFJvt_jet_truthflav, "failforwardJvt_jet_truthflav"); + systematicTree->makeOutputVariable(m_failFJvt_jet_truthPartonLabel, "failforwardJvt_jet_truthPartonLabel"); + systematicTree->makeOutputVariable(m_failFJvt_jet_isTrueHS, "failforwardJvt_jet_isTrueHS"); + systematicTree->makeOutputVariable(m_failFJvt_jet_HadronConeExclExtendedTruthLabelID, + "failforwardJvt_jet_truthflavExtended"); + } - // nominal b-tagging SFs - for( auto& tagWP : m_config -> bTagWP_available()){ - // skip uncalibrated though available WPs - if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; - m_weight_bTagSF[tagWP] = 0.; - systematicTree->makeOutputVariable(m_weight_bTagSF[tagWP] , "weight_bTagSF_"+shortBtagWP(tagWP)); - } - if( m_config->useTrackJets() ) { - for( auto& tagWP : m_config -> bTagWP_available_trkJet()) { - // skip uncalibrated though available WPs - if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; - m_weight_trackjet_bTagSF[tagWP] = 0.; - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF[tagWP] , "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)); - } - } + if (m_config->useJetGhostTrack()) { + systematicTree->makeOutputVariable(m_failFJvt_jet_ghostTrack_pt, "failforwardJvt_jet_ghostTrack_pt"); + systematicTree->makeOutputVariable(m_failFJvt_jet_ghostTrack_eta, "failforwardJvt_jet_ghostTrack_eta"); + systematicTree->makeOutputVariable(m_failFJvt_jet_ghostTrack_phi, "failforwardJvt_jet_ghostTrack_phi"); + systematicTree->makeOutputVariable(m_failFJvt_jet_ghostTrack_e, "failforwardJvt_jet_ghostTrack_e"); + systematicTree->makeOutputVariable(m_failFJvt_jet_ghostTrack_d0, "failforwardJvt_jet_ghostTrack_d0"); + systematicTree->makeOutputVariable(m_failFJvt_jet_ghostTrack_z0, "failforwardJvt_jet_ghostTrack_z0"); + systematicTree->makeOutputVariable(m_failFJvt_jet_ghostTrack_qOverP, "failforwardJvt_jet_ghostTrack_qOverP"); + } + } - systematicTree->makeOutputVariable(m_weight_jvt, "weight_jvt"); - - if (m_config->isSherpa22Vjets()) - systematicTree->makeOutputVariable(m_weight_sherpa_22_vjets, - "weight_sherpa_22_vjets"); - - if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName) { - - systematicTree->makeOutputVariable(m_weight_pileup_UP , "weight_pileup_UP"); - systematicTree->makeOutputVariable(m_weight_pileup_DOWN , "weight_pileup_DOWN"); - - systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Trigger_UP, "weight_leptonSF_EL_SF_Trigger_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Trigger_DOWN, "weight_leptonSF_EL_SF_Trigger_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Reco_UP, "weight_leptonSF_EL_SF_Reco_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Reco_DOWN, "weight_leptonSF_EL_SF_Reco_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_ID_UP, "weight_leptonSF_EL_SF_ID_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_ID_DOWN, "weight_leptonSF_EL_SF_ID_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Isol_UP, "weight_leptonSF_EL_SF_Isol_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_EL_SF_Isol_DOWN, "weight_leptonSF_EL_SF_Isol_DOWN"); - - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Trigger_STAT_UP, "weight_leptonSF_MU_SF_Trigger_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Trigger_STAT_DOWN, "weight_leptonSF_MU_SF_Trigger_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Trigger_SYST_UP, "weight_leptonSF_MU_SF_Trigger_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Trigger_SYST_DOWN, "weight_leptonSF_MU_SF_Trigger_SYST_DOWN"); - // Muon ID SF systematics (regular) - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_STAT_UP, "weight_leptonSF_MU_SF_ID_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_STAT_DOWN, "weight_leptonSF_MU_SF_ID_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_SYST_UP, "weight_leptonSF_MU_SF_ID_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_SYST_DOWN, "weight_leptonSF_MU_SF_ID_SYST_DOWN"); - // Muon ID SF systematics (low pt) - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP, "weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN, "weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP, "weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN, "weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN"); - // Muon isolation SF systematics - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Isol_STAT_UP, "weight_leptonSF_MU_SF_Isol_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Isol_STAT_DOWN, "weight_leptonSF_MU_SF_Isol_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Isol_SYST_UP, "weight_leptonSF_MU_SF_Isol_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_Isol_SYST_DOWN, "weight_leptonSF_MU_SF_Isol_SYST_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_TTVA_STAT_UP, "weight_leptonSF_MU_SF_TTVA_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_TTVA_STAT_DOWN, "weight_leptonSF_MU_SF_TTVA_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_TTVA_SYST_UP, "weight_leptonSF_MU_SF_TTVA_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_leptonSF_MU_SF_TTVA_SYST_DOWN, "weight_leptonSF_MU_SF_TTVA_SYST_DOWN"); - - - // write also out the individual components: - - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Trigger, "weight_indiv_SF_EL_Trigger"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Trigger_UP, "weight_indiv_SF_EL_Trigger_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Trigger_DOWN, "weight_indiv_SF_EL_Trigger_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Reco, "weight_indiv_SF_EL_Reco"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Reco_UP, "weight_indiv_SF_EL_Reco_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Reco_DOWN, "weight_indiv_SF_EL_Reco_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ID, "weight_indiv_SF_EL_ID"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ID_UP, "weight_indiv_SF_EL_ID_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ID_DOWN, "weight_indiv_SF_EL_ID_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Isol, "weight_indiv_SF_EL_Isol"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Isol_UP, "weight_indiv_SF_EL_Isol_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_Isol_DOWN, "weight_indiv_SF_EL_Isol_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeID, "weight_indiv_SF_EL_ChargeID"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeID_UP, "weight_indiv_SF_EL_ChargeID_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeID_DOWN, "weight_indiv_SF_EL_ChargeID_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID, "weight_indiv_SF_EL_ChargeMisID"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID_STAT_UP, "weight_indiv_SF_EL_ChargeMisID_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN,"weight_indiv_SF_EL_ChargeMisID_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID_SYST_UP, "weight_indiv_SF_EL_ChargeMisID_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN,"weight_indiv_SF_EL_ChargeMisID_SYST_DOWN"); - - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Trigger, "weight_indiv_SF_MU_Trigger"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Trigger_STAT_UP, "weight_indiv_SF_MU_Trigger_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Trigger_STAT_DOWN, "weight_indiv_SF_MU_Trigger_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Trigger_SYST_UP, "weight_indiv_SF_MU_Trigger_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Trigger_SYST_DOWN, "weight_indiv_SF_MU_Trigger_SYST_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID, "weight_indiv_SF_MU_ID"); - // Muon ID SF systematics (regular) - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_STAT_UP, "weight_indiv_SF_MU_ID_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_STAT_DOWN, "weight_indiv_SF_MU_ID_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_SYST_UP, "weight_indiv_SF_MU_ID_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_SYST_DOWN, "weight_indiv_SF_MU_ID_SYST_DOWN"); - // Muon ID SF systematics (low pt) - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_STAT_LOWPT_UP, "weight_indiv_SF_MU_ID_STAT_LOWPT_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN, "weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_SYST_LOWPT_UP, "weight_indiv_SF_MU_ID_SYST_LOWPT_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN, "weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN"); - // Muon isolation SF systematics - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol, "weight_indiv_SF_MU_Isol"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol_STAT_UP, "weight_indiv_SF_MU_Isol_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol_STAT_DOWN, "weight_indiv_SF_MU_Isol_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol_SYST_UP, "weight_indiv_SF_MU_Isol_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_Isol_SYST_DOWN, "weight_indiv_SF_MU_Isol_SYST_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA, "weight_indiv_SF_MU_TTVA"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA_STAT_UP, "weight_indiv_SF_MU_TTVA_STAT_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA_STAT_DOWN, "weight_indiv_SF_MU_TTVA_STAT_DOWN"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA_SYST_UP, "weight_indiv_SF_MU_TTVA_SYST_UP"); - systematicTree->makeOutputVariable(m_weight_indiv_SF_MU_TTVA_SYST_DOWN, "weight_indiv_SF_MU_TTVA_SYST_DOWN"); - - if (m_config->useTaus()) { - systematicTree->makeOutputVariable(m_weight_tauSF_ELEOLR_UP, - "weight_tauSF_ELEOLR_UP"); - systematicTree->makeOutputVariable(m_weight_tauSF_ELEOLR_DOWN, - "weight_tauSF_ELEOLR_DOWN"); - systematicTree->makeOutputVariable(m_weight_tauSF_JETID_UP, - "weight_tauSF_JETID_UP"); - systematicTree->makeOutputVariable(m_weight_tauSF_JETID_DOWN, - "weight_tauSF_JETID_DOWN"); - systematicTree->makeOutputVariable(m_weight_tauSF_RECO_UP, - "weight_tauSF_RECO_UP"); - systematicTree->makeOutputVariable(m_weight_tauSF_RECO_DOWN, - "weight_tauSF_RECO_DOWN"); - } - - if (m_config->usePhotons()) { - systematicTree->makeOutputVariable(m_weight_photonSF_ID_UP, - "weight_photonSF_ID_UP"); - systematicTree->makeOutputVariable(m_weight_photonSF_ID_DOWN, - "weight_photonSF_ID_DOWN"); - systematicTree->makeOutputVariable(m_weight_photonSF_effIso, - "weight_photonSF_effIso"); - systematicTree->makeOutputVariable(m_weight_photonSF_effLowPtIso_UP, - "weight_photonSF_effLowPtIso_UP"); - systematicTree->makeOutputVariable(m_weight_photonSF_effLowPtIso_DOWN, - "weight_photonSF_effLowPtIso_DOWN"); - systematicTree->makeOutputVariable(m_weight_photonSF_effTrkIso_UP, - "weight_photonSF_effTrkIso_UP"); - systematicTree->makeOutputVariable(m_weight_photonSF_effTrkIso_DOWN, - "weight_photonSF_effTrkIso_DOWN"); - } - - systematicTree->makeOutputVariable(m_weight_jvt_up, "weight_jvt_UP"); - systematicTree->makeOutputVariable(m_weight_jvt_down, "weight_jvt_DOWN"); + //large-R jets + if (m_config->useLargeRJets()) { + systematicTree->makeOutputVariable(m_ljet_pt, "ljet_pt"); + systematicTree->makeOutputVariable(m_ljet_eta, "ljet_eta"); + systematicTree->makeOutputVariable(m_ljet_phi, "ljet_phi"); + systematicTree->makeOutputVariable(m_ljet_e, "ljet_e"); + systematicTree->makeOutputVariable(m_ljet_m, "ljet_m"); - } + for (const std::pair<std::string,std::string>& it : m_config->largeRJetSubstructureVariables()) { + systematicTree->makeOutputVariable(m_ljet_substructure[it.first],"ljet_"+it.first); + } - // for b-tagging SFs, can also have systematic-shifted in systematics trees - if (systematicTree->name() == nominalTTreeName || systematicTree->name() == nominalLooseTTreeName || m_config->dumpBtagSystsInSystTrees()) { - // b-tagging SFs: eigenvectors and named systematics - for( auto& tagWP : m_config -> bTagWP_available()) { - // skip uncalibrated though available WPs - if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; - // up - systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_B_up[tagWP], "weight_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_B_up"); - systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_C_up[tagWP], "weight_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_C_up"); - systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_Light_up[tagWP], "weight_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_Light_up"); - // down - systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_B_down[tagWP], "weight_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_B_down"); - systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_C_down[tagWP], "weight_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_C_down"); - systematicTree->makeOutputVariable(m_weight_bTagSF_eigen_Light_down[tagWP], "weight_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_Light_down"); - // named systematics - for (auto name : m_config->btagging_namedSysts(tagWP)) { - systematicTree->makeOutputVariable(m_weight_bTagSF_named_up[tagWP][name], "weight_bTagSF_"+shortBtagWP(tagWP)+"_"+betterBtagNamedSyst(name)+"_up" ); - systematicTree->makeOutputVariable(m_weight_bTagSF_named_down[tagWP][name], "weight_bTagSF_"+shortBtagWP(tagWP)+"_"+betterBtagNamedSyst(name)+"_down" ); - } - } - if( m_config->useTrackJets() ) { - for( auto& tagWP : m_config -> bTagWP_available_trkJet()) { - // skip uncalibrated though available WPs - if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; - // up - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_B_up[tagWP], "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_B_up"); - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_C_up[tagWP], "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_C_up"); - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_Light_up[tagWP], "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_Light_up"); - // down - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_B_down[tagWP], "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_B_down"); - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_C_down[tagWP], "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_C_down"); - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_eigen_Light_down[tagWP], "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)+"_eigenvars_Light_down"); - // named systematics - for (auto name : m_config->trkjet_btagging_namedSysts(tagWP)) { - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_named_up[tagWP][name], "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)+"_"+betterBtagNamedSyst(name)+"_up" ); - systematicTree->makeOutputVariable(m_weight_trackjet_bTagSF_named_down[tagWP][name], "weight_trackjet_bTagSF_"+shortBtagWP(tagWP)+"_"+betterBtagNamedSyst(name)+"_down" ); - } - } - } - } - } + for (const std::string& taggerName : m_boostedJetTaggersNames) { + systematicTree->makeOutputVariable(m_ljet_isTagged[taggerName], "ljet_isTagged_" + taggerName); + } + + if (m_config->isMC()) { + systematicTree->makeOutputVariable(m_ljet_truthLabel, "ljet_truthLabel"); + for (const std::string& taggerName : m_boostedJetTaggersNamesCalibrated) { + systematicTree->makeOutputVariable(m_ljet_tagSF[taggerName], "ljet_tagSF_" + taggerName); + } + } + } + + //track jets + if (m_config->useTrackJets()) { + systematicTree->makeOutputVariable(m_tjet_pt, "tjet_pt"); + systematicTree->makeOutputVariable(m_tjet_eta, "tjet_eta"); + systematicTree->makeOutputVariable(m_tjet_phi, "tjet_phi"); + systematicTree->makeOutputVariable(m_tjet_e, "tjet_e"); + if (m_config->bTagAlgo_MV2c10_used_trkJet()) { + systematicTree->makeOutputVariable(m_tjet_mv2c10, "tjet_mv2c10"); + } + for (auto& tagWP : m_config->bTagWP_available_trkJet()) { + if (tagWP.find("Continuous") == std::string::npos) systematicTree->makeOutputVariable(m_tjet_isbtagged[tagWP], "tjet_isbtagged_" + shortBtagWP(tagWP)); + else systematicTree->makeOutputVariable(m_tjet_tagWeightBin[tagWP], "tjet_tagWeightBin_" + tagWP); + } + + for (const std::string& algo : m_config->bTagAlgo_available_trkJet()) { + systematicTree->makeOutputVariable(m_tjet_DLx[algo], "tjet_" + algo); + systematicTree->makeOutputVariable(m_tjet_DLx_pb[algo], "tjet_" + algo + "_pb"); + systematicTree->makeOutputVariable(m_tjet_DLx_pc[algo], "tjet_" + algo + "_pc"); + systematicTree->makeOutputVariable(m_tjet_DLx_pu[algo], "tjet_" + algo + "_pu"); + } + } - ///-- weights for matrix-method fakes estimate --/// - if (!m_config->isMC() && systematicTree->name().find("Loose") != std::string::npos && m_config->doFakesMMWeights()) { - top::TopFakesMMWeightCalculator const* fakesMMWeightCalc(nullptr); - if ( asg::ToolStore::contains<top::TopFakesMMWeightCalculator>("MMWeightCalculator") ) { - fakesMMWeightCalc = asg::ToolStore::get<top::TopFakesMMWeightCalculator>("MMWeightCalculator"); - } - else { - ATH_MSG_ERROR("EventSaverFlatNtuple::initialize" ); - throw std::runtime_error("Unable to retrieve top::TopFakesMMWeightCalculator tool"); - } - for(const auto& branchName : m_extraBranches){//loop on selections - for(const auto& conf : fakesMMWeightCalc->GetFakesMMConfigNames(branchName)) { - std::string MMweight_branch_name = "fakesMM_weight_" + branchName + "_" + conf; - systematicTree->makeOutputVariable(m_fakesMM_weights[branchName][conf], MMweight_branch_name); - } - } + if (m_config->useTracks()) { + systematicTree->makeOutputVariable(m_track_pt, "track_pt"); + systematicTree->makeOutputVariable(m_track_eta, "track_eta"); + systematicTree->makeOutputVariable(m_track_phi, "track_phi"); + systematicTree->makeOutputVariable(m_track_e, "track_e"); + systematicTree->makeOutputVariable(m_track_charge, "track_charge"); + systematicTree->makeOutputVariable(m_track_d0, "track_d0"); + systematicTree->makeOutputVariable(m_track_d0_significance, "track_d0_significance"); + systematicTree->makeOutputVariable(m_track_z0, "track_z0"); + systematicTree->makeOutputVariable(m_track_z0_significance, "track_z0_significance"); + systematicTree->makeOutputVariable(m_track_phi0, "track_phi0"); + systematicTree->makeOutputVariable(m_track_theta, "track_theta"); + systematicTree->makeOutputVariable(m_track_qOverP, "track_qOverP"); + systematicTree->makeOutputVariable(m_track_chiSquared, "track_chiSquared"); + systematicTree->makeOutputVariable(m_track_numberDoF, "track_numberDoF"); + } + + + + // RC branches + if (m_makeRCJets) { + systematicTree->makeOutputVariable(m_rcjet_pt, "rcjet_pt"); + systematicTree->makeOutputVariable(m_rcjet_eta, "rcjet_eta"); + systematicTree->makeOutputVariable(m_rcjet_phi, "rcjet_phi"); + systematicTree->makeOutputVariable(m_rcjet_e, "rcjet_e"); + systematicTree->makeOutputVariable(m_rcjet_d12, "rcjet_d12"); // requires >= 2 subjets + systematicTree->makeOutputVariable(m_rcjet_d23, "rcjet_d23"); // requires >= 3 subjets + systematicTree->makeOutputVariable(m_rcjetsub_pt, "rcjetsub_pt"); // vector of vectors for subjet info + systematicTree->makeOutputVariable(m_rcjetsub_eta, "rcjetsub_eta"); + systematicTree->makeOutputVariable(m_rcjetsub_phi, "rcjetsub_phi"); + systematicTree->makeOutputVariable(m_rcjetsub_e, "rcjetsub_e"); + if (m_config->bTagAlgo_MV2c10_used()) { + systematicTree->makeOutputVariable(m_rcjetsub_mv2c10, "rcjetsub_mv2c10"); + } + + if (m_useRCJSS || m_useRCAdditionalJSS) { + systematicTree->makeOutputVariable(m_rrcjet_pt, "rrcjet_pt"); + systematicTree->makeOutputVariable(m_rrcjet_eta, "rrcjet_eta"); + systematicTree->makeOutputVariable(m_rrcjet_phi, "rrcjet_phi"); + systematicTree->makeOutputVariable(m_rrcjet_e, "rrcjet_e"); + } + if (m_useRCJSS) { + // RCJet SS from Clusters + systematicTree->makeOutputVariable(m_rcjet_tau32_clstr, "rcjet_tau32_clstr"); + systematicTree->makeOutputVariable(m_rcjet_tau21_clstr, "rcjet_tau21_clstr"); + systematicTree->makeOutputVariable(m_rcjet_tau3_clstr, "rcjet_tau3_clstr"); + systematicTree->makeOutputVariable(m_rcjet_tau2_clstr, "rcjet_tau2_clstr"); + systematicTree->makeOutputVariable(m_rcjet_tau1_clstr, "rcjet_tau1_clstr"); + systematicTree->makeOutputVariable(m_rcjet_d12_clstr, "rcjet_d12_clstr"); + systematicTree->makeOutputVariable(m_rcjet_d23_clstr, "rcjet_d23_clstr"); + systematicTree->makeOutputVariable(m_rcjet_Qw_clstr, "rcjet_Qw_clstr"); + systematicTree->makeOutputVariable(m_rcjet_nconstituent_clstr, "rcjet_nconstituent_clstr"); + systematicTree->makeOutputVariable(m_rcjet_D2_clstr, "rcjet_D2_clstr"); + systematicTree->makeOutputVariable(m_rcjet_ECF1_clstr, "rcjet_ECF1_clstr"); + systematicTree->makeOutputVariable(m_rcjet_ECF2_clstr, "rcjet_ECF2_clstr"); + systematicTree->makeOutputVariable(m_rcjet_ECF3_clstr, "rcjet_ECF3_clstr"); + } + if (m_useRCAdditionalJSS) { + systematicTree->makeOutputVariable(m_rcjet_gECF332_clstr, "rcjet_gECF332_clstr"); + systematicTree->makeOutputVariable(m_rcjet_gECF461_clstr, "rcjet_gECF461_clstr"); + systematicTree->makeOutputVariable(m_rcjet_gECF322_clstr, "rcjet_gECF322_clstr"); + systematicTree->makeOutputVariable(m_rcjet_gECF331_clstr, "rcjet_gECF331_clstr"); + systematicTree->makeOutputVariable(m_rcjet_gECF422_clstr, "rcjet_gECF422_clstr"); + systematicTree->makeOutputVariable(m_rcjet_gECF441_clstr, "rcjet_gECF441_clstr"); + systematicTree->makeOutputVariable(m_rcjet_gECF212_clstr, "rcjet_gECF212_clstr"); + systematicTree->makeOutputVariable(m_rcjet_gECF321_clstr, "rcjet_gECF321_clstr"); + systematicTree->makeOutputVariable(m_rcjet_gECF311_clstr, "rcjet_gECF311_clstr"); + systematicTree->makeOutputVariable(m_rcjet_L1_clstr, "rcjet_L1_clstr"); + systematicTree->makeOutputVariable(m_rcjet_L2_clstr, "rcjet_L2_clstr"); + systematicTree->makeOutputVariable(m_rcjet_L3_clstr, "rcjet_L3_clstr"); + systematicTree->makeOutputVariable(m_rcjet_L4_clstr, "rcjet_L4_clstr"); + systematicTree->makeOutputVariable(m_rcjet_L5_clstr, "rcjet_L5_clstr"); + } + } + // vRC branches + if (m_makeVarRCJets) { + std::string VarRC = "vrcjet"; + + for (auto& rho : m_VarRCJetRho) { + for (auto& mass_scale : m_VarRCJetMassScale) { + std::replace(rho.begin(), rho.end(), '.', '_'); + std::string name = rho + mass_scale; + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_pt"], VarRC + "_" + name + "_pt"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_eta"], VarRC + "_" + name + "_eta"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_phi"], VarRC + "_" + name + "_phi"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_e"], VarRC + "_" + name + "_e"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_d12"], VarRC + "_" + name + "_d12"); // requires + // >= + // 2 + // subjets + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_d23"], VarRC + "_" + name + "_d23"); // requires + // >= + // 3 + // subjets + systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_pt"], VarRC + "sub_" + name + "_pt"); // vector + // of + // vectors + // for + // subjet + // info + systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_eta"], VarRC + "sub_" + name + "_eta"); + systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_phi"], VarRC + "sub_" + name + "_phi"); + systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_e"], VarRC + "sub_" + name + "_e"); + if (m_config->bTagAlgo_MV2c10_used()) { + systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_mv2c10"], VarRC + "sub_" + name + "_mv2c10"); } - //event info - systematicTree->makeOutputVariable(m_eventNumber, "eventNumber"); - systematicTree->makeOutputVariable(m_runNumber, "runNumber"); - if (m_config->isMC() && m_config->doPileupReweighting()) systematicTree->makeOutputVariable(m_randomRunNumber, "randomRunNumber"); - systematicTree->makeOutputVariable(m_mcChannelNumber, "mcChannelNumber"); - systematicTree->makeOutputVariable(m_mu, "mu"); - if (!m_config->isMC()) { - systematicTree->makeOutputVariable(m_mu_original, "mu_original_xAOD"); + if (m_useVarRCJSS || m_useVarRCAdditionalJSS) { + systematicTree->makeOutputVariable(m_VarRCjetBranches["vrrcjet_" + name + "_pt"], "vrrcjet_" + name + "_pt"); + systematicTree->makeOutputVariable(m_VarRCjetBranches["vrrcjet_" + name + "_eta"], "vrrcjet_" + name + "_eta"); + systematicTree->makeOutputVariable(m_VarRCjetBranches["vrrcjet_" + name + "_phi"], "vrrcjet_" + name + "_phi"); + systematicTree->makeOutputVariable(m_VarRCjetBranches["vrrcjet_" + name + "_e"], "vrrcjet_" + name + "_e"); } - systematicTree->makeOutputVariable(m_backgroundFlags, "backgroundFlags"); - if (m_config->useMuons()) - systematicTree->makeOutputVariable(m_hasBadMuon, "hasBadMuon"); - - //electrons - if (m_config->useElectrons()) { - systematicTree->makeOutputVariable(m_el_pt, "el_pt"); - systematicTree->makeOutputVariable(m_el_eta, "el_eta"); - systematicTree->makeOutputVariable(m_el_cl_eta, "el_cl_eta"); - systematicTree->makeOutputVariable(m_el_phi, "el_phi"); - systematicTree->makeOutputVariable(m_el_e, "el_e"); - systematicTree->makeOutputVariable(m_el_charge, "el_charge"); - systematicTree->makeOutputVariable(m_el_topoetcone20, "el_topoetcone20"); - systematicTree->makeOutputVariable(m_el_ptvarcone20, "el_ptvarcone20"); - if (systematicTree->name().find("Loose") != std::string::npos) { - systematicTree->makeOutputVariable(m_el_isTight, "el_isTight"); - } - systematicTree->makeOutputVariable(m_el_CF, "el_CF"); - systematicTree->makeOutputVariable(m_el_d0sig, "el_d0sig"); - systematicTree->makeOutputVariable(m_el_delta_z0_sintheta, "el_delta_z0_sintheta"); - if (m_config->isMC()) { - systematicTree->makeOutputVariable(m_el_true_type, "el_true_type"); - systematicTree->makeOutputVariable(m_el_true_origin, "el_true_origin"); - systematicTree->makeOutputVariable(m_el_true_typebkg, "el_true_typebkg"); - systematicTree->makeOutputVariable(m_el_true_originbkg, "el_true_originbkg"); - } + if (m_useVarRCJSS) { + // RCJet SS from Clusters + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_tau32_clstr"], VarRC + "_" + name + "_tau32_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_tau21_clstr"], VarRC + "_" + name + "_tau21_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_tau3_clstr"], VarRC + "_" + name + "_tau3_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_tau2_clstr"], VarRC + "_" + name + "_tau2_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_tau1_clstr"], VarRC + "_" + name + "_tau1_clstr"); + + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_d12_clstr"], VarRC + "_" + name + "_d12_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_d23_clstr"], VarRC + "_" + name + "_d23_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_Qw_clstr"], VarRC + "_" + name + "_Qw_clstr"); + + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_D2_clstr"], VarRC + "_" + name + "_D2_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_ECF1_clstr"], VarRC + "_" + name + "_ECF1_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_ECF2_clstr"], VarRC + "_" + name + "_ECF2_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_ECF3_clstr"], VarRC + "_" + name + "_ECF3_clstr"); } - - //muons - if (m_config->useMuons()) { - systematicTree->makeOutputVariable(m_mu_pt, "mu_pt"); - systematicTree->makeOutputVariable(m_mu_eta, "mu_eta"); - systematicTree->makeOutputVariable(m_mu_phi, "mu_phi"); - systematicTree->makeOutputVariable(m_mu_e, "mu_e"); - systematicTree->makeOutputVariable(m_mu_charge, "mu_charge"); - systematicTree->makeOutputVariable(m_mu_topoetcone20, "mu_topoetcone20"); - systematicTree->makeOutputVariable(m_mu_ptvarcone30, "mu_ptvarcone30"); - if (systematicTree->name().find("Loose") != std::string::npos) { - systematicTree->makeOutputVariable(m_mu_isTight, "mu_isTight"); - } - systematicTree->makeOutputVariable(m_mu_d0sig, "mu_d0sig"); - systematicTree->makeOutputVariable(m_mu_delta_z0_sintheta, "mu_delta_z0_sintheta"); - if (m_config->isMC()) { - systematicTree->makeOutputVariable(m_mu_true_type, "mu_true_type"); - systematicTree->makeOutputVariable(m_mu_true_origin, "mu_true_origin"); - } + if (m_useVarRCAdditionalJSS) { + + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF332_clstr"], VarRC + "_" + name + "_gECF332_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF461_clstr"], VarRC + "_" + name + "_gECF461_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF322_clstr"], VarRC + "_" + name + "_gECF322_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF331_clstr"], VarRC + "_" + name + "_gECF331_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF422_clstr"], VarRC + "_" + name + "_gECF422_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF441_clstr"], VarRC + "_" + name + "_gECF441_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF212_clstr"], VarRC + "_" + name + "_gECF212_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF321_clstr"], VarRC + "_" + name + "_gECF321_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_gECF311_clstr"], VarRC + "_" + name + "_gECF311_clstr"); + + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_L1_clstr"], VarRC + "_" + name + "_L1_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_L2_clstr"], VarRC + "_" + name + "_L2_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_L3_clstr"], VarRC + "_" + name + "_L3_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_L4_clstr"], VarRC + "_" + name + "_L4_clstr"); + systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC + "_" + name + "_L5_clstr"], VarRC + "_" + name + "_L5_clstr"); } + } // end loop over mass parameters + } // end loop over multipliers for mass scale + } // end if VarRC jets + + //met + systematicTree->makeOutputVariable(m_met_met, "met_met"); + systematicTree->makeOutputVariable(m_met_phi, "met_phi"); + //these are for specific studies on the met, turned off by default, and turned on with the WriteMETBuiltWithLooseObjects option + if(m_config->writeMETBuiltWithLooseObjects()) + { + systematicTree->makeOutputVariable(m_met_met_withLooseObjects, "met_met_withLooseObjects"); + systematicTree->makeOutputVariable(m_met_phi_withLooseObjects, "met_phi_withLooseObjects"); + } - //photons - if (m_config->usePhotons()) { - systematicTree->makeOutputVariable(m_ph_pt, "ph_pt"); - systematicTree->makeOutputVariable(m_ph_eta, "ph_eta"); - systematicTree->makeOutputVariable(m_ph_phi, "ph_phi"); - systematicTree->makeOutputVariable(m_ph_e, "ph_e"); - systematicTree->makeOutputVariable(m_ph_iso, "ph_iso"); - } + if (m_config->doKLFitter()) { + /// Global result + systematicTree->makeOutputVariable(m_klfitter_logLikelihood, "klfitter_logLikelihood"); + systematicTree->makeOutputVariable(m_klfitter_eventProbability, "klfitter_eventProbability"); + systematicTree->makeOutputVariable(m_klfitter_selected, "klfitter_selected"); + + // If FULL information is requested + if (m_config->KLFitterOutput() == "FULL") { + /// Debugging information + systematicTree->makeOutputVariable(m_klfitter_selection, "klfitter_selection"); + systematicTree->makeOutputVariable(m_klfitter_minuitDidNotConverge, "klfitter_minuitDidNotConverge"); + systematicTree->makeOutputVariable(m_klfitter_fitAbortedDueToNaN, "klfitter_fitAbortedDueToNaN"); + systematicTree->makeOutputVariable(m_klfitter_atLeastOneFitParameterAtItsLimit, "klfitter_atLeastOneFitParameterAtItsLimit"); + systematicTree->makeOutputVariable(m_klfitter_invalidTransferFunctionAtConvergence, "klfitter_invalidTransferFunctionAtConvergence"); + /// Global + systematicTree->makeOutputVariable(m_klfitter_parameters_size, "klfitter_parameters_size"); + systematicTree->makeOutputVariable(m_klfitter_parameters, "klfitter_parameters"); + systematicTree->makeOutputVariable(m_klfitter_parameterErrors, "klfitter_parameterErrors"); + systematicTree->makeOutputVariable(m_klfitter_bestPermutation, "klfitter_bestPermutation"); + } - //taus - if (m_config->useTaus()) { - systematicTree->makeOutputVariable(m_tau_pt, "tau_pt"); - systematicTree->makeOutputVariable(m_tau_eta, "tau_eta"); - systematicTree->makeOutputVariable(m_tau_phi, "tau_phi"); - systematicTree->makeOutputVariable(m_tau_charge, "tau_charge"); - } + if (m_config->KLFitterOutput() == "FULL" || m_config->KLFitterOutput() == "JETPERM_ONLY") { + /// Model + if (m_config->KLFitterLH() == "ttbar" || m_config->KLFitterLH() == "ttZTrilepton" || m_config->KLFitterLH() == "ttH" || m_config->KLFitterLH() == "ttbar_JetAngles" || m_config->KLFitterLH() == "ttbar_BoostedLJets") { + systematicTree->makeOutputVariable(m_klfitter_model_bhad_pt, "klfitter_model_bhad_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_bhad_eta, "klfitter_model_bhad_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_bhad_phi, "klfitter_model_bhad_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_bhad_E, "klfitter_model_bhad_E"); + systematicTree->makeOutputVariable(m_klfitter_model_bhad_jetIndex, "klfitter_model_bhad_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_blep_pt, "klfitter_model_blep_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_blep_eta, "klfitter_model_blep_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_blep_phi, "klfitter_model_blep_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_blep_E, "klfitter_model_blep_E"); + systematicTree->makeOutputVariable(m_klfitter_model_blep_jetIndex, "klfitter_model_blep_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_lq1_pt, "klfitter_model_lq1_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lq1_eta, "klfitter_model_lq1_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lq1_phi, "klfitter_model_lq1_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lq1_E, "klfitter_model_lq1_E"); + systematicTree->makeOutputVariable(m_klfitter_model_lq1_jetIndex, "klfitter_model_lq1_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_lep_pt, "klfitter_model_lep_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lep_eta, "klfitter_model_lep_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lep_phi, "klfitter_model_lep_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lep_E, "klfitter_model_lep_E"); + + systematicTree->makeOutputVariable(m_klfitter_model_nu_pt, "klfitter_model_nu_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_nu_eta, "klfitter_model_nu_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_nu_phi, "klfitter_model_nu_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_nu_E, "klfitter_model_nu_E"); + + if (m_config->KLFitterLH() != "ttbar_BoostedLJets") { + systematicTree->makeOutputVariable(m_klfitter_model_lq2_pt, "klfitter_model_lq2_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lq2_eta, "klfitter_model_lq2_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lq2_phi, "klfitter_model_lq2_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lq2_E, "klfitter_model_lq2_E"); + systematicTree->makeOutputVariable(m_klfitter_model_lq2_jetIndex, "klfitter_model_lq2_jetIndex"); + + if (m_config->KLFitterLH() == "ttZTrilepton") { + systematicTree->makeOutputVariable(m_klfitter_model_lep_index, "klfitter_model_lep_index"); + + systematicTree->makeOutputVariable(m_klfitter_model_lepZ1_pt, "klfitter_model_lepZ1_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lepZ1_eta, "klfitter_model_lepZ1_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lepZ1_phi, "klfitter_model_lepZ1_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lepZ1_E, "klfitter_model_lepZ1_E"); + systematicTree->makeOutputVariable(m_klfitter_model_lepZ1_index, "klfitter_model_lepZ1_index"); + + systematicTree->makeOutputVariable(m_klfitter_model_lepZ2_pt, "klfitter_model_lepZ2_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lepZ2_eta, "klfitter_model_lepZ2_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lepZ2_phi, "klfitter_model_lepZ2_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lepZ2_E, "klfitter_model_lepZ2_E"); + systematicTree->makeOutputVariable(m_klfitter_model_lepZ2_index, "klfitter_model_lepZ2_index"); + } - //jets - if (m_config->useJets()) { - systematicTree->makeOutputVariable(m_jet_pt, "jet_pt"); - systematicTree->makeOutputVariable(m_jet_eta, "jet_eta"); - systematicTree->makeOutputVariable(m_jet_phi, "jet_phi"); - systematicTree->makeOutputVariable(m_jet_e, "jet_e"); - systematicTree->makeOutputVariable(m_jet_mv2c00, "jet_mv2c00"); - systematicTree->makeOutputVariable(m_jet_mv2c10, "jet_mv2c10"); - systematicTree->makeOutputVariable(m_jet_mv2c20, "jet_mv2c20"); - systematicTree->makeOutputVariable(m_jet_ip3dsv1, "jet_ip3dsv1"); - systematicTree->makeOutputVariable(m_jet_jvt, "jet_jvt"); - systematicTree->makeOutputVariable(m_jet_passfjvt,"jet_passfjvt"); - if (m_config->isMC()) { - systematicTree->makeOutputVariable(m_jet_truthflav, "jet_truthflav"); - systematicTree->makeOutputVariable(m_jet_truthPartonLabel, "jet_truthPartonLabel"); - systematicTree->makeOutputVariable(m_jet_isTrueHS, "jet_isTrueHS"); - } - for( auto& tagWP : m_config -> bTagWP_available()){ - if (tagWP!= "Continuous") systematicTree->makeOutputVariable(m_jet_isbtagged[tagWP] , "jet_isbtagged_"+shortBtagWP(tagWP)); - else systematicTree->makeOutputVariable(m_jet_tagWeightBin , "jet_tagWeightBin"); - } + if (m_config->KLFitterLH() == "ttH") { + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_pt, "klfitter_model_Higgs_b1_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_eta, "klfitter_model_Higgs_b1_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_phi, "klfitter_model_Higgs_b1_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_E, "klfitter_model_Higgs_b1_E"); + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_jetIndex, "klfitter_model_Higgs_b1_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_pt, "klfitter_model_Higgs_b2_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_eta, "klfitter_model_Higgs_b2_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_phi, "klfitter_model_Higgs_b2_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_E, "klfitter_model_Higgs_b2_E"); + systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_jetIndex, "klfitter_model_Higgs_b2_jetIndex"); + } } + } else if (m_config->KLFitterLH() == "ttbar_AllHadronic") { + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top1_pt, "klfitter_model_b_from_top1_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top1_eta, "klfitter_model_b_from_top1_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top1_phi, "klfitter_model_b_from_top1_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top1_E, "klfitter_model_b_from_top1_E"); + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top1_jetIndex, "klfitter_model_b_from_top1_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top2_pt, "klfitter_model_b_from_top2_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top2_eta, "klfitter_model_b_from_top2_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top2_phi, "klfitter_model_b_from_top2_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top2_E, "klfitter_model_b_from_top2_E"); + systematicTree->makeOutputVariable(m_klfitter_model_b_from_top2_jetIndex, "klfitter_model_b_from_top2_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top1_pt, "klfitter_model_lj1_from_top1_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top1_eta, "klfitter_model_lj1_from_top1_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top1_phi, "klfitter_model_lj1_from_top1_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top1_E, "klfitter_model_lj1_from_top1_E"); + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top1_jetIndex, "klfitter_model_lj1_from_top1_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top1_pt, "klfitter_model_lj2_from_top1_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top1_eta, "klfitter_model_lj2_from_top1_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top1_phi, "klfitter_model_lj2_from_top1_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top1_E, "klfitter_model_lj2_from_top1_E"); + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top1_jetIndex, "klfitter_model_lj2_from_top1_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top2_pt, "klfitter_model_lj1_from_top2_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top2_eta, "klfitter_model_lj1_from_top2_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top2_phi, "klfitter_model_lj1_from_top2_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top2_E, "klfitter_model_lj1_from_top2_E"); + systematicTree->makeOutputVariable(m_klfitter_model_lj1_from_top2_jetIndex, "klfitter_model_lj1_from_top2_jetIndex"); + + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top2_pt, "klfitter_model_lj2_from_top2_pt"); + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top2_eta, "klfitter_model_lj2_from_top2_eta"); + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top2_phi, "klfitter_model_lj2_from_top2_phi"); + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top2_E, "klfitter_model_lj2_from_top2_E"); + systematicTree->makeOutputVariable(m_klfitter_model_lj2_from_top2_jetIndex, "klfitter_model_lj2_from_top2_jetIndex"); + } + } - //large-R jets - if (m_config->useLargeRJets()) { - systematicTree->makeOutputVariable(m_ljet_pt, "ljet_pt"); - systematicTree->makeOutputVariable(m_ljet_eta, "ljet_eta"); - systematicTree->makeOutputVariable(m_ljet_phi, "ljet_phi"); - systematicTree->makeOutputVariable(m_ljet_e, "ljet_e"); - systematicTree->makeOutputVariable(m_ljet_m, "ljet_m"); - systematicTree->makeOutputVariable(m_ljet_sd12, "ljet_sd12"); - } + if (m_config->KLFitterOutput() == "FULL" || m_config->KLFitterOutput() == "FITTEDTOPS_ONLY") { + if (m_config->KLFitterLH() == "ttbar" || m_config->KLFitterLH() == "ttZTrilepton" || m_config->KLFitterLH() == "ttH" || m_config->KLFitterLH() == "ttbar_JetAngles") { + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_pt, "klfitter_bestPerm_topLep_pt"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_eta, "klfitter_bestPerm_topLep_eta"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_phi, "klfitter_bestPerm_topLep_phi"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_E, "klfitter_bestPerm_topLep_E"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_m, "klfitter_bestPerm_topLep_m"); + + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_pt, "klfitter_bestPerm_topHad_pt"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_eta, "klfitter_bestPerm_topHad_eta"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_phi, "klfitter_bestPerm_topHad_phi"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_E, "klfitter_bestPerm_topHad_E"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_m, "klfitter_bestPerm_topHad_m"); + + systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_pt, "klfitter_bestPerm_ttbar_pt"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_eta, "klfitter_bestPerm_ttbar_eta"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_phi, "klfitter_bestPerm_ttbar_phi"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_E, "klfitter_bestPerm_ttbar_E"); + systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_m, "klfitter_bestPerm_ttbar_m"); + } + } + } - //track jets - if (m_config->useTrackJets()) { - systematicTree->makeOutputVariable(m_tjet_pt, "tjet_pt"); - systematicTree->makeOutputVariable(m_tjet_eta, "tjet_eta"); - systematicTree->makeOutputVariable(m_tjet_phi, "tjet_phi"); - systematicTree->makeOutputVariable(m_tjet_e, "tjet_e"); - systematicTree->makeOutputVariable(m_tjet_mv2c00, "tjet_mv2c00"); - systematicTree->makeOutputVariable(m_tjet_mv2c10, "tjet_mv2c10"); - systematicTree->makeOutputVariable(m_tjet_mv2c20, "tjet_mv2c20"); - for( auto& tagWP : m_config -> bTagWP_available_trkJet()){ - if (tagWP!= "Continuous") systematicTree->makeOutputVariable(m_tjet_isbtagged[tagWP] , "tjet_isbtagged_"+shortBtagWP(tagWP)); - else systematicTree->makeOutputVariable(m_tjet_tagWeightBin , "tjet_tagWeightBin"); - } - } + if (m_config->doPseudoTop()) { + systematicTree->makeOutputVariable(m_PseudoTop_Reco_ttbar_pt, "PseudoTop_Reco_ttbar_pt"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_ttbar_eta, "PseudoTop_Reco_ttbar_eta"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_ttbar_phi, "PseudoTop_Reco_ttbar_phi"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_ttbar_m, "PseudoTop_Reco_ttbar_m"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_had_pt, "PseudoTop_Reco_top_had_pt"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_had_eta, "PseudoTop_Reco_top_had_eta"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_had_phi, "PseudoTop_Reco_top_had_phi"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_had_m, "PseudoTop_Reco_top_had_m"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_lep_pt, "PseudoTop_Reco_top_lep_pt"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_lep_eta, "PseudoTop_Reco_top_lep_eta"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_lep_phi, "PseudoTop_Reco_top_lep_phi"); + systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_lep_m, "PseudoTop_Reco_top_lep_m"); + } - // RC branches - if (m_makeRCJets){ - systematicTree->makeOutputVariable(m_rcjet_pt, "rcjet_pt"); - systematicTree->makeOutputVariable(m_rcjet_eta, "rcjet_eta"); - systematicTree->makeOutputVariable(m_rcjet_phi, "rcjet_phi"); - systematicTree->makeOutputVariable(m_rcjet_e, "rcjet_e"); - systematicTree->makeOutputVariable(m_rcjet_d12, "rcjet_d12"); // requires >= 2 subjets - systematicTree->makeOutputVariable(m_rcjet_d23, "rcjet_d23"); // requires >= 3 subjets - systematicTree->makeOutputVariable(m_rcjetsub_pt, "rcjetsub_pt"); // vector of vectors for subjet info - systematicTree->makeOutputVariable(m_rcjetsub_eta, "rcjetsub_eta"); - systematicTree->makeOutputVariable(m_rcjetsub_phi, "rcjetsub_phi"); - systematicTree->makeOutputVariable(m_rcjetsub_e, "rcjetsub_e"); - systematicTree->makeOutputVariable(m_rcjetsub_mv2c10, "rcjetsub_mv2c10"); - } + //extra branches telling you if the event passed / failed a selection + int index(0); + for (const auto& branchName : m_extraBranches) { + m_selectionDecisions[index] = 0; + systematicTree->makeOutputVariable(m_selectionDecisions[index], branchName); + // Add all triggers to a map so we don't get any duplicates + for (auto& trigger_name : m_config->allTriggers_Tight(branchName)) { + m_triggerDecisions [trigger_name] = 0; + } + for (auto& trigger_name : m_config->allTriggers_Loose(branchName)) { + // let's make sure this isn't done twice + if (m_triggerDecisions.find(trigger_name) != m_triggerDecisions.end() + && m_triggerPrescales.find(trigger_name) != m_triggerPrescales.end()) continue; + m_triggerDecisions [trigger_name] = 0; + } + for (auto& trigger_name : m_config->electronTriggers_Tight(branchName)) + m_el_trigMatched [trigger_name] = std::vector<char>(); + for (auto& trigger_name : m_config->electronTriggers_Loose(branchName)) { + // let's make sure this isn't done twice + if (m_el_trigMatched.find(trigger_name) != m_el_trigMatched.end()) continue; + m_el_trigMatched [trigger_name] = std::vector<char>(); + } + for (auto& trigger_name : m_config->muonTriggers_Tight(branchName)) + m_mu_trigMatched [trigger_name] = std::vector<char>(); + for (auto& trigger_name : m_config->muonTriggers_Loose(branchName)) { + // let's make sure this isn't done twice + if (m_mu_trigMatched.find(trigger_name) != m_mu_trigMatched.end()) continue; + m_mu_trigMatched [trigger_name] = std::vector<char>(); + } + ++index; + } - // vRC branches - if (m_makeVarRCJets){ - std::string VarRC = "vrcjet"; - - for (auto& rho : m_VarRCJetRho){ - for (auto& mass_scale : m_VarRCJetMassScale){ - std::replace( rho.begin(), rho.end(), '.', '_'); - std::string name = rho+mass_scale; - systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC+"_"+name+"_pt"], VarRC+"_"+name+"_pt"); - systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC+"_"+name+"_eta"],VarRC+"_"+name+"_eta"); - systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC+"_"+name+"_phi"],VarRC+"_"+name+"_phi"); - systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC+"_"+name+"_e"], VarRC+"_"+name+"_e"); - systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC+"_"+name+"_d12"],VarRC+"_"+name+"_d12"); // requires >= 2 subjets - systematicTree->makeOutputVariable(m_VarRCjetBranches[VarRC+"_"+name+"_d23"],VarRC+"_"+name+"_d23"); // requires >= 3 subjets - systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_pt"], VarRC+"sub_"+name+"_pt"); // vector of vectors for subjet info - systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_eta"], VarRC+"sub_"+name+"_eta"); - systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_phi"], VarRC+"sub_"+name+"_phi"); - systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_e"], VarRC+"sub_"+name+"_e"); - systematicTree->makeOutputVariable(m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_mv2c10"], VarRC+"sub_"+name+"_mv2c10"); - } // end loop over mass parameters - } // end loop over multipliers for mass scale - } // end if VarRC jets - - //met - systematicTree->makeOutputVariable(m_met_met, "met_met"); - systematicTree->makeOutputVariable(m_met_phi, "met_phi"); - - if (m_config->doKLFitter()) { - systematicTree->makeOutputVariable(m_klfitter_selected,"klfitter_selected"); - systematicTree->makeOutputVariable(m_klfitter_minuitDidNotConverge,"klfitter_minuitDidNotConverge"); - systematicTree->makeOutputVariable(m_klfitter_fitAbortedDueToNaN,"klfitter_fitAbortedDueToNaN"); - systematicTree->makeOutputVariable(m_klfitter_atLeastOneFitParameterAtItsLimit,"klfitter_atLeastOneFitParameterAtItsLimit"); - systematicTree->makeOutputVariable(m_klfitter_invalidTransferFunctionAtConvergence,"klfitter_invalidTransferFunctionAtConvergence"); - - /// Global result - systematicTree->makeOutputVariable(m_klfitter_bestPermutation,"klfitter_bestPermutation"); - systematicTree->makeOutputVariable(m_klfitter_logLikelihood,"klfitter_logLikelihood"); - systematicTree->makeOutputVariable(m_klfitter_eventProbability,"klfitter_eventProbability"); - systematicTree->makeOutputVariable(m_klfitter_parameters,"klfitter_parameters"); - systematicTree->makeOutputVariable(m_klfitter_parameterErrors,"klfitter_parameterErrors"); - - /// Model - systematicTree->makeOutputVariable(m_klfitter_model_bhad_pt,"klfitter_model_bhad_pt"); - systematicTree->makeOutputVariable(m_klfitter_model_bhad_eta,"klfitter_model_bhad_eta"); - systematicTree->makeOutputVariable(m_klfitter_model_bhad_phi,"klfitter_model_bhad_phi"); - systematicTree->makeOutputVariable(m_klfitter_model_bhad_E,"klfitter_model_bhad_E"); - systematicTree->makeOutputVariable(m_klfitter_model_bhad_jetIndex,"klfitter_model_bhad_jetIndex"); - - systematicTree->makeOutputVariable(m_klfitter_model_blep_pt,"klfitter_model_blep_pt"); - systematicTree->makeOutputVariable(m_klfitter_model_blep_eta,"klfitter_model_blep_eta"); - systematicTree->makeOutputVariable(m_klfitter_model_blep_phi,"klfitter_model_blep_phi"); - systematicTree->makeOutputVariable(m_klfitter_model_blep_E,"klfitter_model_blep_E"); - systematicTree->makeOutputVariable(m_klfitter_model_blep_jetIndex,"klfitter_model_blep_jetIndex"); - - systematicTree->makeOutputVariable(m_klfitter_model_lq1_pt,"klfitter_model_lq1_pt"); - systematicTree->makeOutputVariable(m_klfitter_model_lq1_eta,"klfitter_model_lq1_eta"); - systematicTree->makeOutputVariable(m_klfitter_model_lq1_phi,"klfitter_model_lq1_phi"); - systematicTree->makeOutputVariable(m_klfitter_model_lq1_E,"klfitter_model_lq1_E"); - systematicTree->makeOutputVariable(m_klfitter_model_lq1_jetIndex,"klfitter_model_lq1_jetIndex"); - - systematicTree->makeOutputVariable(m_klfitter_model_lq2_pt,"klfitter_model_lq2_pt"); - systematicTree->makeOutputVariable(m_klfitter_model_lq2_eta,"klfitter_model_lq2_eta"); - systematicTree->makeOutputVariable(m_klfitter_model_lq2_phi,"klfitter_model_lq2_phi"); - systematicTree->makeOutputVariable(m_klfitter_model_lq2_E,"klfitter_model_lq2_E"); - systematicTree->makeOutputVariable(m_klfitter_model_lq2_jetIndex,"klfitter_model_lq2_jetIndex"); - - if(m_config->KLFitterLH() == "ttH"){ - - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_pt,"klfitter_model_Higgs_b1_pt"); - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_eta,"klfitter_model_Higgs_b1_eta"); - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_phi,"klfitter_model_Higgs_b1_phi"); - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_E,"klfitter_model_Higgs_b1_E"); - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b1_jetIndex,"klfitter_model_Higgs_b1_jetIndex"); - - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_pt,"klfitter_model_Higgs_b2_pt"); - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_eta,"klfitter_model_Higgs_b2_eta"); - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_phi,"klfitter_model_Higgs_b2_phi"); - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_E,"klfitter_model_Higgs_b2_E"); - systematicTree->makeOutputVariable(m_klfitter_model_Higgs_b2_jetIndex,"klfitter_model_Higgs_b2_jetIndex"); - - } - - systematicTree->makeOutputVariable(m_klfitter_model_lep_pt,"klfitter_model_lep_pt"); - systematicTree->makeOutputVariable(m_klfitter_model_lep_eta,"klfitter_model_lep_eta"); - systematicTree->makeOutputVariable(m_klfitter_model_lep_phi,"klfitter_model_lep_phi"); - systematicTree->makeOutputVariable(m_klfitter_model_lep_E,"klfitter_model_lep_E"); - - systematicTree->makeOutputVariable(m_klfitter_model_nu_pt,"klfitter_model_nu_pt"); - systematicTree->makeOutputVariable(m_klfitter_model_nu_eta,"klfitter_model_nu_eta"); - systematicTree->makeOutputVariable(m_klfitter_model_nu_phi,"klfitter_model_nu_phi"); - systematicTree->makeOutputVariable(m_klfitter_model_nu_E,"klfitter_model_nu_E"); - - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_pt,"klfitter_bestPerm_topLep_pt"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_eta,"klfitter_bestPerm_topLep_eta"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_phi,"klfitter_bestPerm_topLep_phi"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_E,"klfitter_bestPerm_topLep_E"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topLep_m,"klfitter_bestPerm_topLep_m"); - - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_pt,"klfitter_bestPerm_topHad_pt"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_eta,"klfitter_bestPerm_topHad_eta"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_phi,"klfitter_bestPerm_topHad_phi"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_E,"klfitter_bestPerm_topHad_E"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_topHad_m,"klfitter_bestPerm_topHad_m"); - - systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_pt,"klfitter_bestPerm_ttbar_pt"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_eta,"klfitter_bestPerm_ttbar_eta"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_phi,"klfitter_bestPerm_ttbar_phi"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_E,"klfitter_bestPerm_ttbar_E"); - systematicTree->makeOutputVariable(m_klfitter_bestPerm_ttbar_m,"klfitter_bestPerm_ttbar_m"); + for (auto& trig_name : m_triggerDecisions) + systematicTree->makeOutputVariable(trig_name.second, trig_name.first); + for (auto& trig_name : m_el_trigMatched) + systematicTree->makeOutputVariable(trig_name.second, "el_trigMatch_" + trig_name.first); + for (auto& trig_name : m_mu_trigMatched) + systematicTree->makeOutputVariable(trig_name.second, "mu_trigMatch_" + trig_name.first); + } + setupUpgradeTreeManager(); + setupParticleLevelTreeManager(); + } - } + void EventSaverFlatNtuple::execute() { + if (m_config->isMC() && m_config->doMCGeneratorWeights()) { + loadMCGeneratorWeights(); + } - if (m_config->doPseudoTop()) { - - systematicTree->makeOutputVariable(m_PseudoTop_Reco_ttbar_pt, "PseudoTop_Reco_ttbar_pt"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_ttbar_eta, "PseudoTop_Reco_ttbar_eta"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_ttbar_phi, "PseudoTop_Reco_ttbar_phi"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_ttbar_m, "PseudoTop_Reco_ttbar_m"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_had_pt, "PseudoTop_Reco_top_had_pt"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_had_eta, "PseudoTop_Reco_top_had_eta"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_had_phi, "PseudoTop_Reco_top_had_phi"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_had_m, "PseudoTop_Reco_top_had_m"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_lep_pt, "PseudoTop_Reco_top_lep_pt"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_lep_eta, "PseudoTop_Reco_top_lep_eta"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_lep_phi, "PseudoTop_Reco_top_lep_phi"); - systematicTree->makeOutputVariable(m_PseudoTop_Reco_top_lep_m, "PseudoTop_Reco_top_lep_m"); + if (m_config->isMC() && m_config->doTruthPDFInfo()) { + loadPdfInfo(); + } - } + if (m_config->isMC() && m_config->saveLHAPDFEvent()) { + loadPdfWeights(); + } + } - //extra branches telling you if the event passed / failed a selection - int index(0); - for (const auto& branchName : m_extraBranches) { - m_selectionDecisions[index] = 0; - systematicTree->makeOutputVariable(m_selectionDecisions[index], branchName); - // Add all triggers to a map so we don't get any duplicates - for (auto& trigger_name : m_config->allTriggers( branchName ) ) { - m_triggerDecisions [trigger_name] = 0; - if (!m_config->isMC() && m_config->doFakesMMWeights()) - m_triggerPrescales [trigger_name] = -99999.;//initialised to dummmy value, in case it can't be retrieved by the tool - } - for (auto& trigger_name : m_config->electronTriggers( branchName ) ) - m_el_trigMatched [trigger_name] = std::vector<char>(); - for (auto& trigger_name : m_config->muonTriggers( branchName ) ) - m_mu_trigMatched [trigger_name] = std::vector<char>(); - ++index; - } + void EventSaverFlatNtuple::setupParticleLevelTreeManager(/*const top::ParticleLevelEvent& plEvent*/) { + // Quick return if particle level is disabled or the tree is already initialised. + // If particle level is disabled, no tree will be created. + if (not m_config->doTopParticleLevel() or m_particleLevelTreeManager) { + return; + } - for( auto& trig_name : m_triggerDecisions ) - systematicTree->makeOutputVariable( trig_name.second, trig_name.first ); - if (!m_config->isMC() && m_config->doFakesMMWeights()) { - for( auto& trig_name : m_triggerPrescales ) - systematicTree->makeOutputVariable( trig_name.second, "PS_"+trig_name.first ); - } - for( auto& trig_name : m_el_trigMatched ) - systematicTree->makeOutputVariable( trig_name.second, "el_trigMatch_"+trig_name.first ); - for( auto& trig_name : m_mu_trigMatched ) - systematicTree->makeOutputVariable( trig_name.second, "mu_trigMatch_"+trig_name.first ); + m_particleLevelTreeManager = std::make_shared<top::TreeManager>("particleLevel", m_outputFile, m_config->outputFileNEventAutoFlush(), m_config->outputFileBasketSizePrimitive(), m_config->outputFileBasketSizeVector()); + + m_particleLevelTreeManager->branchFilters() = branchFilters(); + m_particleLevelTreeManager->makeOutputVariable(m_weight_mc, "weight_mc"); + + //event info + m_particleLevelTreeManager->makeOutputVariable(m_eventNumber, "eventNumber"); + m_particleLevelTreeManager->makeOutputVariable(m_runNumber, "runNumber"); + if (m_config->isMC() && m_config->doPileupReweighting()) m_particleLevelTreeManager->makeOutputVariable(m_randomRunNumber, "randomRunNumber"); + m_particleLevelTreeManager->makeOutputVariable(m_mcChannelNumber, "mcChannelNumber"); + m_particleLevelTreeManager->makeOutputVariable(m_mu, "mu"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_actual, "mu_actual"); + m_particleLevelTreeManager->makeOutputVariable(m_weight_pileup, "weight_pileup"); + + if (m_config->doPseudoTop()) { + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_ttbar_pt, "PseudoTop_Particle_ttbar_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_ttbar_eta, "PseudoTop_Particle_ttbar_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_ttbar_phi, "PseudoTop_Particle_ttbar_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_ttbar_m, "PseudoTop_Particle_ttbar_m"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_had_pt, "PseudoTop_Particle_top_had_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_had_eta, "PseudoTop_Particle_top_had_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_had_phi, "PseudoTop_Particle_top_had_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_had_m, "PseudoTop_Particle_top_had_m"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_lep_pt, "PseudoTop_Particle_top_lep_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_lep_eta, "PseudoTop_Particle_top_lep_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_lep_phi, "PseudoTop_Particle_top_lep_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_lep_m, "PseudoTop_Particle_top_lep_m"); + } - } + //electrons + if (m_config->useTruthElectrons()) { + m_particleLevelTreeManager->makeOutputVariable(m_el_pt, "el_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_el_eta, "el_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_el_phi, "el_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_el_e, "el_e"); + m_particleLevelTreeManager->makeOutputVariable(m_el_charge, "el_charge"); + + m_particleLevelTreeManager->makeOutputVariable(m_el_true_type, "el_true_type"); + m_particleLevelTreeManager->makeOutputVariable(m_el_true_origin, "el_true_origin"); + + m_particleLevelTreeManager->makeOutputVariable(m_el_pt_bare, "el_pt_bare"); + m_particleLevelTreeManager->makeOutputVariable(m_el_eta_bare, "el_eta_bare"); + m_particleLevelTreeManager->makeOutputVariable(m_el_phi_bare, "el_phi_bare"); + m_particleLevelTreeManager->makeOutputVariable(m_el_e_bare, "el_e_bare"); } - void EventSaverFlatNtuple::setupParticleLevelTreeManager(const top::ParticleLevelEvent& plEvent){ - // Quick return if particle level is disabled or the tree is already initialised. - // If particle level is disabled, no tree will be created. - if ( not m_config->doTopParticleLevel() or m_particleLevelTreeManager ){ - return; + //muons + if (m_config->useTruthMuons()) { + m_particleLevelTreeManager->makeOutputVariable(m_mu_pt, "mu_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_eta, "mu_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_phi, "mu_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_e, "mu_e"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_charge, "mu_charge"); + + m_particleLevelTreeManager->makeOutputVariable(m_mu_true_type, "mu_true_type"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_true_origin, "mu_true_origin"); + + m_particleLevelTreeManager->makeOutputVariable(m_mu_pt_bare, "mu_pt_bare"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_eta_bare, "mu_eta_bare"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_phi_bare, "mu_phi_bare"); + m_particleLevelTreeManager->makeOutputVariable(m_mu_e_bare, "mu_e_bare"); + + if(m_config->useSoftMuons()) + { + m_particleLevelTreeManager->makeOutputVariable(m_softmu_pt, "softmu_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_eta, "softmu_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_phi, "softmu_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_e, "softmu_e"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_charge, "softmu_charge"); + + m_particleLevelTreeManager->makeOutputVariable(m_softmu_true_type, "softmu_true_type"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_true_origin, "softmu_true_origin"); + + if(m_config->softmuonAdditionalTruthInfo()) + { + if(m_config->softmuonAdditionalTruthInfoCheckPartonOrigin()) m_particleLevelTreeManager->makeOutputVariable(m_softmu_parton_origin_flag, "softmu_parton_origin_flag"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_particle_origin_flag, "softmu_particle_origin_flag"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_parent_pdgid,"softmu_parent_pdgid"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_b_hadron_parent_pdgid,"softmu_b_hadron_parent_pdgid"); + m_particleLevelTreeManager->makeOutputVariable(m_softmu_c_hadron_parent_pdgid,"softmu_c_hadron_parent_pdgid"); } + } + }//end of muons branches + + //photons + if (m_config->useTruthPhotons()) { + m_particleLevelTreeManager->makeOutputVariable(m_ph_pt, "ph_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_ph_eta, "ph_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_ph_phi, "ph_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_ph_e, "ph_e"); + } + + //jets + if (m_config->useTruthJets()) { + m_particleLevelTreeManager->makeOutputVariable(m_jet_pt, "jet_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_jet_eta, "jet_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_jet_phi, "jet_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_jet_e, "jet_e"); + + m_particleLevelTreeManager->makeOutputVariable(m_jet_Ghosts_BHadron_Final_Count, "jet_nGhosts_bHadron"); + m_particleLevelTreeManager->makeOutputVariable(m_jet_Ghosts_CHadron_Final_Count, "jet_nGhosts_cHadron"); + } - m_particleLevelTreeManager = std::make_shared<top::TreeManager>( "particleLevel", m_outputFile, m_config->outputFileSetAutoFlushZero() ); + //large R jets + if (m_config->useTruthLargeRJets()) { + m_particleLevelTreeManager->makeOutputVariable(m_ljet_pt, "ljet_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_ljet_eta, "ljet_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_ljet_phi, "ljet_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_ljet_e, "ljet_e"); - m_particleLevelTreeManager->makeOutputVariable(m_weight_mc, "weight_mc"); + m_particleLevelTreeManager->makeOutputVariable(m_ljet_Ghosts_BHadron_Final_Count, "ljet_nGhosts_bHadron"); + m_particleLevelTreeManager->makeOutputVariable(m_ljet_Ghosts_CHadron_Final_Count, "ljet_nGhosts_cHadron"); + } - //event info - m_particleLevelTreeManager->makeOutputVariable(m_eventNumber, "eventNumber"); - m_particleLevelTreeManager->makeOutputVariable(m_runNumber, "runNumber"); - if (m_config->isMC() && m_config->doPileupReweighting()) m_particleLevelTreeManager->makeOutputVariable(m_randomRunNumber, "randomRunNumber"); - m_particleLevelTreeManager->makeOutputVariable(m_mcChannelNumber, "mcChannelNumber"); - m_particleLevelTreeManager->makeOutputVariable(m_mu, "mu"); - m_particleLevelTreeManager->makeOutputVariable(m_weight_pileup, "weight_pileup"); + //taus + if (m_config->useTruthTaus()) { + m_particleLevelTreeManager->makeOutputVariable(m_tau_pt, "tau_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_tau_eta, "tau_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_tau_phi, "tau_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_tau_e, "tau_e"); + m_particleLevelTreeManager->makeOutputVariable(m_tau_charge, "tau_charge"); + m_particleLevelTreeManager->makeOutputVariable(m_tau_isHadronic, "tau_isHadronic"); + } - if (m_config->doPseudoTop()) { + // RC branches + if (m_makeRCJets) { + // create the branches + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_pt, "rcjet_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_eta, "rcjet_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_phi, "rcjet_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_e, "rcjet_e"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_d12, "rcjet_d12"); // requires >= 2 subjets + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_d23, "rcjet_d23"); // requires >= 3 subjets + m_particleLevelTreeManager->makeOutputVariable(m_rcjetsub_pt, "rcjetsub_pt"); // vector of vectors for subjet + // info + m_particleLevelTreeManager->makeOutputVariable(m_rcjetsub_eta, "rcjetsub_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjetsub_phi, "rcjetsub_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjetsub_e, "rcjetsub_e"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjetsub_Ghosts_BHadron_Final_Count, "rcjetsub_nGhosts_bHadron"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjetsub_Ghosts_CHadron_Final_Count, "rcjetsub_nGhosts_cHadron"); + + if (m_useRCJSS || m_useRCAdditionalJSS) { + m_particleLevelTreeManager->makeOutputVariable(m_rrcjet_pt, "rrcjet_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_rrcjet_eta, "rrcjet_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_rrcjet_phi, "rrcjet_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_rrcjet_e, "rrcjet_e"); + } - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_ttbar_pt, "PseudoTop_Particle_ttbar_pt"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_ttbar_eta, "PseudoTop_Particle_ttbar_eta"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_ttbar_phi, "PseudoTop_Particle_ttbar_phi"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_ttbar_m, "PseudoTop_Particle_ttbar_m"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_had_pt, "PseudoTop_Particle_top_had_pt"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_had_eta, "PseudoTop_Particle_top_had_eta"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_had_phi, "PseudoTop_Particle_top_had_phi"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_had_m, "PseudoTop_Particle_top_had_m"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_lep_pt, "PseudoTop_Particle_top_lep_pt"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_lep_eta, "PseudoTop_Particle_top_lep_eta"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_lep_phi, "PseudoTop_Particle_top_lep_phi"); - m_particleLevelTreeManager->makeOutputVariable(m_PseudoTop_Particle_top_lep_m, "PseudoTop_Particle_top_lep_m"); + if (m_useRCJSS) { + // RCJet SS from Clusters + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_tau32_clstr, "rcjet_tau32_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_tau21_clstr, "rcjet_tau21_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_tau3_clstr, "rcjet_tau3_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_tau2_clstr, "rcjet_tau2_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_tau1_clstr, "rcjet_tau1_clstr"); + + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_d12_clstr, "rcjet_d12_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_d23_clstr, "rcjet_d23_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_Qw_clstr, "rcjet_Qw_clstr"); + + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_nconstituent_clstr, "rcjet_nconstituent_clstr"); + + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_D2_clstr, "rcjet_D2_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_ECF1_clstr, "rcjet_ECF1_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_ECF2_clstr, "rcjet_ECF2_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_ECF3_clstr, "rcjet_ECF3_clstr"); - } + } + if (m_useRCAdditionalJSS) { + + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF332_clstr, "rcjet_gECF332_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF461_clstr, "rcjet_gECF461_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF322_clstr, "rcjet_gECF322_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF331_clstr, "rcjet_gECF331_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF422_clstr, "rcjet_gECF422_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF441_clstr, "rcjet_gECF441_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF212_clstr, "rcjet_gECF212_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF321_clstr, "rcjet_gECF321_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_gECF311_clstr, "rcjet_gECF311_clstr"); + + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_L1_clstr, "rcjet_L1_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_L2_clstr, "rcjet_L2_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_L3_clstr, "rcjet_L3_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_L4_clstr, "rcjet_L4_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_rcjet_L5_clstr, "rcjet_L5_clstr"); + } + } - //electrons - if ( m_config->useTruthElectrons() ){ - m_particleLevelTreeManager->makeOutputVariable(m_el_pt, "el_pt"); - m_particleLevelTreeManager->makeOutputVariable(m_el_eta, "el_eta"); - m_particleLevelTreeManager->makeOutputVariable(m_el_phi, "el_phi"); - m_particleLevelTreeManager->makeOutputVariable(m_el_e, "el_e"); - m_particleLevelTreeManager->makeOutputVariable(m_el_charge, "el_charge"); + if (m_makeVarRCJets) { + std::string VarRC = "vrcjet"; + + for (auto& rho : m_VarRCJetRho) { + for (auto& mass_scale : m_VarRCJetMassScale) { + std::replace(rho.begin(), rho.end(), '.', '_'); + std::string name = rho + mass_scale; + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_pt"], VarRC + "_" + name + "_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_eta"], VarRC + "_" + name + "_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_phi"], VarRC + "_" + name + "_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_e"], VarRC + "_" + name + "_e"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d12"], VarRC + "_" + name + "_d12"); // requires + // >= + // 2 + // subjets + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d23"], VarRC + "_" + name + "_d23"); // requires + // >= + // 3 + // subjets + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_pt"], VarRC + "sub_" + name + "_pt"); // vector + // of + // vectors + // for + // subjet + // info + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_eta"], VarRC + "sub_" + name + "_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_phi"], VarRC + "sub_" + name + "_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_e"], VarRC + "sub_" + name + "_e"); + + if (m_useVarRCJSS || m_useVarRCAdditionalJSS) { + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle["vrrcjet_" + name + "_pt"], "vrrcjet_" + name + "_pt"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle["vrrcjet_" + name + "_eta"], "vrrcjet_" + name + "_eta"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle["vrrcjet_" + name + "_phi"], "vrrcjet_" + name + "_phi"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle["vrrcjet_" + name + "_e"], "vrrcjet_" + name + "_e"); + } + if (m_useVarRCJSS) { + // RCJet SS from Clusters + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau32_clstr"], VarRC + "_" + name + "_tau32_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau21_clstr"], VarRC + "_" + name + "_tau21_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau3_clstr"], VarRC + "_" + name + "_tau3_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau2_clstr"], VarRC + "_" + name + "_tau2_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau1_clstr"], VarRC + "_" + name + "_tau1_clstr"); + + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d12_clstr"], VarRC + "_" + name + "_d12_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d23_clstr"], VarRC + "_" + name + "_d23_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_Qw_clstr"], VarRC + "_" + name + "_Qw_clstr"); + } + if (m_useVarRCAdditionalJSS) { + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF332_clstr"], VarRC + "_" + name + "_gECF332_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF461_clstr"], VarRC + "_" + name + "_gECF461_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF322_clstr"], VarRC + "_" + name + "_gECF322_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF331_clstr"], VarRC + "_" + name + "_gECF331_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF422_clstr"], VarRC + "_" + name + "_gECF422_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF441_clstr"], VarRC + "_" + name + "_gECF441_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF212_clstr"], VarRC + "_" + name + "_gECF212_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF321_clstr"], VarRC + "_" + name + "_gECF321_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF311_clstr"], VarRC + "_" + name + "_gECF311_clstr"); + + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L1_clstr"], VarRC + "_" + name + "_L1_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L2_clstr"], VarRC + "_" + name + "_L2_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L3_clstr"], VarRC + "_" + name + "_L3_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L4_clstr"], VarRC + "_" + name + "_L4_clstr"); + m_particleLevelTreeManager->makeOutputVariable(m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L5_clstr"], VarRC + "_" + name + "_L5_clstr"); + } + } // end loop over mass parameters + } // end loop over multipliers for mass scale + } // end if VarRC jets + + //met + if (m_config->useTruthMET()) { + m_particleLevelTreeManager->makeOutputVariable(m_met_met, "met_met"); + m_particleLevelTreeManager->makeOutputVariable(m_met_phi, "met_phi"); + } - m_particleLevelTreeManager->makeOutputVariable(m_el_pt_bare, "el_pt_bare"); - m_particleLevelTreeManager->makeOutputVariable(m_el_eta_bare, "el_eta_bare"); - m_particleLevelTreeManager->makeOutputVariable(m_el_phi_bare, "el_phi_bare"); - m_particleLevelTreeManager->makeOutputVariable(m_el_e_bare, "el_e_bare"); - } + // Setup PDF info branches if PDF info is requested. + if (m_config->doTruthPDFInfo()) { + m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_X1, "PDFinfo_X1"); + m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_X2, "PDFinfo_X2"); + m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_PDGID1, "PDFinfo_PDGID1"); + m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_PDGID2, "PDFinfo_PDGID2"); + m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_Q, "PDFinfo_Q"); + m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_XF1, "PDFinfo_XF1"); + m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_XF2, "PDFinfo_XF2"); + } - //muons - if ( m_config->useTruthMuons() ){ - m_particleLevelTreeManager->makeOutputVariable(m_mu_pt, "mu_pt"); - m_particleLevelTreeManager->makeOutputVariable(m_mu_eta, "mu_eta"); - m_particleLevelTreeManager->makeOutputVariable(m_mu_phi, "mu_phi"); - m_particleLevelTreeManager->makeOutputVariable(m_mu_e, "mu_e"); - m_particleLevelTreeManager->makeOutputVariable(m_mu_charge, "mu_charge"); + // Setup MC generator weights branch if requested. + if (m_config->doMCGeneratorWeights()) { + m_particleLevelTreeManager->makeOutputVariable(m_mc_generator_weights, "mc_generator_weights"); + } - m_particleLevelTreeManager->makeOutputVariable(m_mu_pt_bare, "mu_pt_bare"); - m_particleLevelTreeManager->makeOutputVariable(m_mu_eta_bare, "mu_eta_bare"); - m_particleLevelTreeManager->makeOutputVariable(m_mu_phi_bare, "mu_phi_bare"); - m_particleLevelTreeManager->makeOutputVariable(m_mu_e_bare, "mu_e_bare"); - } + // Setup PDF weight branches if PDF systematics are requested, + if (m_config->saveLHAPDFEvent()) { + for (auto& pdf : m_PDF_eventWeights) { + m_particleLevelTreeManager->makeOutputVariable(pdf.second, pdf.first); + } + } + + // Setup the selection decision branches. This is a two-step process: + // + // (1) First, we need to create an array of variables which will be used to + // store the data in the TTree. The variable + // m_particleLevel_SelectionDecisions is just that: A std::vector of + // pairs, thwere the .first corresponds to the name of the selection, + // and the .second is the actual variable. + // (2) Secondly, we need to attach the newly created variables to the + // particle level tree manager. + m_particleLevel_SelectionDecisions.reserve(m_extraBranches.size()); + for (const auto& selection : m_extraBranches) { + m_particleLevel_SelectionDecisions.push_back(std::make_pair(selection, int())); + } + + for (auto& selectionDecision : m_particleLevel_SelectionDecisions) { + m_particleLevelTreeManager->makeOutputVariable(selectionDecision.second, selectionDecision.first); + } + } + + void EventSaverFlatNtuple::setupUpgradeTreeManager(/*const top::ParticleLevelEvent& upgradeEvent*/) { + // Quick return if upgrade is disabled or the tree is already initialised. + if (not m_config->HLLHC() or m_upgradeTreeManager) { + return; + } + + m_upgradeTreeManager = std::make_shared<top::TreeManager>("upgrade", m_outputFile, m_config->outputFileNEventAutoFlush(), m_config->outputFileBasketSizePrimitive(), m_config->outputFileBasketSizeVector()); - //photons - if (m_config->useTruthPhotons()) { - m_particleLevelTreeManager->makeOutputVariable(m_ph_pt, "ph_pt"); - m_particleLevelTreeManager->makeOutputVariable(m_ph_eta, "ph_eta"); - m_particleLevelTreeManager->makeOutputVariable(m_ph_phi, "ph_phi"); - m_particleLevelTreeManager->makeOutputVariable(m_ph_e, "ph_e"); + m_upgradeTreeManager->makeOutputVariable(m_weight_mc, "weight_mc"); + + if (m_config->doMCGeneratorWeights()) { + m_upgradeTreeManager->makeOutputVariable(m_mc_generator_weights, "mc_generator_weights"); + } + + //event info + m_upgradeTreeManager->makeOutputVariable(m_eventNumber, "eventNumber"); + m_upgradeTreeManager->makeOutputVariable(m_runNumber, "runNumber"); + m_upgradeTreeManager->makeOutputVariable(m_mcChannelNumber, "mcChannelNumber"); + m_upgradeTreeManager->makeOutputVariable(m_mu, "mu"); + m_upgradeTreeManager->makeOutputVariable(m_mu_actual, "mu_actual"); + + // electrons + m_upgradeTreeManager->makeOutputVariable(m_el_pt, "el_pt"); + m_upgradeTreeManager->makeOutputVariable(m_el_eta, "el_eta"); + m_upgradeTreeManager->makeOutputVariable(m_el_phi, "el_phi"); + m_upgradeTreeManager->makeOutputVariable(m_el_e, "el_e"); + m_upgradeTreeManager->makeOutputVariable(m_el_charge, "el_charge"); + m_upgradeTreeManager->makeOutputVariable(m_el_true_type, "el_true_type"); + m_upgradeTreeManager->makeOutputVariable(m_el_true_origin, "el_true_origin"); + m_upgradeTreeManager->makeOutputVariable(m_el_etcone20, "el_etcone20"); + m_upgradeTreeManager->makeOutputVariable(m_el_ptcone30, "el_ptcone30"); + //m_upgradeTreeManager->makeOutputVariable(m_el_true_firstEgMotherTruthType, "el_true_firstEgMotherTruthType"); + //m_upgradeTreeManager->makeOutputVariable(m_el_true_firstEgMotherTruthOrigin, "el_true_firstEgMotherTruthOrigin"); + //m_upgradeTreeManager->makeOutputVariable(m_el_true_isPrompt, "el_true_isPrompt"); + if (m_config->HLLHCFakes()) m_upgradeTreeManager->makeOutputVariable(m_el_faketype, "el_faketype"); // 0 true 2 + // hfake + + //forward electrons + if (m_config->useFwdElectrons()) { + m_upgradeTreeManager->makeOutputVariable(m_fwdel_pt, "fwdel_pt"); + m_upgradeTreeManager->makeOutputVariable(m_fwdel_eta, "fwdel_eta"); + m_upgradeTreeManager->makeOutputVariable(m_fwdel_phi, "fwdel_phi"); + m_upgradeTreeManager->makeOutputVariable(m_fwdel_e, "fwdel_e"); + m_upgradeTreeManager->makeOutputVariable(m_fwdel_etcone20, "fwdel_etcone20"); + m_upgradeTreeManager->makeOutputVariable(m_fwdel_etcone30, "fwdel_etcone30"); + m_upgradeTreeManager->makeOutputVariable(m_fwdel_etcone40, "fwdel_etcone40"); + } + + // muons + m_upgradeTreeManager->makeOutputVariable(m_mu_pt, "mu_pt"); + m_upgradeTreeManager->makeOutputVariable(m_mu_eta, "mu_eta"); + m_upgradeTreeManager->makeOutputVariable(m_mu_phi, "mu_phi"); + m_upgradeTreeManager->makeOutputVariable(m_mu_e, "mu_e"); + m_upgradeTreeManager->makeOutputVariable(m_mu_charge, "mu_charge"); + m_upgradeTreeManager->makeOutputVariable(m_mu_true_type, "mu_true_type"); + m_upgradeTreeManager->makeOutputVariable(m_mu_true_origin, "mu_true_origin"); + m_upgradeTreeManager->makeOutputVariable(m_mu_etcone20, "mu_etcone20"); + m_upgradeTreeManager->makeOutputVariable(m_mu_ptcone30, "mu_ptcone30"); + m_upgradeTreeManager->makeOutputVariable(m_mu_true_isPrompt, "mu_true_isPrompt"); + m_upgradeTreeManager->makeOutputVariable(m_mu_prodVtx_z, "mu_prodVtx_z"); + m_upgradeTreeManager->makeOutputVariable(m_mu_prodVtx_perp, "mu_prodVtx_perp"); + m_upgradeTreeManager->makeOutputVariable(m_mu_prodVtx_phi, "mu_prodVtx_phi"); + + // jets + m_upgradeTreeManager->makeOutputVariable(m_jet_pt, "jet_pt"); + m_upgradeTreeManager->makeOutputVariable(m_jet_eta, "jet_eta"); + m_upgradeTreeManager->makeOutputVariable(m_jet_phi, "jet_phi"); + m_upgradeTreeManager->makeOutputVariable(m_jet_e, "jet_e"); + m_upgradeTreeManager->makeOutputVariable(m_jet_mv1eff, "jet_mv1eff"); + m_upgradeTreeManager->makeOutputVariable(m_jet_isPileup, "jet_isPileup"); + + m_upgradeTreeManager->makeOutputVariable(m_jet_Ghosts_BHadron_Final_Count, "jet_nGhosts_bHadron"); + m_upgradeTreeManager->makeOutputVariable(m_jet_Ghosts_CHadron_Final_Count, "jet_nGhosts_cHadron"); + + //large R jets + if (m_config->useTruthLargeRJets()) { + m_upgradeTreeManager->makeOutputVariable(m_ljet_pt, "ljet_pt"); + m_upgradeTreeManager->makeOutputVariable(m_ljet_eta, "ljet_eta"); + m_upgradeTreeManager->makeOutputVariable(m_ljet_phi, "ljet_phi"); + m_upgradeTreeManager->makeOutputVariable(m_ljet_e, "ljet_e"); + + m_upgradeTreeManager->makeOutputVariable(m_ljet_Ghosts_BHadron_Final_Count, "ljet_nGhosts_bHadron"); + m_upgradeTreeManager->makeOutputVariable(m_ljet_Ghosts_CHadron_Final_Count, "ljet_nGhosts_cHadron"); + } + + if (m_config->useTruthPhotons()) { + m_upgradeTreeManager->makeOutputVariable(m_ph_pt, "ph_pt"); + m_upgradeTreeManager->makeOutputVariable(m_ph_eta, "ph_eta"); + m_upgradeTreeManager->makeOutputVariable(m_ph_phi, "ph_phi"); + m_upgradeTreeManager->makeOutputVariable(m_ph_e, "ph_e"); + m_upgradeTreeManager->makeOutputVariable(m_ph_true_type, "ph_true_type"); + m_upgradeTreeManager->makeOutputVariable(m_ph_true_origin, "ph_true_origin"); + if (m_config->HLLHCFakes()) m_upgradeTreeManager->makeOutputVariable(m_ph_faketype, "ph_faketype"); // 0 + // true + // 1 + // efake + // 2 + // hfake + } + + // MET + m_upgradeTreeManager->makeOutputVariable(m_met_met, "met_met"); + m_upgradeTreeManager->makeOutputVariable(m_met_phi, "met_phi"); + + m_upgrade_SelectionDecisions.reserve(m_extraBranches.size()); + for (const auto& selection : m_extraBranches) { + m_upgrade_SelectionDecisions.push_back(std::make_pair(selection, int())); + } + + for (auto& selectionDecision : m_upgrade_SelectionDecisions) { + m_upgradeTreeManager->makeOutputVariable(selectionDecision.second, selectionDecision.first); + } + }//setupUpgradeTreeManager + + void EventSaverFlatNtuple::recordSelectionDecision(const top::Event& event) { + int index(0); + + for (const auto& branchName : m_extraBranches) { + m_selectionDecisions[index] = event.m_info->auxdataConst<int>(branchName); + ++index; + } + } + + void EventSaverFlatNtuple::recordTriggerDecision(const top::Event& event) { + for (const auto& trigger : m_triggerDecisions) + m_triggerDecisions[trigger.first] = event.m_info->auxdataConst<char>("TRIGDEC_" + trigger.first); + } + + void EventSaverFlatNtuple::saveEvent(const top::Event& event) { + // record the event? + if (m_config->saveOnlySelectedEvents() && !event.m_saveEvent) return; + + this->cleanEvent(); + this->calculateEvent(event); + this->fillEvent(event); + } + + void EventSaverFlatNtuple::cleanEvent() { + /* Doing nothing for now, but we should put here the (re-)initialisation to dummy values + * of all variables later calculated in calculateEvent(const top::Event& event) + * For example all weights set to 1, all vectors cleaned, all kinematic or angular variables set to -99999. + */ + } + + void EventSaverFlatNtuple::calculateEvent(const top::Event& event) { + //We have decorated event-info with a variable for each selection - with pass / fail + recordSelectionDecision(event); + + recordTriggerDecision(event); + + //some event weights + m_weight_mc = 0.; + if (m_config->isMC()) m_weight_mc = event.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); + + if (m_config->isMC()) { + m_weight_pileup = m_sfRetriever->pileupSF(event); + + m_weight_leptonSF = m_sfRetriever->leptonSF(event, top::topSFSyst::nominal); + if (m_config->useFwdElectrons()) m_weight_fwdElSF = m_sfRetriever->fwdElectronSF(event, top::topSFSyst::nominal); + + if (m_config->useTaus()) m_weight_tauSF = m_sfRetriever->tauSF(event, top::topSFSyst::nominal); + + if (m_config->usePhotons()) m_weight_photonSF = m_sfRetriever->photonSF(event, top::topSFSyst::nominal); + + if (m_config->useGlobalTriggerConfiguration()) m_weight_globalLeptonTriggerSF = m_sfRetriever->globalTriggerSF(event, top::topSFSyst::nominal); + m_weight_oldTriggerSF = m_sfRetriever->oldTriggerSF(event, top::topSFSyst::nominal); + + for (auto& tagWP : m_config->bTagWP_available()) { + if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; + m_weight_bTagSF[tagWP] = m_sfRetriever->btagSF(event, top::topSFSyst::nominal, tagWP); + } + if (m_config->useTrackJets()) { + for (auto& tagWP : m_config->bTagWP_available_trkJet()) { + if (std::find(m_config->bTagWP_calibrated_trkJet().begin(), m_config->bTagWP_calibrated_trkJet().end(), tagWP) == m_config->bTagWP_calibrated_trkJet().end()) continue; + m_weight_trackjet_bTagSF[tagWP] = m_sfRetriever->btagSF(event, top::topSFSyst::nominal, tagWP, true); } + } - //jets - if ( m_config->useTruthJets() ){ - m_particleLevelTreeManager->makeOutputVariable(m_jet_pt, "jet_pt"); - m_particleLevelTreeManager->makeOutputVariable(m_jet_eta, "jet_eta"); - m_particleLevelTreeManager->makeOutputVariable(m_jet_phi, "jet_phi"); - m_particleLevelTreeManager->makeOutputVariable(m_jet_e, "jet_e"); + m_weight_jvt = m_sfRetriever->jvtSF(event, top::topSFSyst::nominal); + if (m_config->getfJVTWP() != "None") m_weight_forwardjvt = m_sfRetriever->fjvtSF(event, top::topSFSyst::nominal); - m_particleLevelTreeManager->makeOutputVariable(m_jet_Ghosts_BHadron_Final_Count, "jet_nGhosts_bHadron"); - m_particleLevelTreeManager->makeOutputVariable(m_jet_Ghosts_CHadron_Final_Count, "jet_nGhosts_cHadron"); + if (m_config->isSherpa22Vjets()) { + if (event.m_info->isAvailable<double>("Sherpa22VJetsWeight")) { + m_weight_sherpa_22_vjets = event.m_info->auxdataConst<double>("Sherpa22VJetsWeight"); } + } - //large R jets - if ( m_config->useTruthLargeRJets() ){ - m_particleLevelTreeManager->makeOutputVariable(m_ljet_pt, "ljet_pt"); - m_particleLevelTreeManager->makeOutputVariable(m_ljet_eta, "ljet_eta"); - m_particleLevelTreeManager->makeOutputVariable(m_ljet_phi, "ljet_phi"); - m_particleLevelTreeManager->makeOutputVariable(m_ljet_e, "ljet_e"); + // writing the systematic-shifted SFs only in the nominal (or nominal_Loose) tree + if (event.m_hashValue == m_config->nominalHashValue()) { + if (m_config->useFwdElectrons()) { + m_weight_fwdElSF_FWDEL_SF_ID_UP = m_sfRetriever->fwdElectronSF(event, top::topSFSyst::FWDEL_SF_ID_UP); + m_weight_fwdElSF_FWDEL_SF_ID_DOWN = m_sfRetriever->fwdElectronSF(event, top::topSFSyst::FWDEL_SF_ID_DOWN); + } - m_particleLevelTreeManager->makeOutputVariable(m_ljet_Ghosts_BHadron_Final_Count, "ljet_nGhosts_bHadron"); - m_particleLevelTreeManager->makeOutputVariable(m_ljet_Ghosts_CHadron_Final_Count, "ljet_nGhosts_cHadron"); + m_weight_pileup_UP = m_sfRetriever->pileupSF(event, +1); // up variation + m_weight_pileup_DOWN = m_sfRetriever->pileupSF(event, -1); // down variation + + m_weight_leptonSF_EL_SF_Trigger_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::EL_SF_Trigger_UP); + m_weight_leptonSF_EL_SF_Trigger_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::EL_SF_Trigger_DOWN); + m_weight_leptonSF_EL_SF_Reco_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::EL_SF_Reco_UP); + m_weight_leptonSF_EL_SF_Reco_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::EL_SF_Reco_DOWN); + m_weight_leptonSF_EL_SF_ID_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::EL_SF_ID_UP); + m_weight_leptonSF_EL_SF_ID_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::EL_SF_ID_DOWN); + m_weight_leptonSF_EL_SF_Isol_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::EL_SF_Isol_UP); + m_weight_leptonSF_EL_SF_Isol_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::EL_SF_Isol_DOWN); + + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + m_weight_leptonSF_EL_SF_CorrModel_Reco_UP = m_sfRetriever->electronSFSystVariationVector(event, top::topSFComp::RECO, 1); + m_weight_leptonSF_EL_SF_CorrModel_Reco_DOWN = m_sfRetriever->electronSFSystVariationVector(event, top::topSFComp::RECO, -1); + m_weight_leptonSF_EL_SF_CorrModel_ID_UP = m_sfRetriever->electronSFSystVariationVector(event, top::topSFComp::ID, 1); + m_weight_leptonSF_EL_SF_CorrModel_ID_DOWN = m_sfRetriever->electronSFSystVariationVector(event, top::topSFComp::ID, -1); + m_weight_leptonSF_EL_SF_CorrModel_Iso_UP = m_sfRetriever->electronSFSystVariationVector(event, top::topSFComp::ISOLATION, 1); + m_weight_leptonSF_EL_SF_CorrModel_Iso_DOWN = m_sfRetriever->electronSFSystVariationVector(event, top::topSFComp::ISOLATION, -1); + } + m_weight_leptonSF_MU_SF_Trigger_STAT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_Trigger_STAT_UP); + m_weight_leptonSF_MU_SF_Trigger_STAT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_Trigger_STAT_DOWN); + m_weight_leptonSF_MU_SF_Trigger_SYST_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_Trigger_SYST_UP); + m_weight_leptonSF_MU_SF_Trigger_SYST_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_Trigger_SYST_DOWN); + // Muon ID SF systematics (regular) + m_weight_leptonSF_MU_SF_ID_STAT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_STAT_UP); + m_weight_leptonSF_MU_SF_ID_STAT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_STAT_DOWN); + m_weight_leptonSF_MU_SF_ID_SYST_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_SYST_UP); + m_weight_leptonSF_MU_SF_ID_SYST_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_SYST_DOWN); + // Muon ID SF systematics (regular) + m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_STAT_LOWPT_UP); + m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_STAT_LOWPT_DOWN); + m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_SYST_LOWPT_UP); + m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_SYST_LOWPT_DOWN); + // Muon isolation SF systematics + m_weight_leptonSF_MU_SF_Isol_STAT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_Isol_STAT_UP); + m_weight_leptonSF_MU_SF_Isol_STAT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_Isol_STAT_DOWN); + m_weight_leptonSF_MU_SF_Isol_SYST_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_Isol_SYST_UP); + m_weight_leptonSF_MU_SF_Isol_SYST_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_Isol_SYST_DOWN); + m_weight_leptonSF_MU_SF_TTVA_STAT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_TTVA_STAT_UP); + m_weight_leptonSF_MU_SF_TTVA_STAT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_TTVA_STAT_DOWN); + m_weight_leptonSF_MU_SF_TTVA_SYST_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_TTVA_SYST_UP); + m_weight_leptonSF_MU_SF_TTVA_SYST_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_TTVA_SYST_DOWN); + // Special global lepton trigger SF systematics if requested + if (m_config->useGlobalTriggerConfiguration()) { + m_weight_globalLeptonTriggerSF_EL_Trigger_UP = m_sfRetriever->globalTriggerSF(event, top::topSFSyst::EL_SF_Trigger_UP); + m_weight_globalLeptonTriggerSF_EL_Trigger_DOWN = m_sfRetriever->globalTriggerSF(event, top::topSFSyst::EL_SF_Trigger_DOWN); + m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_UP = m_sfRetriever->globalTriggerSF(event, top::topSFSyst::MU_SF_Trigger_STAT_UP); + m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_DOWN = m_sfRetriever->globalTriggerSF(event, top::topSFSyst::MU_SF_Trigger_STAT_DOWN); + m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_UP = m_sfRetriever->globalTriggerSF(event, top::topSFSyst::MU_SF_Trigger_SYST_UP); + m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_DOWN = m_sfRetriever->globalTriggerSF(event, top::topSFSyst::MU_SF_Trigger_SYST_DOWN); } + m_weight_oldTriggerSF_EL_Trigger_UP = m_sfRetriever->oldTriggerSF(event, top::topSFSyst::EL_SF_Trigger_UP); + m_weight_oldTriggerSF_EL_Trigger_DOWN = m_sfRetriever->oldTriggerSF(event, top::topSFSyst::EL_SF_Trigger_DOWN); + m_weight_oldTriggerSF_MU_Trigger_STAT_UP = m_sfRetriever->oldTriggerSF(event, top::topSFSyst::MU_SF_Trigger_STAT_UP); + m_weight_oldTriggerSF_MU_Trigger_STAT_DOWN = m_sfRetriever->oldTriggerSF(event, top::topSFSyst::MU_SF_Trigger_STAT_DOWN); + m_weight_oldTriggerSF_MU_Trigger_SYST_UP = m_sfRetriever->oldTriggerSF(event, top::topSFSyst::MU_SF_Trigger_SYST_UP); + m_weight_oldTriggerSF_MU_Trigger_SYST_DOWN = m_sfRetriever->oldTriggerSF(event, top::topSFSyst::MU_SF_Trigger_SYST_DOWN); + + m_weight_indiv_SF_EL_Reco = m_sfRetriever->electronSF(event, top::topSFSyst::nominal, top::topSFComp::RECO); + m_weight_indiv_SF_EL_Reco_UP = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_Reco_UP, top::topSFComp::RECO); + m_weight_indiv_SF_EL_Reco_DOWN = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_Reco_DOWN, top::topSFComp::RECO); + m_weight_indiv_SF_EL_ID = m_sfRetriever->electronSF(event, top::topSFSyst::nominal, top::topSFComp::ID); + m_weight_indiv_SF_EL_ID_UP = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_ID_UP, top::topSFComp::ID); + m_weight_indiv_SF_EL_ID_DOWN = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_ID_DOWN, top::topSFComp::ID); + m_weight_indiv_SF_EL_Isol = m_sfRetriever->electronSF(event, top::topSFSyst::nominal, top::topSFComp::ISOLATION); + m_weight_indiv_SF_EL_Isol_UP = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_Isol_UP, top::topSFComp::ISOLATION); + m_weight_indiv_SF_EL_Isol_DOWN = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_Isol_DOWN, top::topSFComp::ISOLATION); + m_weight_indiv_SF_EL_ChargeID = m_sfRetriever->electronSF(event, top::topSFSyst::nominal, top::topSFComp::CHARGEID); + m_weight_indiv_SF_EL_ChargeID_UP = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_ChargeID_UP, top::topSFComp::CHARGEID); + m_weight_indiv_SF_EL_ChargeID_DOWN = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_ChargeID_DOWN, top::topSFComp::CHARGEID); + m_weight_indiv_SF_EL_ChargeMisID = m_sfRetriever->electronSF(event, top::topSFSyst::nominal, top::topSFComp::CHARGEMISID); + m_weight_indiv_SF_EL_ChargeMisID_STAT_UP = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_ChargeMisID_STAT_UP, top::topSFComp::CHARGEMISID); + m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_ChargeMisID_STAT_DOWN, top::topSFComp::CHARGEMISID); + m_weight_indiv_SF_EL_ChargeMisID_SYST_UP = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_ChargeMisID_SYST_UP, top::topSFComp::CHARGEMISID); + m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN = m_sfRetriever->electronSF(event, top::topSFSyst::EL_SF_ChargeMisID_SYST_DOWN, top::topSFComp::CHARGEMISID); + ATH_MSG_DEBUG("Electron Reco SF = " << m_weight_indiv_SF_EL_Reco << " + " << m_weight_indiv_SF_EL_Reco_UP << " - " << m_weight_indiv_SF_EL_Reco_DOWN); + ATH_MSG_DEBUG("Electron ID SF = " << m_weight_indiv_SF_EL_ID << " + " << m_weight_indiv_SF_EL_ID_UP << " - " << m_weight_indiv_SF_EL_ID_DOWN); + ATH_MSG_DEBUG("Electron Charge ID SF = " << m_weight_indiv_SF_EL_ChargeID << " + " << m_weight_indiv_SF_EL_ChargeID_UP << " - " << m_weight_indiv_SF_EL_ChargeID_DOWN); + ATH_MSG_DEBUG("Electron Charge Mis ID SF = " << m_weight_indiv_SF_EL_ChargeMisID << " + " << m_weight_indiv_SF_EL_ChargeMisID_STAT_UP << " - " << m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN << " + " << m_weight_indiv_SF_EL_ChargeMisID_SYST_UP << " - " << m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN); + + m_weight_indiv_SF_MU_ID = m_sfRetriever->muonSF(event, top::topSFSyst::nominal, top::topSFComp::ID); + // Muon ID SF systematics (regular) + m_weight_indiv_SF_MU_ID_STAT_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_STAT_UP, top::topSFComp::ID); + m_weight_indiv_SF_MU_ID_STAT_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_STAT_DOWN, top::topSFComp::ID); + m_weight_indiv_SF_MU_ID_SYST_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_SYST_UP, top::topSFComp::ID); + m_weight_indiv_SF_MU_ID_SYST_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_SYST_DOWN, top::topSFComp::ID); + // Muon ID SF systematics (low pt) + m_weight_indiv_SF_MU_ID_STAT_LOWPT_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_STAT_LOWPT_UP, top::topSFComp::ID); + m_weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_STAT_LOWPT_DOWN, top::topSFComp::ID); + m_weight_indiv_SF_MU_ID_SYST_LOWPT_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_SYST_LOWPT_UP, top::topSFComp::ID); + m_weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_SYST_LOWPT_DOWN, top::topSFComp::ID); + // Muon isolation SF systematics + m_weight_indiv_SF_MU_Isol = m_sfRetriever->muonSF(event, top::topSFSyst::nominal, top::topSFComp::ISOLATION); + m_weight_indiv_SF_MU_Isol_STAT_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_Isol_STAT_UP, top::topSFComp::ISOLATION); + m_weight_indiv_SF_MU_Isol_STAT_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_Isol_STAT_DOWN, top::topSFComp::ISOLATION); + m_weight_indiv_SF_MU_Isol_SYST_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_Isol_SYST_UP, top::topSFComp::ISOLATION); + m_weight_indiv_SF_MU_Isol_SYST_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_Isol_SYST_DOWN, top::topSFComp::ISOLATION); + m_weight_indiv_SF_MU_TTVA = m_sfRetriever->muonSF(event, top::topSFSyst::nominal, top::topSFComp::TTVA); + m_weight_indiv_SF_MU_TTVA_STAT_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_TTVA_STAT_UP, top::topSFComp::TTVA); + m_weight_indiv_SF_MU_TTVA_STAT_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_TTVA_STAT_DOWN, top::topSFComp::TTVA); + m_weight_indiv_SF_MU_TTVA_SYST_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_TTVA_SYST_UP, top::topSFComp::TTVA); + m_weight_indiv_SF_MU_TTVA_SYST_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_TTVA_SYST_DOWN, top::topSFComp::TTVA); + - //met - if ( m_config->useTruthMET() ){ - m_particleLevelTreeManager->makeOutputVariable(m_met_met, "met_met"); - m_particleLevelTreeManager->makeOutputVariable(m_met_phi, "met_phi"); + ATH_MSG_DEBUG("Muon ID SF = " << m_weight_indiv_SF_MU_ID << " + " << m_weight_indiv_SF_MU_ID_STAT_UP << " - " << m_weight_indiv_SF_MU_ID_STAT_DOWN << " + " << m_weight_indiv_SF_MU_ID_SYST_UP << " - " << m_weight_indiv_SF_MU_ID_SYST_DOWN); + + if (m_config->useTaus()) { + // Tau-electron overlap removal + for (auto& tauSFvariation: m_weight_tauSF_variations) { + tauSFvariation.second = m_sfRetriever->tauSF(event, tauSFvariation.first); + } } - // Setup PDF info branches if PDF info is requested. - if (m_config->doTruthPDFInfo()) { - m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_X1, "PDFinfo_X1"); - m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_X2, "PDFinfo_X2"); - m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_PDGID1, "PDFinfo_PDGID1"); - m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_PDGID2, "PDFinfo_PDGID2"); - m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_Q, "PDFinfo_Q"); - m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_XF1, "PDFinfo_XF1"); - m_particleLevelTreeManager->makeOutputVariable(m_PDFinfo_XF2, "PDFinfo_XF2"); + if (m_config->usePhotons()) { + m_weight_photonSF_ID_UP = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_IDSF_UP); + m_weight_photonSF_ID_DOWN = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_IDSF_DOWN); + m_weight_photonSF_effIso_UP = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_EFF_ISO_UP); + m_weight_photonSF_effIso_DOWN = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_EFF_ISO_DOWN); } - // Setup MC generator weights branch if requested. - if (m_config->doMCGeneratorWeights()) { - m_particleLevelTreeManager->makeOutputVariable(m_mc_generator_weights, "mc_generator_weights"); + + m_weight_jvt_up = m_sfRetriever->jvtSF(event, top::topSFSyst::JVT_UP); + m_weight_jvt_down = m_sfRetriever->jvtSF(event, top::topSFSyst::JVT_DOWN); + if (m_config->getfJVTWP() != "None"){ + m_weight_forwardjvt_up = m_sfRetriever->fjvtSF(event, top::topSFSyst::FJVT_UP); + m_weight_forwardjvt_down = m_sfRetriever->fjvtSF(event, top::topSFSyst::FJVT_DOWN); } + } - // Setup PDF weight branches if PDF systematics are requested, - if( m_config->saveLHAPDFEvent() ){ - for ( auto & pdf : m_PDF_eventWeights ) { - m_particleLevelTreeManager->makeOutputVariable( pdf.second, pdf.first ); + // for b-tagging SFs, can also have systematic-shifted in systematics trees + if (event.m_hashValue == m_config->nominalHashValue() || m_config->dumpBtagSystsInSystTrees()) { + for (auto& tagWP : m_config->bTagWP_available()) { + // skip uncalibrated though available WPs + if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; + m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_B, + m_weight_bTagSF_eigen_B_up[tagWP], + m_weight_bTagSF_eigen_B_down[tagWP], tagWP); + m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_C, + m_weight_bTagSF_eigen_C_up[tagWP], + m_weight_bTagSF_eigen_C_down[tagWP], tagWP); + m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_LIGHT, + m_weight_bTagSF_eigen_Light_up[tagWP], + m_weight_bTagSF_eigen_Light_down[tagWP], tagWP); + for (auto name : m_config->btagging_namedSysts(tagWP)) { + m_weight_bTagSF_named_up[tagWP][name] = m_sfRetriever->btagSF(event, top::topSFSyst::BTAG_SF_NAMED_UP, tagWP, false, name); + m_weight_bTagSF_named_down[tagWP][name] = m_sfRetriever->btagSF(event, top::topSFSyst::BTAG_SF_NAMED_DOWN, tagWP, false, name); + } + } + if (m_config->useTrackJets()) { + for (auto& tagWP : m_config->bTagWP_available_trkJet()) { + // skip uncalibrated though available WPs + if (std::find(m_config->bTagWP_calibrated_trkJet().begin(), m_config->bTagWP_calibrated_trkJet().end(), tagWP) == m_config->bTagWP_calibrated_trkJet().end()) continue; + m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_B, + m_weight_trackjet_bTagSF_eigen_B_up[tagWP], + m_weight_trackjet_bTagSF_eigen_B_down[tagWP], tagWP, true); + m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_C, + m_weight_trackjet_bTagSF_eigen_C_up[tagWP], + m_weight_trackjet_bTagSF_eigen_C_down[tagWP], tagWP, true); + m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_LIGHT, + m_weight_trackjet_bTagSF_eigen_Light_up[tagWP], + m_weight_trackjet_bTagSF_eigen_Light_down[tagWP], tagWP, true); + for (auto name : m_config->trkjet_btagging_namedSysts(tagWP)) { + m_weight_trackjet_bTagSF_named_up[tagWP][name] = m_sfRetriever->btagSF(event, top::topSFSyst::BTAG_SF_NAMED_UP, tagWP, true, name); + m_weight_trackjet_bTagSF_named_down[tagWP][name] = m_sfRetriever->btagSF(event, top::topSFSyst::BTAG_SF_NAMED_DOWN, tagWP, true, name); } + } } + } + } - // Setup the selection decision branches. This is a two-step process: - // - // (1) First, we need to create an array of variables which will be used to - // store the data in the TTree. The variable - // m_particleLevel_SelectionDecisions is just that: A std::vector of - // pairs, thwere the .first corresponds to the name of the selection, - // and the .second is the actual variable. - // (2) Secondly, we need to attach the newly created variables to the - // particle level tree manager. - m_particleLevel_SelectionDecisions.reserve( plEvent.m_selectionDecisions.size() ); - for ( const auto & selectionDecision : plEvent.m_selectionDecisions ){ - m_particleLevel_SelectionDecisions.push_back( std::make_pair( selectionDecision.first, - selectionDecision.second ) ); - } + /// Bootstrapping poisson weights - Moved to run for MC and data + if (m_config->saveBootstrapWeights()) { + m_weight_poisson = event.m_info->auxdataConst<std::vector<int> >("weight_poisson"); + } - for ( auto & selectionDecision : m_particleLevel_SelectionDecisions ){ - m_particleLevelTreeManager->makeOutputVariable( selectionDecision.second, selectionDecision.first ); - } + ///-- weights for matrix-method fakes estimate by IFF --/// + if (event.m_hashValue == m_config->nominalHashValue() && !m_config->isMC() && m_config->doFakesMMWeightsIFF()) { + //std::vector<CP::AsymptMatrixTool*> fakesMMWeightCalcIFF; + //for (int mmi = 0; mmi < m_ASMsize; ++mmi) { + // fakesMMWeightCalcIFF.push_back(asg::ToolStore::get<CP::AsymptMatrixTool>("AsymptMatrixTool_" + std::to_string (mmi))); + //} + //std::string ASMweights_branch_name = "ASMWeight"; + //std::string decorName = "ASMWeight"; + //if (event.m_info->isAvailable<std::vector<float> >(decorName.c_str())) { + // m_ASMweights = event.m_info->auxdataConst<std::vector<float> >(decorName.c_str()); + // if (event.m_info->isAvailable<std::vector<std::vector<float> > >((decorName + "_Syst").c_str())) { + // m_ASMweights_Syst = event.m_info->auxdataConst<std::vector<std::vector<float> > >((decorName + "_Syst").c_str()); + // m_ASMweights_Systname = event.m_info->auxdataConst<std::vector<std::vector<std::string> > >((decorName + "_Systname").c_str()); + // } + //} } - void EventSaverFlatNtuple::setupUpgradeTreeManager(/*const top::ParticleLevelEvent& upgradeEvent*/){ - // Quick return if upgrade is disabled or the tree is already initialised. - if ( not m_config->HLLHC() or m_upgradeTreeManager ){ - return; - } + //event info + m_eventNumber = event.m_info->eventNumber(); + m_runNumber = event.m_info->runNumber(); + m_randomRunNumber = 0; + if (m_config->isMC() && m_config->doPileupReweighting()) { + if (event.m_info->isAvailable<unsigned int>("RandomRunNumber")) m_randomRunNumber = event.m_info->auxdataConst<unsigned int>("RandomRunNumber"); + } + m_mcChannelNumber = 0; - m_upgradeTreeManager = std::make_shared<top::TreeManager>( "upgrade", m_outputFile, m_config->outputFileSetAutoFlushZero() ); + if (m_config->isMC()) m_mcChannelNumber = event.m_info->mcChannelNumber(); - m_upgradeTreeManager->makeOutputVariable(m_weight_mc, "weight_mc"); + // (non-collision-)background flags + m_backgroundFlags = 0; + if (event.m_info->isAvailable<unsigned int>("backgroundFlags")) m_backgroundFlags = event.m_info->auxdataConst<unsigned int>("backgroundFlags"); - //event info - m_upgradeTreeManager->makeOutputVariable(m_eventNumber, "eventNumber"); - m_upgradeTreeManager->makeOutputVariable(m_runNumber, "runNumber"); - m_upgradeTreeManager->makeOutputVariable(m_mcChannelNumber, "mcChannelNumber"); - m_upgradeTreeManager->makeOutputVariable(m_mu, "mu"); + // hasBadMuon flag + m_hasBadMuon = 0; + if (m_config->useMuons() && event.m_info->isAvailable<char>("AnalysisTop_HASBADMUON")) m_hasBadMuon = event.m_info->auxdataConst<char>("AnalysisTop_HASBADMUON"); - // electrons - m_upgradeTreeManager->makeOutputVariable(m_el_pt, "el_pt"); - m_upgradeTreeManager->makeOutputVariable(m_el_eta, "el_eta"); - m_upgradeTreeManager->makeOutputVariable(m_el_phi, "el_phi"); - m_upgradeTreeManager->makeOutputVariable(m_el_e, "el_e"); - m_upgradeTreeManager->makeOutputVariable(m_el_charge, "el_charge"); + // mu values (original and corrected by pileup reweighting tool) + m_mu_original = event.m_info->averageInteractionsPerCrossing(); + m_mu_actual_original = event.m_info->actualInteractionsPerCrossing(); - // muons - m_upgradeTreeManager->makeOutputVariable(m_mu_pt, "mu_pt"); - m_upgradeTreeManager->makeOutputVariable(m_mu_eta, "mu_eta"); - m_upgradeTreeManager->makeOutputVariable(m_mu_phi, "mu_phi"); - m_upgradeTreeManager->makeOutputVariable(m_mu_e, "mu_e"); - m_upgradeTreeManager->makeOutputVariable(m_mu_charge, "mu_charge"); + // set these all to zero (maybe not the most sensible value...) + m_mu = 0; + m_mu_actual = 0; + + if (m_config->isMC()) { + m_mu = m_mu_original; + m_mu_actual = m_mu_actual_original; + } + if (!m_config->isMC()) { + // If we have the corrected mu value from pileup reweighting then save that + // instead of mu value in (d)xAOD. + if (event.m_info->isAvailable<float>("corrected_averageInteractionsPerCrossing")) m_mu = event.m_info->auxdataConst<float>("corrected_averageInteractionsPerCrossing"); + if (event.m_info->isAvailable<float>("corrected_actualInteractionsPerCrossing")) m_mu_actual = event.m_info->auxdataConst<float>("corrected_actualInteractionsPerCrossing"); + } - // jets - m_upgradeTreeManager->makeOutputVariable(m_jet_pt, "jet_pt"); - m_upgradeTreeManager->makeOutputVariable(m_jet_eta, "jet_eta"); - m_upgradeTreeManager->makeOutputVariable(m_jet_phi, "jet_phi"); - m_upgradeTreeManager->makeOutputVariable(m_jet_e, "jet_e"); - m_upgradeTreeManager->makeOutputVariable(m_jet_mv1eff, "jet_mv1eff"); - m_upgradeTreeManager->makeOutputVariable(m_jet_isPileup, "jet_isPileup"); + ATH_MSG_DEBUG(" mu = " << m_mu_original << " -> " << m_mu); + + //forward electrons + if (m_config->useFwdElectrons()) { + unsigned int i(0); + unsigned int n_electrons = event.m_fwdElectrons.size(); + m_fwdel_pt.resize(n_electrons); + m_fwdel_eta.resize(n_electrons); + m_fwdel_phi.resize(n_electrons); + m_fwdel_e.resize(n_electrons); + m_fwdel_etcone20.resize(n_electrons); + m_fwdel_etcone30.resize(n_electrons); + m_fwdel_etcone40.resize(n_electrons); + m_fwdel_isTight.resize(n_electrons); + + for (const auto* const elPtr : event.m_fwdElectrons) { + m_fwdel_pt[i] = elPtr->pt(); + m_fwdel_eta[i] = elPtr->eta(); + m_fwdel_phi[i] = elPtr->phi(); + m_fwdel_e[i] = elPtr->e(); + + float etcone20 = 0.0; + elPtr->isolationValue(etcone20, xAOD::Iso::topoetcone20); + float etcone30 = 0.0; + elPtr->isolationValue(etcone30, xAOD::Iso::topoetcone30); + float etcone40 = 0.0; + elPtr->isolationValue(etcone40, xAOD::Iso::topoetcone40); + + m_fwdel_etcone20[i] = etcone20; + m_fwdel_etcone30[i] = etcone30; + m_fwdel_etcone40[i] = etcone40; + + if (event.m_isLoose) { + if (elPtr->isAvailable<char>("passPreORSelection")) { + m_fwdel_isTight[i] = elPtr->auxdataConst<char>("passPreORSelection"); + } + } - m_upgradeTreeManager->makeOutputVariable(m_jet_Ghosts_BHadron_Final_Count, "jet_nGhosts_bHadron"); - m_upgradeTreeManager->makeOutputVariable(m_jet_Ghosts_CHadron_Final_Count, "jet_nGhosts_cHadron"); - - // MET - m_upgradeTreeManager->makeOutputVariable(m_met_met, "met_met"); - m_upgradeTreeManager->makeOutputVariable(m_met_phi, "met_phi"); - }//setupUpgradeTreeManager + ++i; + }//end of loop on fwd electrons + }//end of fwd electrons filling + + //electrons + if (m_config->useElectrons()) { + unsigned int i(0); + unsigned int n_electrons = event.m_electrons.size(); + m_el_pt.resize(n_electrons); + m_el_eta.resize(n_electrons); + m_el_cl_eta.resize(n_electrons); + m_el_phi.resize(n_electrons); + m_el_e.resize(n_electrons); + m_el_charge.resize(n_electrons); + m_el_topoetcone20.resize(n_electrons); + m_el_ptvarcone20.resize(n_electrons); + m_el_isTight.resize(n_electrons); + m_el_CF.resize(n_electrons); + for (const auto& trigger : m_el_trigMatched) + m_el_trigMatched[trigger.first].resize(n_electrons); + m_el_d0sig.resize(n_electrons); + m_el_delta_z0_sintheta.resize(n_electrons); + if (m_useElectronChargeIDSelection) { + m_el_ECIDS.resize(n_electrons); + m_el_ECIDSResult.resize(n_electrons); + } + if (m_config->isMC()) { + m_el_true_type.resize(n_electrons); + m_el_true_origin.resize(n_electrons); + m_el_true_firstEgMotherTruthOrigin.resize(n_electrons); + m_el_true_firstEgMotherTruthType.resize(n_electrons); + m_el_true_firstEgMotherPdgId.resize(n_electrons); + m_el_true_isPrompt.resize(n_electrons); + m_el_true_isChargeFl.resize(n_electrons); + } + if (m_config->enablePromptLeptonImprovedVetoStudies()) { + m_PLIV_el_PromptLeptonRNN_conversion.resize(n_electrons); + m_PLIV_el_PromptLeptonRNN_non_prompt_b.resize(n_electrons); + m_PLIV_el_PromptLeptonRNN_non_prompt_c.resize(n_electrons); + m_PLIV_el_PromptLeptonRNN_prompt.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_MVAXBin.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_TrackJetNTrack.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_topoetcone30rel.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_ptvarcone30rel.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_PtFrac.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_DRlj.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_CaloClusterSumEtRel.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_PtRel.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedVetoBARR.resize(n_electrons); + m_PLIV_el_PromptLeptonImprovedVetoECAP.resize(n_electrons); + } - void EventSaverFlatNtuple::recordSelectionDecision(const top::Event& event) { - int index(0); - for (const auto& branchName : m_extraBranches) { - m_selectionDecisions[index] = event.m_info->auxdataConst<int>(branchName); - ++index; + static const SG::AuxElement::Accessor<char> accECIDS("DFCommonElectronsECIDS"); + static const SG::AuxElement::Accessor<double> accECIDSResult("DFCommonElectronsECIDSResult"); + + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonRNN_conversion("PromptLeptonRNN_conversion"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonRNN_non_prompt_b("PromptLeptonRNN_non_prompt_b"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonRNN_non_prompt_c("PromptLeptonRNN_non_prompt_c"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonRNN_prompt("PromptLeptonRNN_prompt"); + static const SG::AuxElement::Accessor<short> PLIV_el_PromptLeptonImprovedInput_MVAXBin("PromptLeptonImprovedInput_MVAXBin"); + static const SG::AuxElement::Accessor<short> PLIV_el_PromptLeptonImprovedInput_TrackJetNTrack("PromptLeptonImprovedInput_TrackJetNTrack"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedInput_topoetcone30rel("PromptLeptonImprovedInput_topoetcone30rel"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedInput_ptvarcone30rel("PromptLeptonImprovedInput_ptvarcone30rel"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedInput_PtFrac("PromptLeptonImprovedInput_PtFrac"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedInput_DRlj("PromptLeptonImprovedInput_DRlj"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedInput_CaloClusterSumEtRel("PromptLeptonImprovedInput_CaloClusterSumEtRel"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedInput_PtRel("PromptLeptonImprovedInput_PtRel"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx("PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedVetoBARR("PromptLeptonImprovedVetoBARR"); + static const SG::AuxElement::Accessor<float> PLIV_el_PromptLeptonImprovedVetoECAP("PromptLeptonImprovedVetoECAP"); + + for (const auto* const elPtr : event.m_electrons) { + m_el_pt[i] = elPtr->pt(); + m_el_eta[i] = elPtr->eta(); + m_el_cl_eta[i] = elPtr->caloCluster()->etaBE(2); + m_el_phi[i] = elPtr->phi(); + m_el_e[i] = elPtr->e(); + m_el_charge[i] = elPtr->charge(); + elPtr->isolationValue(m_el_topoetcone20[i], xAOD::Iso::topoetcone20); + elPtr->isolationValue(m_el_ptvarcone20[i], xAOD::Iso::ptvarcone20); + if (event.m_isLoose) { + if (elPtr->isAvailable<char>("passPreORSelection")) { + m_el_isTight[i] = elPtr->auxdataConst<char>("passPreORSelection"); + } + } + if (elPtr->isAvailable<char>("passChargeID")) m_el_CF[i] = elPtr->auxdataConst<char>("passChargeID"); + for (const auto& trigger : m_el_trigMatched) { + std::string trig = "TRIGMATCH_" + trigger.first; + m_el_trigMatched[trigger.first][i] = elPtr->auxdataConst<char>(trig); } + if (elPtr->isAvailable<float>("d0sig")) m_el_d0sig[i] = elPtr->auxdataConst<float>("d0sig"); + if (elPtr->isAvailable<float>("delta_z0_sintheta")) m_el_delta_z0_sintheta[i] = elPtr->auxdataConst<float>("delta_z0_sintheta"); + + if (m_useElectronChargeIDSelection) { + m_el_ECIDS[i] = accECIDS.isAvailable(*elPtr) ? accECIDS(*elPtr) : 'n'; + m_el_ECIDSResult[i] = accECIDSResult.isAvailable(*elPtr) ? accECIDSResult(*elPtr) : -999.; + } + + if (m_config->enablePromptLeptonImprovedVetoStudies()) { + m_PLIV_el_PromptLeptonRNN_conversion[i] = PLIV_el_PromptLeptonRNN_conversion.isAvailable(*elPtr) ? PLIV_el_PromptLeptonRNN_conversion(*elPtr) : -999.; + m_PLIV_el_PromptLeptonRNN_non_prompt_b[i] = PLIV_el_PromptLeptonRNN_non_prompt_b.isAvailable(*elPtr) ? PLIV_el_PromptLeptonRNN_non_prompt_b(*elPtr) : -999.; + m_PLIV_el_PromptLeptonRNN_non_prompt_c[i] = PLIV_el_PromptLeptonRNN_non_prompt_c.isAvailable(*elPtr) ? PLIV_el_PromptLeptonRNN_non_prompt_c(*elPtr) : -999.; + m_PLIV_el_PromptLeptonRNN_prompt[i] = PLIV_el_PromptLeptonRNN_prompt.isAvailable(*elPtr) ? PLIV_el_PromptLeptonRNN_prompt(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_MVAXBin[i] = PLIV_el_PromptLeptonImprovedInput_MVAXBin.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_MVAXBin(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_TrackJetNTrack[i] = PLIV_el_PromptLeptonImprovedInput_TrackJetNTrack.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_TrackJetNTrack(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_topoetcone30rel[i] = PLIV_el_PromptLeptonImprovedInput_topoetcone30rel.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_topoetcone30rel(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_ptvarcone30rel[i] = PLIV_el_PromptLeptonImprovedInput_ptvarcone30rel.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_ptvarcone30rel(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_PtFrac[i] = PLIV_el_PromptLeptonImprovedInput_PtFrac.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_PtFrac(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_DRlj[i] = PLIV_el_PromptLeptonImprovedInput_DRlj.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_DRlj(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_CaloClusterSumEtRel[i] = PLIV_el_PromptLeptonImprovedInput_CaloClusterSumEtRel.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_CaloClusterSumEtRel(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_PtRel[i] = PLIV_el_PromptLeptonImprovedInput_PtRel.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_PtRel(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx[i] = PLIV_el_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedVetoBARR[i] = PLIV_el_PromptLeptonImprovedVetoBARR.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedVetoBARR(*elPtr) : -999.; + m_PLIV_el_PromptLeptonImprovedVetoECAP[i] = PLIV_el_PromptLeptonImprovedVetoECAP.isAvailable(*elPtr) ? PLIV_el_PromptLeptonImprovedVetoECAP(*elPtr) : -999.; + } + + //retrieve the truth-matching variables from MCTruthClassifier + if (m_config->isMC()) { + m_el_true_type[i] = 0; + m_el_true_origin[i] = 0; + m_el_true_firstEgMotherTruthType[i] = 0; + m_el_true_firstEgMotherTruthOrigin[i] = 0; + m_el_true_firstEgMotherPdgId[i] = 0; + static const SG::AuxElement::Accessor<int> typeel("truthType"); + static const SG::AuxElement::Accessor<int> origel("truthOrigin"); + static const SG::AuxElement::Accessor<int> firstEgMotherTruthType("firstEgMotherTruthType"); + static const SG::AuxElement::Accessor<int> firstEgMotherTruthOrigin("firstEgMotherTruthOrigin"); + static const SG::AuxElement::Accessor<int> firstEgMotherPdgId("firstEgMotherPdgId"); + + if (typeel.isAvailable(*elPtr)) m_el_true_type[i] = typeel(*elPtr); + if (origel.isAvailable(*elPtr)) m_el_true_origin[i] = origel(*elPtr); + if (firstEgMotherTruthType.isAvailable(*elPtr)) m_el_true_firstEgMotherTruthType[i] = firstEgMotherTruthType(*elPtr); + if (firstEgMotherTruthOrigin.isAvailable(*elPtr)) m_el_true_firstEgMotherTruthOrigin[i] = firstEgMotherTruthOrigin(*elPtr); + if (firstEgMotherPdgId.isAvailable(*elPtr)) m_el_true_firstEgMotherPdgId[i] = firstEgMotherPdgId(*elPtr); + + std::pair<bool, bool> isPrompt_isChargeFl = isPromptElectron(m_el_true_type[i], m_el_true_origin[i], m_el_true_firstEgMotherTruthType[i], m_el_true_firstEgMotherTruthOrigin[i], m_el_true_firstEgMotherPdgId[i], m_el_charge[i]); + m_el_true_isPrompt[i] = isPrompt_isChargeFl.first; + m_el_true_isChargeFl[i] = isPrompt_isChargeFl.second; + } + ++i; + } } - void EventSaverFlatNtuple::recordTriggerDecision(const top::Event& event) { + //muons + if (m_config->useMuons()) { + unsigned int i(0); + unsigned int n_muons = event.m_muons.size(); + m_mu_pt.resize(n_muons); + m_mu_eta.resize(n_muons); + m_mu_phi.resize(n_muons); + m_mu_e.resize(n_muons); + m_mu_charge.resize(n_muons); + m_mu_topoetcone20.resize(n_muons); + m_mu_ptvarcone30.resize(n_muons); + m_mu_isTight.resize(n_muons); + for (const auto& trigger : m_mu_trigMatched) + m_mu_trigMatched[trigger.first].resize(n_muons); + m_mu_d0sig.resize(n_muons); + m_mu_delta_z0_sintheta.resize(n_muons); + if (m_config->isMC()) { + m_mu_true_type.resize(n_muons); + m_mu_true_origin.resize(n_muons); + m_mu_true_isPrompt.resize(n_muons); + } + if (m_config->enablePromptLeptonImprovedVetoStudies()) { + m_PLIV_mu_PromptLeptonRNN_non_prompt_b.resize(n_muons); + m_PLIV_mu_PromptLeptonRNN_non_prompt_c.resize(n_muons); + m_PLIV_mu_PromptLeptonRNN_prompt.resize(n_muons); + m_PLIV_mu_PromptLeptonImprovedInput_MVAXBin.resize(n_muons); + m_PLIV_mu_PromptLeptonImprovedInput_topoetcone30rel.resize(n_muons); + m_PLIV_mu_PromptLeptonImprovedInput_PtFrac.resize(n_muons); + m_PLIV_mu_PromptLeptonImprovedInput_DRlj.resize(n_muons); + m_PLIV_mu_PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel.resize(n_muons); + m_PLIV_mu_PromptLeptonImprovedInput_CaloClusterERel.resize(n_muons); + m_PLIV_mu_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest.resize(n_muons); + m_PLIV_mu_PromptLeptonImprovedVeto.resize(n_muons); + } - for (const auto& trigger : m_triggerDecisions) - m_triggerDecisions[trigger.first] = event.m_info->auxdataConst<char>("TRIGDEC_"+trigger.first); - if (!m_config->isMC() && m_config->doFakesMMWeights()) { - for (const auto& trigger : m_triggerPrescales) - m_triggerPrescales[trigger.first] = event.m_info->auxdataConst<float>("TRIGPS_"+trigger.first); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonRNN_non_prompt_b("PromptLeptonRNN_non_prompt_b"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonRNN_non_prompt_c("PromptLeptonRNN_non_prompt_c"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonRNN_prompt("PromptLeptonRNN_prompt"); + static const SG::AuxElement::Accessor<short> PLIV_mu_PromptLeptonImprovedInput_MVAXBin("PromptLeptonImprovedInput_MVAXBin"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonImprovedInput_topoetcone30rel("PromptLeptonImprovedInput_topoetcone30rel"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonImprovedInput_PtFrac("PromptLeptonImprovedInput_PtFrac"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonImprovedInput_DRlj("PromptLeptonImprovedInput_DRlj"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel("PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonImprovedInput_CaloClusterERel("PromptLeptonImprovedInput_CaloClusterERel"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest("PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest"); + static const SG::AuxElement::Accessor<float> PLIV_mu_PromptLeptonImprovedVeto("PromptLeptonImprovedVeto"); + + for (const auto* const muPtr : event.m_muons) { + m_mu_pt[i] = muPtr->pt(); + m_mu_eta[i] = muPtr->eta(); + m_mu_phi[i] = muPtr->phi(); + m_mu_e[i] = muPtr->e(); + m_mu_charge[i] = muPtr->charge(); + muPtr->isolation(m_mu_topoetcone20[i], xAOD::Iso::topoetcone20); + muPtr->isolation(m_mu_ptvarcone30[i], xAOD::Iso::ptvarcone30); + if (event.m_isLoose) { + if (muPtr->isAvailable<char>("passPreORSelection")) { + m_mu_isTight[i] = muPtr->auxdataConst<char>("passPreORSelection"); + } + } + for (const auto& trigger : m_mu_trigMatched) { + std::string trig = "TRIGMATCH_" + trigger.first; + m_mu_trigMatched[trigger.first][i] = muPtr->auxdataConst<char>(trig); } + if (muPtr->isAvailable<float>("d0sig")) m_mu_d0sig[i] = muPtr->auxdataConst<float>("d0sig"); + if (muPtr->isAvailable<float>("delta_z0_sintheta")) m_mu_delta_z0_sintheta[i] = muPtr->auxdataConst<float>("delta_z0_sintheta"); + + if (m_config->enablePromptLeptonImprovedVetoStudies()) { + m_PLIV_mu_PromptLeptonRNN_non_prompt_b[i] = PLIV_mu_PromptLeptonRNN_non_prompt_b.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonRNN_non_prompt_b(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonRNN_non_prompt_c[i] = PLIV_mu_PromptLeptonRNN_non_prompt_c.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonRNN_non_prompt_c(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonRNN_prompt[i] = PLIV_mu_PromptLeptonRNN_prompt.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonRNN_prompt(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonImprovedInput_MVAXBin[i] = PLIV_mu_PromptLeptonImprovedInput_MVAXBin.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonImprovedInput_MVAXBin(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonImprovedInput_topoetcone30rel[i] = PLIV_mu_PromptLeptonImprovedInput_topoetcone30rel.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonImprovedInput_topoetcone30rel(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonImprovedInput_PtFrac[i] = PLIV_mu_PromptLeptonImprovedInput_PtFrac.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonImprovedInput_PtFrac(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonImprovedInput_DRlj[i] = PLIV_mu_PromptLeptonImprovedInput_DRlj.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonImprovedInput_DRlj(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel[i] = PLIV_mu_PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonImprovedInput_CaloClusterERel[i] = PLIV_mu_PromptLeptonImprovedInput_CaloClusterERel.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonImprovedInput_CaloClusterERel(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest[i] = PLIV_mu_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest(*muPtr) : -999.; + m_PLIV_mu_PromptLeptonImprovedVeto[i] = PLIV_mu_PromptLeptonImprovedVeto.isAvailable(*muPtr) ? PLIV_mu_PromptLeptonImprovedVeto(*muPtr) : -999.; + } + //retrieve the truth-matching variables from MCTruthClassifier + if (m_config->isMC()) { + static const SG::AuxElement::Accessor<int> acc_mctt("truthType"); + static const SG::AuxElement::Accessor<int> acc_mcto("truthOrigin"); + m_mu_true_type[i] = 0; + m_mu_true_origin[i] = 0; + if (acc_mctt.isAvailable(*muPtr)) m_mu_true_type[i] = acc_mctt(*muPtr); + if (acc_mcto.isAvailable(*muPtr)) m_mu_true_origin[i] = acc_mcto(*muPtr); + m_mu_true_isPrompt[i] = isPromptMuon(m_mu_true_type[i], m_mu_true_origin[i]); + } + ++i; + } } - void EventSaverFlatNtuple::saveEvent(const top::Event& event) { + //soft muons + if (m_config->useSoftMuons()) { + unsigned int i(0); + unsigned int n_muons = event.m_softmuons.size(); + + m_softmu_pt.resize(n_muons); + m_softmu_eta.resize(n_muons); + m_softmu_phi.resize(n_muons); + m_softmu_e.resize(n_muons); + m_softmu_charge.resize(n_muons); + m_softmu_d0.resize(n_muons); + m_softmu_d0sig.resize(n_muons); + m_softmu_delta_z0_sintheta.resize(n_muons); + + if (m_config->isMC()) { + m_softmu_true_type.resize(n_muons); + m_softmu_true_origin.resize(n_muons); + m_softmu_true_isPrompt.resize(n_muons); + m_softmu_SF_ID.resize(n_muons); + m_softmu_SF_ID_STAT_UP.resize(n_muons); + m_softmu_SF_ID_STAT_DOWN.resize(n_muons); + m_softmu_SF_ID_SYST_UP.resize(n_muons); + m_softmu_SF_ID_SYST_DOWN.resize(n_muons); + m_softmu_SF_ID_STAT_LOWPT_UP.resize(n_muons); + m_softmu_SF_ID_STAT_LOWPT_DOWN.resize(n_muons); + m_softmu_SF_ID_SYST_LOWPT_UP.resize(n_muons); + m_softmu_SF_ID_SYST_LOWPT_DOWN.resize(n_muons); + + if(m_config->softmuonAdditionalTruthInfo()) + { + m_softmu_parton_origin_flag.resize(n_muons); + m_softmu_particle_origin_flag.resize(n_muons); + m_softmu_parent_pdgid.resize(n_muons); + m_softmu_b_hadron_parent_pdgid.resize(n_muons); + m_softmu_c_hadron_parent_pdgid.resize(n_muons); + } + } - // record the event? - if (m_config->saveOnlySelectedEvents() && !event.m_saveEvent) - return; + for (const auto* const muPtr : event.m_softmuons) { + m_softmu_pt[i] = muPtr->pt(); + m_softmu_eta[i] = muPtr->eta(); + m_softmu_phi[i] = muPtr->phi(); + m_softmu_e[i] = muPtr->e(); + m_softmu_charge[i] = muPtr->charge(); - //We have decorated event-info with a variable for each selection - with pass / fail - recordSelectionDecision(event); + m_softmu_d0[i] = 999.; + m_softmu_d0sig[i] = 999.; + m_softmu_delta_z0_sintheta[i] = 999.; - recordTriggerDecision(event); + const xAOD::TrackParticle* mutrack = muPtr->primaryTrackParticle(); - //some event weights - m_weight_mc = 0.; - if (m_config->isMC()) -// m_weight_mc = event.m_info->mcEventWeight(); - m_weight_mc = event.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix + if (mutrack) m_softmu_d0[i] = mutrack->d0(); + if (muPtr->isAvailable<float>("d0sig")) m_softmu_d0sig[i] = muPtr->auxdataConst<float>("d0sig"); + if (muPtr->isAvailable<float>("delta_z0_sintheta")) m_softmu_delta_z0_sintheta[i] = muPtr->auxdataConst<float>("delta_z0_sintheta"); if (m_config->isMC()) { + m_softmu_SF_ID[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::nominal); + if (event.m_hashValue == m_config->nominalHashValue()) { + m_softmu_SF_ID_STAT_UP[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::MU_SF_ID_STAT_UP); + m_softmu_SF_ID_STAT_DOWN[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::MU_SF_ID_STAT_DOWN); + m_softmu_SF_ID_SYST_UP[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::MU_SF_ID_SYST_UP); + m_softmu_SF_ID_SYST_DOWN[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::MU_SF_ID_SYST_DOWN); + m_softmu_SF_ID_STAT_LOWPT_UP[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::MU_SF_ID_STAT_LOWPT_UP); + m_softmu_SF_ID_STAT_LOWPT_DOWN[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::MU_SF_ID_STAT_LOWPT_DOWN); + m_softmu_SF_ID_SYST_LOWPT_UP[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::MU_SF_ID_SYST_LOWPT_UP); + m_softmu_SF_ID_SYST_LOWPT_DOWN[i] = m_sfRetriever->softmuonSF_ID(*muPtr, top::topSFSyst::MU_SF_ID_SYST_LOWPT_DOWN); + } - m_weight_pileup = m_sfRetriever->pileupSF(event); + static const SG::AuxElement::Accessor<int> acc_mctt("truthType"); + static const SG::AuxElement::Accessor<int> acc_mcto("truthOrigin"); + m_softmu_true_type[i] = 0; + m_softmu_true_origin[i] = 0; + if (acc_mctt.isAvailable(*muPtr)) m_softmu_true_type[i] = acc_mctt(*muPtr); + if (acc_mcto.isAvailable(*muPtr)) m_softmu_true_origin[i] = acc_mcto(*muPtr); + m_softmu_true_isPrompt[i] = isPromptMuon(m_softmu_true_type[i], m_softmu_true_origin[i]); + + if(m_config->softmuonAdditionalTruthInfo()) + { + //these truth info are written in SoftMuonObjectCollectionMaker.cxx + + m_softmu_parton_origin_flag[i]=0; + if(m_config->softmuonAdditionalTruthInfoCheckPartonOrigin()) + { + static const SG::AuxElement::Accessor<top::LepPartonOriginFlag> leppartonoriginflag("LepPartonOriginFlag"); + if(leppartonoriginflag.isAvailable(*muPtr)) m_softmu_parton_origin_flag[i]=static_cast<int>(leppartonoriginflag(*muPtr)); + } + m_softmu_particle_origin_flag[i]=0; + m_softmu_parent_pdgid[i]=0; + m_softmu_b_hadron_parent_pdgid[i]=0; + m_softmu_c_hadron_parent_pdgid[i]=0; + static const SG::AuxElement::Accessor<top::LepParticleOriginFlag> lepparticleoriginflag("LepParticleOriginFlag"); + if(lepparticleoriginflag.isAvailable(*muPtr)) m_softmu_particle_origin_flag[i]=static_cast<int>(lepparticleoriginflag(*muPtr)); + + static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> Mother("truthMotherLink"); + const xAOD::TruthParticle* mother = 0; + if(Mother.isAvailable(*muPtr)) mother=Mother(*muPtr); + if(mother) m_softmu_parent_pdgid[i]=mother->pdgId(); + + static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> BMother("truthBMotherLink"); + const xAOD::TruthParticle* Bmother = 0; + if(BMother.isAvailable(*muPtr)) Bmother=BMother(*muPtr); + if(Bmother) m_softmu_b_hadron_parent_pdgid[i]=Bmother->pdgId(); + + static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> CMother("truthCMotherLink"); + const xAOD::TruthParticle* Cmother = 0; + if(CMother.isAvailable(*muPtr)) Cmother=CMother(*muPtr); + if(Cmother) m_softmu_c_hadron_parent_pdgid[i]=Cmother->pdgId(); + + if(m_config->softmuonAdditionalTruthInfoDoVerbose()) asg::msgUserCode::ATH_MSG_INFO("writing soft muon with pt="<<m_softmu_pt[i] <<" parton_origin_flag="<<m_softmu_parton_origin_flag[i]<<" particle_origin_flag="<<m_softmu_particle_origin_flag[i]<<" parent_pdg_id="<<m_softmu_parent_pdgid[i]<<" b_hadron_parent_pdg_id="<<m_softmu_b_hadron_parent_pdgid[i]<<" c_hadron_parent_pdg_id="<<m_softmu_c_hadron_parent_pdgid[i]); + } + }//end of if (m_config->isMC()) + ++i; + }//end of loop on softmuons + }//end of if (m_config->useSoftMuons()) + + //photons + if (m_config->usePhotons()) { + unsigned int i(0); + m_ph_pt.resize(event.m_photons.size()); + m_ph_eta.resize(event.m_photons.size()); + m_ph_phi.resize(event.m_photons.size()); + m_ph_e.resize(event.m_photons.size()); + m_ph_iso.resize(event.m_photons.size()); + for (const auto* const phPtr : event.m_photons) { + m_ph_pt[i] = phPtr->pt(); + m_ph_eta[i] = phPtr->eta(); + m_ph_phi[i] = phPtr->phi(); + m_ph_e[i] = phPtr->e(); + + m_ph_iso[i] = 0.; + if (phPtr->isAvailable<float>("ptvarcone20")) m_ph_iso[i] = phPtr->auxdata<float>("ptvarcone20"); + + ++i; + } + } - m_weight_leptonSF = m_sfRetriever->leptonSF(event,top::topSFSyst::nominal); - if (m_config->useTaus()) - m_weight_tauSF = m_sfRetriever->tauSF(event, top::topSFSyst::nominal); + //taus + if (m_config->useTaus()) { + unsigned int i(0); + m_tau_pt.resize(event.m_tauJets.size()); + m_tau_eta.resize(event.m_tauJets.size()); + m_tau_phi.resize(event.m_tauJets.size()); + m_tau_charge.resize(event.m_tauJets.size()); + for (const auto* const tauPtr : event.m_tauJets) { + m_tau_pt[i] = tauPtr->pt(); + m_tau_eta[i] = tauPtr->eta(); + m_tau_phi[i] = tauPtr->phi(); + m_tau_charge[i] = tauPtr->charge(); + ++i; + } + } - if (m_config->usePhotons()) - m_weight_photonSF = m_sfRetriever->photonSF(event, top::topSFSyst::nominal); + // tracks + if (m_config->useTracks()) { + + m_track_pt.resize(event.m_tracks.size()); + m_track_eta.resize(event.m_tracks.size()); + m_track_phi.resize(event.m_tracks.size()); + m_track_e.resize(event.m_tracks.size()); + m_track_charge.resize(event.m_tracks.size()); + m_track_d0.resize(event.m_tracks.size()); + m_track_d0_significance.resize(event.m_tracks.size()); + m_track_z0.resize(event.m_tracks.size()); + m_track_z0_significance.resize(event.m_tracks.size()); + m_track_phi0.resize(event.m_tracks.size()); + m_track_theta.resize(event.m_tracks.size()); + m_track_qOverP.resize(event.m_tracks.size()); + m_track_chiSquared.resize(event.m_tracks.size()); + m_track_numberDoF.resize(event.m_tracks.size()); + + unsigned int i = 0; + for (const auto* const trkPtr : event.m_tracks){ + + m_track_pt[i] = trkPtr->pt(); + m_track_eta[i] = trkPtr->eta(); + m_track_phi[i] = trkPtr->phi(); + m_track_e[i] = trkPtr->e(); + m_track_charge[i] = trkPtr->charge(); + m_track_d0[i] = trkPtr->d0(); + m_track_d0_significance[i] = xAOD::TrackingHelpers::d0significance(trkPtr); + m_track_z0[i] = trkPtr->z0(); + m_track_z0_significance[i] = xAOD::TrackingHelpers::z0significance(trkPtr); + m_track_phi0[i] = trkPtr->phi0(); + m_track_theta[i] = trkPtr->theta(); + m_track_qOverP[i] = trkPtr->qOverP(); + m_track_chiSquared[i] = trkPtr->chiSquared(); + m_track_numberDoF[i] = trkPtr->numberDoF(); + + ++i; - for( auto& tagWP : m_config -> bTagWP_available()) { - m_weight_bTagSF[tagWP] = m_sfRetriever->btagSF(event, top::topSFSyst::nominal, tagWP); - } - if (m_config->useTrackJets()) { - for( auto& tagWP : m_config -> bTagWP_available_trkJet()) { - m_weight_trackjet_bTagSF[tagWP] = m_sfRetriever->btagSF(event, top::topSFSyst::nominal, tagWP, true); - } - } + } - m_weight_jvt = m_sfRetriever->jvtSF(event, top::topSFSyst::nominal); + } - if (m_config->isSherpa22Vjets()) { - if (event.m_info->isAvailable<double>("Sherpa22VJetsWeight")) { - m_weight_sherpa_22_vjets = event.m_info->auxdataConst<double>("Sherpa22VJetsWeight"); - } + + + //jets + if (m_config->useJets()) { + unsigned int i(0); + m_jet_pt.resize(event.m_jets.size()); + m_jet_eta.resize(event.m_jets.size()); + m_jet_phi.resize(event.m_jets.size()); + m_jet_e.resize(event.m_jets.size()); + if (m_config->bTagAlgo_MV2c10_used()) { + m_jet_mv2c10.resize(event.m_jets.size()); + } + m_jet_jvt.resize(event.m_jets.size()); + m_jet_fjvt.resize(event.m_jets.size()); + m_jet_passfjvt.resize(event.m_jets.size()); + + // ghost tracks + if (m_config->useJetGhostTrack()) { + m_jet_ghostTrack_pt.clear(); + m_jet_ghostTrack_eta.clear(); + m_jet_ghostTrack_phi.clear(); + m_jet_ghostTrack_e.clear(); + m_jet_ghostTrack_d0.clear(); + m_jet_ghostTrack_z0.clear(); + m_jet_ghostTrack_qOverP.clear(); + + + m_jet_ghostTrack_pt.resize(event.m_jets.size()); + m_jet_ghostTrack_eta.resize(event.m_jets.size()); + m_jet_ghostTrack_phi.resize(event.m_jets.size()); + m_jet_ghostTrack_e.resize(event.m_jets.size()); + m_jet_ghostTrack_d0.resize(event.m_jets.size()); + m_jet_ghostTrack_z0.resize(event.m_jets.size()); + m_jet_ghostTrack_qOverP.resize(event.m_jets.size()); + } + + // R21 b-tagging + for (const std::string& algo : m_config->bTagAlgo_available()) { + m_jet_DLx[algo].resize(event.m_jets.size()); + m_jet_DLx_pb[algo].resize(event.m_jets.size()); + m_jet_DLx_pc[algo].resize(event.m_jets.size()); + m_jet_DLx_pu[algo].resize(event.m_jets.size()); + } + if (m_config->isMC()) { + m_jet_truthflav.resize(event.m_jets.size()); + m_jet_truthPartonLabel.resize(event.m_jets.size()); + m_jet_isTrueHS.resize(event.m_jets.size()); + m_jet_HadronConeExclExtendedTruthLabelID.resize(event.m_jets.size()); + } + for (auto& tagWP : m_config->bTagWP_available()) { + + if (tagWP.find("Continuous") == std::string::npos) { + m_jet_isbtagged[tagWP].resize(event.m_jets.size()); + if (std::find(m_config->bTagWP_calibrated().begin(), + m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; + + if (m_config->isMC() && m_config->storePerJetBtagSFs()) { + m_perjet_weight_bTagSF[tagWP].resize(event.m_jets.size()); + m_perjet_weight_bTagSF_eigen_B_up[tagWP].resize(event.m_jets.size(), std::vector<float>(m_config->btagging_num_B_eigenvars(tagWP))); + m_perjet_weight_bTagSF_eigen_B_down[tagWP].resize(event.m_jets.size(), std::vector<float>(m_config->btagging_num_B_eigenvars(tagWP))); + m_perjet_weight_bTagSF_eigen_C_up[tagWP].resize(event.m_jets.size(), std::vector<float>(m_config->btagging_num_C_eigenvars(tagWP))); + m_perjet_weight_bTagSF_eigen_C_down[tagWP].resize(event.m_jets.size(), std::vector<float>(m_config->btagging_num_C_eigenvars(tagWP))); + m_perjet_weight_bTagSF_eigen_Light_up[tagWP].resize(event.m_jets.size(), std::vector<float>(m_config->btagging_num_Light_eigenvars(tagWP))); + m_perjet_weight_bTagSF_eigen_Light_down[tagWP].resize(event.m_jets.size(), std::vector<float>(m_config->btagging_num_Light_eigenvars(tagWP))); + for (const std::string& name : m_config->btagging_namedSysts(tagWP)) { + m_perjet_weight_bTagSF_named_up[tagWP][name].resize(event.m_jets.size()); + m_perjet_weight_bTagSF_named_down[tagWP][name].resize(event.m_jets.size()); } + } + } else m_jet_tagWeightBin[tagWP].resize(event.m_jets.size()); + } + for (const auto* const jetPtr : event.m_jets) { + m_jet_pt[i] = jetPtr->pt(); + m_jet_eta[i] = jetPtr->eta(); + m_jet_phi[i] = jetPtr->phi(); + m_jet_e[i] = jetPtr->e(); + // In R21, list of b-tagging variables is changing and this is outdated + const xAOD::BTagging* btag(nullptr); + btag = jetPtr->btagging(); + if (m_config->isMC()) { + m_jet_truthflav[i] = -99; + if (jetPtr->isAvailable<int>("HadronConeExclTruthLabelID")) { + jetPtr->getAttribute("HadronConeExclTruthLabelID", m_jet_truthflav[i]); + } + m_jet_truthPartonLabel[i] = -99; + if (jetPtr->isAvailable<int>("PartonTruthLabelID")) { + jetPtr->getAttribute("PartonTruthLabelID", m_jet_truthPartonLabel[i]); + } + m_jet_isTrueHS[i] = false; + if (jetPtr->isAvailable<char>("AnalysisTop_isHS")) { + jetPtr->getAttribute("AnalysisTop_isHS", m_jet_isTrueHS[i]); + } + m_jet_HadronConeExclExtendedTruthLabelID[i] = -99; + if (jetPtr->isAvailable<int>("HadronConeExclExtendedTruthLabelID")) { + jetPtr->getAttribute("HadronConeExclExtendedTruthLabelID", m_jet_HadronConeExclExtendedTruthLabelID[i]); + } + } - // writing the systematic-shifted SFs only in the nominal (or nominal_Loose) tree - if (event.m_hashValue == m_config->nominalHashValue()) { - - m_weight_pileup_UP = m_sfRetriever->pileupSF( event, +1 ); // up variation - m_weight_pileup_DOWN = m_sfRetriever->pileupSF( event, -1 ); // down variation - - m_weight_leptonSF_EL_SF_Trigger_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::EL_SF_Trigger_UP); - m_weight_leptonSF_EL_SF_Trigger_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::EL_SF_Trigger_DOWN); - m_weight_leptonSF_EL_SF_Reco_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::EL_SF_Reco_UP); - m_weight_leptonSF_EL_SF_Reco_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::EL_SF_Reco_DOWN); - m_weight_leptonSF_EL_SF_ID_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::EL_SF_ID_UP); - m_weight_leptonSF_EL_SF_ID_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::EL_SF_ID_DOWN); - m_weight_leptonSF_EL_SF_Isol_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::EL_SF_Isol_UP); - m_weight_leptonSF_EL_SF_Isol_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::EL_SF_Isol_DOWN); - - m_weight_leptonSF_MU_SF_Trigger_STAT_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_Trigger_STAT_UP); - m_weight_leptonSF_MU_SF_Trigger_STAT_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_Trigger_STAT_DOWN); - m_weight_leptonSF_MU_SF_Trigger_SYST_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_Trigger_SYST_UP); - m_weight_leptonSF_MU_SF_Trigger_SYST_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_Trigger_SYST_DOWN); - // Muon ID SF systematics (regular) - m_weight_leptonSF_MU_SF_ID_STAT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_STAT_UP); - m_weight_leptonSF_MU_SF_ID_STAT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_STAT_DOWN); - m_weight_leptonSF_MU_SF_ID_SYST_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_SYST_UP); - m_weight_leptonSF_MU_SF_ID_SYST_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_SYST_DOWN); - // Muon ID SF systematics (regular) - m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_STAT_LOWPT_UP); - m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_STAT_LOWPT_DOWN); - m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_SYST_LOWPT_UP); - m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN = m_sfRetriever->leptonSF(event, top::topSFSyst::MU_SF_ID_SYST_LOWPT_DOWN); - // Muon isolation SF systematics - m_weight_leptonSF_MU_SF_Isol_STAT_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_Isol_STAT_UP); - m_weight_leptonSF_MU_SF_Isol_STAT_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_Isol_STAT_DOWN); - m_weight_leptonSF_MU_SF_Isol_SYST_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_Isol_SYST_UP); - m_weight_leptonSF_MU_SF_Isol_SYST_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_Isol_SYST_DOWN); - m_weight_leptonSF_MU_SF_TTVA_STAT_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_TTVA_STAT_UP); - m_weight_leptonSF_MU_SF_TTVA_STAT_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_TTVA_STAT_DOWN); - m_weight_leptonSF_MU_SF_TTVA_SYST_UP = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_TTVA_SYST_UP); - m_weight_leptonSF_MU_SF_TTVA_SYST_DOWN = m_sfRetriever->leptonSF(event,top::topSFSyst::MU_SF_TTVA_SYST_DOWN); - - - m_weight_indiv_SF_EL_Trigger = m_sfRetriever -> triggerSF(event,top::topSFSyst::nominal); - m_weight_indiv_SF_EL_Trigger_UP = m_sfRetriever -> triggerSF(event,top::topSFSyst::EL_SF_Trigger_UP); - m_weight_indiv_SF_EL_Trigger_DOWN = m_sfRetriever -> triggerSF(event,top::topSFSyst::EL_SF_Trigger_DOWN); - m_weight_indiv_SF_EL_Reco = m_sfRetriever -> electronSF(event,top::topSFSyst::nominal, top::topSFComp::RECO); - m_weight_indiv_SF_EL_Reco_UP = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_Reco_UP, top::topSFComp::RECO); - m_weight_indiv_SF_EL_Reco_DOWN = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_Reco_DOWN, top::topSFComp::RECO); - m_weight_indiv_SF_EL_ID = m_sfRetriever -> electronSF(event,top::topSFSyst::nominal, top::topSFComp::ID); - m_weight_indiv_SF_EL_ID_UP = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_ID_UP, top::topSFComp::ID); - m_weight_indiv_SF_EL_ID_DOWN = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_ID_DOWN, top::topSFComp::ID); - m_weight_indiv_SF_EL_Isol = m_sfRetriever -> electronSF(event,top::topSFSyst::nominal, top::topSFComp::ISOLATION); - m_weight_indiv_SF_EL_Isol_UP = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_Isol_UP, top::topSFComp::ISOLATION); - m_weight_indiv_SF_EL_Isol_DOWN = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_Isol_DOWN, top::topSFComp::ISOLATION); - m_weight_indiv_SF_EL_ChargeID = m_sfRetriever -> electronSF(event,top::topSFSyst::nominal, top::topSFComp::CHARGEID); - m_weight_indiv_SF_EL_ChargeID_UP = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_ChargeID_UP, top::topSFComp::CHARGEID); - m_weight_indiv_SF_EL_ChargeID_DOWN = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_ChargeID_DOWN,top::topSFComp::CHARGEID); - m_weight_indiv_SF_EL_ChargeMisID = m_sfRetriever -> electronSF(event,top::topSFSyst::nominal, top::topSFComp::CHARGEMISID); - m_weight_indiv_SF_EL_ChargeMisID_STAT_UP = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_ChargeMisID_STAT_UP, top::topSFComp::CHARGEMISID); - m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_ChargeMisID_STAT_DOWN,top::topSFComp::CHARGEMISID); - m_weight_indiv_SF_EL_ChargeMisID_SYST_UP = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_ChargeMisID_SYST_UP, top::topSFComp::CHARGEMISID); - m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN = m_sfRetriever -> electronSF(event,top::topSFSyst::EL_SF_ChargeMisID_SYST_DOWN,top::topSFComp::CHARGEMISID); - ATH_MSG_DEBUG("Electron Trigger SF = "<<m_weight_indiv_SF_EL_Trigger<<" + "<<m_weight_indiv_SF_EL_Trigger_UP<<" - "<<m_weight_indiv_SF_EL_Trigger_DOWN); - ATH_MSG_DEBUG("Electron Reco SF = "<<m_weight_indiv_SF_EL_Reco<<" + "<<m_weight_indiv_SF_EL_Reco_UP<<" - "<<m_weight_indiv_SF_EL_Reco_DOWN); - ATH_MSG_DEBUG("Electron ID SF = "<<m_weight_indiv_SF_EL_ID<<" + "<<m_weight_indiv_SF_EL_ID_UP<<" - "<<m_weight_indiv_SF_EL_ID_DOWN); - ATH_MSG_DEBUG("Electron Charge ID SF = "<<m_weight_indiv_SF_EL_ChargeID<<" + "<<m_weight_indiv_SF_EL_ChargeID_UP<<" - "<<m_weight_indiv_SF_EL_ChargeID_DOWN); - ATH_MSG_DEBUG("Electron Charge Mis ID SF = "<<m_weight_indiv_SF_EL_ChargeMisID<<" + "<<m_weight_indiv_SF_EL_ChargeMisID_STAT_UP<<" - "<<m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN<<" + "<<m_weight_indiv_SF_EL_ChargeMisID_SYST_UP<<" - "<<m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN); - - m_weight_indiv_SF_MU_Trigger = m_sfRetriever -> triggerSF(event,top::topSFSyst::nominal); - m_weight_indiv_SF_MU_Trigger_STAT_UP = m_sfRetriever -> triggerSF(event,top::topSFSyst::MU_SF_Trigger_STAT_UP); - m_weight_indiv_SF_MU_Trigger_STAT_DOWN = m_sfRetriever -> triggerSF(event,top::topSFSyst::MU_SF_Trigger_STAT_DOWN); - m_weight_indiv_SF_MU_Trigger_SYST_UP = m_sfRetriever -> triggerSF(event,top::topSFSyst::MU_SF_Trigger_SYST_UP); - m_weight_indiv_SF_MU_Trigger_SYST_DOWN = m_sfRetriever -> triggerSF(event,top::topSFSyst::MU_SF_Trigger_SYST_DOWN); - m_weight_indiv_SF_MU_ID = m_sfRetriever -> muonSF(event,top::topSFSyst::nominal, top::topSFComp::ID); - // Muon ID SF systematics (regular) - m_weight_indiv_SF_MU_ID_STAT_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_STAT_UP, top::topSFComp::ID); - m_weight_indiv_SF_MU_ID_STAT_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_STAT_DOWN, top::topSFComp::ID); - m_weight_indiv_SF_MU_ID_SYST_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_SYST_UP, top::topSFComp::ID); - m_weight_indiv_SF_MU_ID_SYST_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_SYST_DOWN, top::topSFComp::ID); - // Muon ID SF systematics (low pt) - m_weight_indiv_SF_MU_ID_STAT_LOWPT_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_STAT_LOWPT_UP, top::topSFComp::ID); - m_weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_STAT_LOWPT_DOWN, top::topSFComp::ID); - m_weight_indiv_SF_MU_ID_SYST_LOWPT_UP = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_SYST_LOWPT_UP, top::topSFComp::ID); - m_weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN = m_sfRetriever->muonSF(event, top::topSFSyst::MU_SF_ID_SYST_LOWPT_DOWN, top::topSFComp::ID); - // Muon isolation SF systematics - m_weight_indiv_SF_MU_Isol = m_sfRetriever -> muonSF(event,top::topSFSyst::nominal, top::topSFComp::ISOLATION); - m_weight_indiv_SF_MU_Isol_STAT_UP = m_sfRetriever -> muonSF(event,top::topSFSyst::MU_SF_Isol_STAT_UP, top::topSFComp::ISOLATION); - m_weight_indiv_SF_MU_Isol_STAT_DOWN = m_sfRetriever -> muonSF(event,top::topSFSyst::MU_SF_Isol_STAT_DOWN, top::topSFComp::ISOLATION); - m_weight_indiv_SF_MU_Isol_SYST_UP = m_sfRetriever -> muonSF(event,top::topSFSyst::MU_SF_Isol_SYST_UP, top::topSFComp::ISOLATION); - m_weight_indiv_SF_MU_Isol_SYST_DOWN = m_sfRetriever -> muonSF(event,top::topSFSyst::MU_SF_Isol_SYST_DOWN, top::topSFComp::ISOLATION); - m_weight_indiv_SF_MU_TTVA = m_sfRetriever -> muonSF(event,top::topSFSyst::nominal, top::topSFComp::TTVA); - m_weight_indiv_SF_MU_TTVA_STAT_UP = m_sfRetriever -> muonSF(event,top::topSFSyst::MU_SF_TTVA_STAT_UP, top::topSFComp::TTVA); - m_weight_indiv_SF_MU_TTVA_STAT_DOWN = m_sfRetriever -> muonSF(event,top::topSFSyst::MU_SF_TTVA_STAT_DOWN, top::topSFComp::TTVA); - m_weight_indiv_SF_MU_TTVA_SYST_UP = m_sfRetriever -> muonSF(event,top::topSFSyst::MU_SF_TTVA_SYST_UP, top::topSFComp::TTVA); - m_weight_indiv_SF_MU_TTVA_SYST_DOWN = m_sfRetriever -> muonSF(event,top::topSFSyst::MU_SF_TTVA_SYST_DOWN, top::topSFComp::TTVA); - - - ATH_MSG_DEBUG("Muon Trigger SF = "<<m_weight_indiv_SF_MU_Trigger<<" + "<< m_weight_indiv_SF_MU_Trigger_STAT_UP<<" - "<< m_weight_indiv_SF_MU_Trigger_STAT_DOWN<<" + "<< m_weight_indiv_SF_MU_Trigger_SYST_UP<<" - "<< m_weight_indiv_SF_MU_Trigger_SYST_DOWN); - - ATH_MSG_DEBUG("Muon ID SF = "<<m_weight_indiv_SF_MU_ID<<" + "<< m_weight_indiv_SF_MU_ID_STAT_UP<<" - "<< m_weight_indiv_SF_MU_ID_STAT_DOWN<<" + "<< m_weight_indiv_SF_MU_ID_SYST_UP<<" - "<< m_weight_indiv_SF_MU_ID_SYST_DOWN); - + if (m_config->useJetGhostTrack() && m_jet_pt[i] > m_config->jetPtGhostTracks() && std::abs(m_jet_eta[i])<m_config->jetEtaGhostTracks()) { + static const SG::AuxElement::Accessor< float > accD0("d0"); + static const SG::AuxElement::Accessor< float > accZ0("z0"); + static const SG::AuxElement::Accessor< float > accQOverP("qOverP"); + + std::vector<const xAOD::TrackParticle*> ghostTracks; + + if(jetPtr->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack(event.m_hashValue),ghostTracks)) { + + const unsigned int nghostTracks = ghostTracks.size(); + + m_jet_ghostTrack_pt[i].clear(); + m_jet_ghostTrack_eta[i].clear(); + m_jet_ghostTrack_phi[i].clear(); + m_jet_ghostTrack_e[i].clear(); + m_jet_ghostTrack_d0[i].clear(); + m_jet_ghostTrack_z0[i].clear(); + m_jet_ghostTrack_qOverP[i].clear(); + + m_jet_ghostTrack_pt[i].reserve(nghostTracks); + m_jet_ghostTrack_eta[i].reserve(nghostTracks); + m_jet_ghostTrack_phi[i].reserve(nghostTracks); + m_jet_ghostTrack_e[i].reserve(nghostTracks); + m_jet_ghostTrack_d0[i].reserve(nghostTracks); + m_jet_ghostTrack_z0[i].reserve(nghostTracks); + m_jet_ghostTrack_qOverP[i].reserve(nghostTracks); + + + for (unsigned int iGhost = 0; iGhost < nghostTracks; ++iGhost) { + + top::check(ghostTracks.at(iGhost), "Error in EventSaverFlatNtuple: Found jet with null pointer in ghost track vector."); - if (m_config->useTaus()) { - // Tau-electron overlap removal - m_weight_tauSF_ELEOLR_UP = m_sfRetriever->tauSF(event, top::topSFSyst::TAU_SF_ELEOLR_TOTAL_UP); - m_weight_tauSF_ELEOLR_DOWN = m_sfRetriever->tauSF(event, top::topSFSyst::TAU_SF_ELEOLR_TOTAL_DOWN); - // Tau Jet IDWP - m_weight_tauSF_JETID_UP = m_sfRetriever->tauSF(event, top::topSFSyst::TAU_SF_JETID_TOTAL_UP); - m_weight_tauSF_JETID_DOWN = m_sfRetriever->tauSF(event, top::topSFSyst::TAU_SF_JETID_TOTAL_DOWN); - // Tau reconstruction - m_weight_tauSF_RECO_UP = m_sfRetriever->tauSF(event, top::topSFSyst::TAU_SF_RECO_TOTAL_UP); - m_weight_tauSF_RECO_DOWN = m_sfRetriever->tauSF(event, top::topSFSyst::TAU_SF_RECO_TOTAL_DOWN); - } + if(ghostTracks.at(iGhost)->auxdataConst< char >("passPreORSelection") != 1) + { continue;} - if (m_config->usePhotons()) { - m_weight_photonSF_ID_UP = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_IDSF_UP); - m_weight_photonSF_ID_DOWN = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_IDSF_DOWN); - m_weight_photonSF_effIso = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_EFF_ISO); - m_weight_photonSF_effLowPtIso_UP = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_EFF_LOWPTISO_UP); - m_weight_photonSF_effLowPtIso_DOWN = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_EFF_LOWPTISO_DOWN); - m_weight_photonSF_effTrkIso_UP = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_EFF_TRKISO_UP); - m_weight_photonSF_effTrkIso_DOWN = m_sfRetriever->photonSF(event, top::topSFSyst::PHOTON_EFF_TRKISO_DOWN); - } + m_jet_ghostTrack_pt[i].emplace_back(ghostTracks.at(iGhost)->pt()); + m_jet_ghostTrack_eta[i].emplace_back(ghostTracks.at(iGhost)->eta()); + m_jet_ghostTrack_phi[i].emplace_back(ghostTracks.at(iGhost)->phi()); + m_jet_ghostTrack_e[i].emplace_back(ghostTracks.at(iGhost)->e()); + m_jet_ghostTrack_d0[i].emplace_back(accD0(*ghostTracks.at(iGhost))); + m_jet_ghostTrack_z0[i].emplace_back(accZ0(*ghostTracks.at(iGhost))); + m_jet_ghostTrack_qOverP[i].emplace_back(accQOverP(*ghostTracks.at(iGhost))); + } + + } + } - m_weight_jvt_up = m_sfRetriever->jvtSF(event, top::topSFSyst::JVT_UP); - m_weight_jvt_down = m_sfRetriever->jvtSF(event, top::topSFSyst::JVT_DOWN); - } - // for b-tagging SFs, can also have systematic-shifted in systematics trees - if (event.m_hashValue == m_config->nominalHashValue() || m_config->dumpBtagSystsInSystTrees()) { - for( auto& tagWP : m_config -> bTagWP_available()) { - // skip uncalibrated though available WPs - if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; - m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_B, - m_weight_bTagSF_eigen_B_up[tagWP], - m_weight_bTagSF_eigen_B_down[tagWP], tagWP); - m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_C, - m_weight_bTagSF_eigen_C_up[tagWP], - m_weight_bTagSF_eigen_C_down[tagWP], tagWP); - m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_LIGHT, - m_weight_bTagSF_eigen_Light_up[tagWP], - m_weight_bTagSF_eigen_Light_down[tagWP], tagWP); - for (auto name : m_config->btagging_namedSysts(tagWP)) { - m_weight_bTagSF_named_up[tagWP][name] = m_sfRetriever->btagSF( event, top::topSFSyst::BTAG_SF_NAMED_UP, tagWP, false, name ); - m_weight_bTagSF_named_down[tagWP][name] = m_sfRetriever->btagSF( event, top::topSFSyst::BTAG_SF_NAMED_DOWN, tagWP, false, name ); - } - } - if (m_config->useTrackJets()) { - for( auto& tagWP : m_config -> bTagWP_available_trkJet()) { - // skip uncalibrated though available WPs - if (std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; - m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_B, - m_weight_trackjet_bTagSF_eigen_B_up[tagWP], - m_weight_trackjet_bTagSF_eigen_B_down[tagWP], tagWP, true); - m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_C, - m_weight_trackjet_bTagSF_eigen_C_up[tagWP], - m_weight_trackjet_bTagSF_eigen_C_down[tagWP], tagWP, true); - m_sfRetriever->btagSF_eigen_vars(event, top::topSFSyst::BTAG_SF_EIGEN_LIGHT, - m_weight_trackjet_bTagSF_eigen_Light_up[tagWP], - m_weight_trackjet_bTagSF_eigen_Light_down[tagWP], tagWP, true); - for (auto name : m_config->btagging_namedSysts(tagWP)) { - m_weight_trackjet_bTagSF_named_up[tagWP][name] = m_sfRetriever->btagSF( event, top::topSFSyst::BTAG_SF_NAMED_UP, tagWP, true, name); - m_weight_trackjet_bTagSF_named_down[tagWP][name] = m_sfRetriever->btagSF( event, top::topSFSyst::BTAG_SF_NAMED_DOWN, tagWP, true, name ); - } - } - } + for (auto& tagWP : m_config->bTagWP_available()) { + if (tagWP.find("Continuous") == std::string::npos) { + m_jet_isbtagged[tagWP][i] = false; + if (jetPtr->isAvailable<char>("isbtagged_" + tagWP)) m_jet_isbtagged[tagWP][i] = jetPtr->auxdataConst<char>("isbtagged_" + tagWP); + if (m_config->isMC() && m_config->storePerJetBtagSFs()) { + if (std::find(m_config->bTagWP_calibrated().begin(), + m_config->bTagWP_calibrated().end(), tagWP) == m_config->bTagWP_calibrated().end()) continue; + m_perjet_weight_bTagSF[tagWP][i] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_nom"); + for (size_t ivar = 0; ivar < m_config->btagging_num_B_eigenvars(tagWP); ++ivar) { + m_perjet_weight_bTagSF_eigen_B_up[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_B_" + std::to_string(ivar) + "__1up"); + m_perjet_weight_bTagSF_eigen_B_down[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_B_" + std::to_string(ivar) + "__1down"); + } + for (size_t ivar = 0; ivar < m_config->btagging_num_C_eigenvars(tagWP); ++ivar) { + m_perjet_weight_bTagSF_eigen_C_up[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_C_" + std::to_string(ivar) + "__1up"); + m_perjet_weight_bTagSF_eigen_C_down[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_C_" + std::to_string(ivar) + "__1down"); + } + for (size_t ivar = 0; ivar < m_config->btagging_num_Light_eigenvars(tagWP); ++ivar) { + m_perjet_weight_bTagSF_eigen_Light_up[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_Light_" + std::to_string(ivar) + "__1up"); + m_perjet_weight_bTagSF_eigen_Light_down[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_Light_" + std::to_string(ivar) + "__1down"); + } + for (const std::string& name : m_config->btagging_namedSysts(tagWP)) { + m_perjet_weight_bTagSF_named_up[tagWP][name][i] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_" + name + "__1up"); + m_perjet_weight_bTagSF_named_down[tagWP][name][i] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_" + name + "__1down"); + } } + } else { + m_jet_tagWeightBin[tagWP][i] = -2;// AT default value + if (jetPtr->isAvailable<int>("tagWeightBin_" + tagWP)) m_jet_tagWeightBin[tagWP][i] = jetPtr->auxdataConst<int>("tagWeightBin_" + tagWP); + } } - ///-- weights for matrix-method fakes estimate --/// - if (!m_config->isMC() && m_config->doFakesMMWeights()) { - top::TopFakesMMWeightCalculator const* fakesMMWeightCalc(nullptr); - if ( asg::ToolStore::contains<top::TopFakesMMWeightCalculator>("MMWeightCalculator") ) { - fakesMMWeightCalc = asg::ToolStore::get<top::TopFakesMMWeightCalculator>("MMWeightCalculator"); - } - else { - ATH_MSG_ERROR("EventSaverFlatNtuple::initialize" ); - throw std::runtime_error("Unable to retrieve top::TopFakesMMWeightCalculator tool"); + // for studies on high performance b-tagging + // the following are in DC14 + + if (m_config->bTagAlgo_MV2c10_used()) { + double mvx = -999; + if (btag) btag->MVx_discriminant("MV2c10", mvx); + m_jet_mv2c10[i] = mvx; + } + + m_jet_jvt[i] = -1; + if (jetPtr->isAvailable<float>("AnalysisTop_JVT")) { + m_jet_jvt[i] = jetPtr->auxdataConst<float>("AnalysisTop_JVT"); + } + + m_jet_fjvt[i] = -1; + if (jetPtr->isAvailable<float>("fJvt")){ + m_jet_fjvt[i] = jetPtr->auxdataConst<float>("fJvt"); + } + m_jet_passfjvt[i] = -1; + if (jetPtr->isAvailable<char>("AnalysisTop_fJVTdecision")){ + m_jet_passfjvt[i] = jetPtr->getAttribute<char>("AnalysisTop_fJVTdecision"); + } + + ++i; + } + // loop over selected DL1 algos and fill all calo jet b-tagging information + // the accessor uses decoration created in TopSystematicObjectMaker/JetObjectCollectionMaker + // calculated by BtaggingSelectionTool + for (const std::string& algo : m_config->bTagAlgo_available()) { + std::vector<float>& m_jet_DLx_pick = m_jet_DLx.at(algo); + std::vector<float>& m_jet_DLx_pb_pick = m_jet_DLx_pb.at(algo); + std::vector<float>& m_jet_DLx_pc_pick = m_jet_DLx_pc.at(algo); + std::vector<float>& m_jet_DLx_pu_pick = m_jet_DLx_pu.at(algo); + const SG::AuxElement::ConstAccessor<float>& DLx_acc = DLx.at(algo); + i = 0; + for (const auto* const jetPtr : event.m_jets) { + m_jet_DLx_pick[i] = DLx_acc(*jetPtr); + + const xAOD::BTagging* btag(nullptr); + btag = jetPtr->btagging(); + if (btag) { + double pu = -999; + double pc = -999; + double pb = -999; + btag->pu(algo, pu); + btag->pc(algo, pc); + btag->pb(algo, pb); + m_jet_DLx_pb_pick[i] = pb; + m_jet_DLx_pc_pick[i] = pc; + m_jet_DLx_pu_pick[i] = pu; + } + ++i; + } + } + } + + // fail-JVT jets + // btagging info is removed since btagging calibration isn't available for fail-JVT jets + if (m_config->saveFailJVTJets()) { + unsigned int i(0); + m_failJvt_jet_pt.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_eta.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_phi.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_e.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_jvt.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_fjvt.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_passfjvt.resize(event.m_failJvt_jets.size()); + + // ghost tracks + // fail-JVT jet could still have some ghost tracks, so these variables are kept + if (m_config->useJetGhostTrack()) { + + m_failJvt_jet_ghostTrack_pt.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_ghostTrack_eta.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_ghostTrack_phi.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_ghostTrack_e.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_ghostTrack_d0.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_ghostTrack_z0.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_ghostTrack_qOverP.resize(event.m_failJvt_jets.size()); + } + + if (m_config->isMC()) { + m_failJvt_jet_truthflav.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_truthPartonLabel.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_isTrueHS.resize(event.m_failJvt_jets.size()); + m_failJvt_jet_HadronConeExclExtendedTruthLabelID.resize(event.m_failJvt_jets.size()); + } + + for (const auto* const jetPtr : event.m_failJvt_jets) { + m_failJvt_jet_pt[i] = jetPtr->pt(); + m_failJvt_jet_eta[i] = jetPtr->eta(); + m_failJvt_jet_phi[i] = jetPtr->phi(); + m_failJvt_jet_e[i] = jetPtr->e(); + if (m_config->isMC()) { + m_failJvt_jet_truthflav[i] = -99; + if (jetPtr->isAvailable<int>("HadronConeExclTruthLabelID")) { + jetPtr->getAttribute("HadronConeExclTruthLabelID", m_failJvt_jet_truthflav[i]); + } + m_failJvt_jet_truthPartonLabel[i] = -99; + if (jetPtr->isAvailable<int>("PartonTruthLabelID")) { + jetPtr->getAttribute("PartonTruthLabelID", m_failJvt_jet_truthPartonLabel[i]); + } + m_failJvt_jet_isTrueHS[i] = false; + if (jetPtr->isAvailable<char>("AnalysisTop_isHS")) { + jetPtr->getAttribute("AnalysisTop_isHS", m_failJvt_jet_isTrueHS[i]); + } + m_failJvt_jet_HadronConeExclExtendedTruthLabelID[i] = -99; + if (jetPtr->isAvailable<int>("HadronConeExclExtendedTruthLabelID")) { + jetPtr->getAttribute("HadronConeExclExtendedTruthLabelID", m_failJvt_jet_HadronConeExclExtendedTruthLabelID[i]); + } + } + + if (m_config->useJetGhostTrack() && m_failJvt_jet_pt[i] > m_config->jetPtGhostTracks() && std::abs(m_failJvt_jet_eta[i])<m_config->jetEtaGhostTracks()) { + static const SG::AuxElement::Accessor< float > accD0("d0"); + static const SG::AuxElement::Accessor< float > accZ0("z0"); + static const SG::AuxElement::Accessor< float > accQOverP("qOverP"); + + std::vector<const xAOD::TrackParticle*> ghostTracks; + if(jetPtr->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack(event.m_hashValue),ghostTracks)) { + + const unsigned int nghostTracks = ghostTracks.size(); + + m_failJvt_jet_ghostTrack_pt[i].clear(); + m_failJvt_jet_ghostTrack_eta[i].clear(); + m_failJvt_jet_ghostTrack_phi[i].clear(); + m_failJvt_jet_ghostTrack_e[i].clear(); + m_failJvt_jet_ghostTrack_d0[i].clear(); + m_failJvt_jet_ghostTrack_z0[i].clear(); + m_failJvt_jet_ghostTrack_qOverP[i].clear(); + + m_failJvt_jet_ghostTrack_pt[i].reserve(nghostTracks); + m_failJvt_jet_ghostTrack_eta[i].reserve(nghostTracks); + m_failJvt_jet_ghostTrack_phi[i].reserve(nghostTracks); + m_failJvt_jet_ghostTrack_e[i].reserve(nghostTracks); + m_failJvt_jet_ghostTrack_d0[i].reserve(nghostTracks); + m_failJvt_jet_ghostTrack_z0[i].reserve(nghostTracks); + m_failJvt_jet_ghostTrack_qOverP[i].reserve(nghostTracks); + + for (unsigned int iGhost = 0; iGhost < nghostTracks; ++iGhost) { + + top::check(ghostTracks.at(iGhost), "Error in EventSaverFlatNtuple: Found jet with null pointer in ghost track vector."); + + if(ghostTracks.at(iGhost)->auxdataConst< char >("passPreORSelection") != 1) + {continue;} + + m_failJvt_jet_ghostTrack_pt[i].emplace_back(ghostTracks.at(iGhost)->pt()); + m_failJvt_jet_ghostTrack_eta[i].emplace_back(ghostTracks.at(iGhost)->eta()); + m_failJvt_jet_ghostTrack_phi[i].emplace_back(ghostTracks.at(iGhost)->phi()); + m_failJvt_jet_ghostTrack_e[i].emplace_back(ghostTracks.at(iGhost)->e()); + m_failJvt_jet_ghostTrack_d0[i].emplace_back(accD0(*ghostTracks.at(iGhost))); + m_failJvt_jet_ghostTrack_z0[i].emplace_back(accZ0(*ghostTracks.at(iGhost))); + m_failJvt_jet_ghostTrack_qOverP[i].emplace_back(accQOverP(*ghostTracks.at(iGhost))); } - for(const auto& branchName : m_extraBranches) {//loop on selections - for(const auto& conf : fakesMMWeightCalc->GetFakesMMConfigNames(branchName)) { - std::string MMweight_branch_name = "fakesMM_weight_" + branchName + "_" + conf; - std::string decorName = "MMWeight_"; decorName += branchName; decorName += "_"; decorName += conf; - if( event.m_info->isAvailable<float>(decorName.c_str()) ) { - m_fakesMM_weights[branchName][conf] = event.m_info->auxdataConst<float>(decorName.c_str()); - } - else {//if decoration is not present, it means this weight is not relevant for this channel - a hurtless weight=1. is then applied - m_fakesMM_weights[branchName][conf] = 1.; - } - } + + } + } + + m_failJvt_jet_jvt[i] = -1; + if (jetPtr->isAvailable<float>("AnalysisTop_JVT")) { + m_failJvt_jet_jvt[i] = jetPtr->auxdataConst<float>("AnalysisTop_JVT"); + } + + m_failJvt_jet_fjvt[i] = -1; + if (jetPtr->isAvailable<float>("fJvt")) { + m_failJvt_jet_fjvt[i] = jetPtr->auxdataConst<float>("fJvt"); + } + m_failJvt_jet_passfjvt[i] = -1; + if (jetPtr->isAvailable<char>("AnalysisTop_fJVTdecision")) { + m_failJvt_jet_passfjvt[i] = jetPtr->getAttribute<char>("AnalysisTop_fJVTdecision"); + } + + ++i; + } + }//ifSaveJVT + + // fail-FJVT jets + // btagging info removed as this is only looking at forward jets + if (m_config->getfJVTWP() != "None" && m_config->saveFailForwardJVTJets()) { + unsigned int i(0); + m_failFJvt_jet_pt.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_eta.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_phi.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_e.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_jvt.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_fjvt.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_passjvt.resize(event.m_failFJvt_jets.size()); + + // ghost tracks + // fail-FJVT jet could still have some ghost tracks, so these variables are kept + if (m_config->useJetGhostTrack()) { + + m_failFJvt_jet_ghostTrack_pt.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_ghostTrack_eta.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_ghostTrack_phi.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_ghostTrack_e.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_ghostTrack_d0.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_ghostTrack_z0.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_ghostTrack_qOverP.resize(event.m_failFJvt_jets.size()); + } + + if (m_config->isMC()) { + m_failFJvt_jet_truthflav.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_truthPartonLabel.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_isTrueHS.resize(event.m_failFJvt_jets.size()); + m_failFJvt_jet_HadronConeExclExtendedTruthLabelID.resize(event.m_failFJvt_jets.size()); + } + + for (const auto* const jetPtr : event.m_failFJvt_jets) { + m_failFJvt_jet_pt[i] = jetPtr->pt(); + m_failFJvt_jet_eta[i] = jetPtr->eta(); + m_failFJvt_jet_phi[i] = jetPtr->phi(); + m_failFJvt_jet_e[i] = jetPtr->e(); + if (m_config->isMC()) { + m_failFJvt_jet_truthflav[i] = -99; + if (jetPtr->isAvailable<int>("HadronConeExclTruthLabelID")) { + jetPtr->getAttribute("HadronConeExclTruthLabelID", m_failFJvt_jet_truthflav[i]); + } + m_failFJvt_jet_truthPartonLabel[i] = -99; + if (jetPtr->isAvailable<int>("PartonTruthLabelID")) { + jetPtr->getAttribute("PartonTruthLabelID", m_failFJvt_jet_truthPartonLabel[i]); + } + m_failFJvt_jet_isTrueHS[i] = false; + if (jetPtr->isAvailable<char>("AnalysisTop_isHS")) { + jetPtr->getAttribute("AnalysisTop_isHS", m_failFJvt_jet_isTrueHS[i]); + } + m_failFJvt_jet_HadronConeExclExtendedTruthLabelID[i] = -99; + if (jetPtr->isAvailable<int>("HadronConeExclExtendedTruthLabelID")) { + jetPtr->getAttribute("HadronConeExclExtendedTruthLabelID", m_failFJvt_jet_HadronConeExclExtendedTruthLabelID[i]); + } + } + + if (m_config->useJetGhostTrack() && m_failFJvt_jet_pt[i] > m_config->jetPtGhostTracks() && std::abs(m_failFJvt_jet_eta[i])<m_config->jetEtaGhostTracks()) { + static const SG::AuxElement::Accessor< float > accD0("d0"); + static const SG::AuxElement::Accessor< float > accZ0("z0"); + static const SG::AuxElement::Accessor< float > accQOverP("qOverP"); + + std::vector<const xAOD::TrackParticle*> ghostTracks; + if(jetPtr->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack(event.m_hashValue),ghostTracks)) { + + const unsigned int nghostTracks = ghostTracks.size(); + + m_failFJvt_jet_ghostTrack_pt[i].clear(); + m_failFJvt_jet_ghostTrack_eta[i].clear(); + m_failFJvt_jet_ghostTrack_phi[i].clear(); + m_failFJvt_jet_ghostTrack_e[i].clear(); + m_failFJvt_jet_ghostTrack_d0[i].clear(); + m_failFJvt_jet_ghostTrack_z0[i].clear(); + m_failFJvt_jet_ghostTrack_qOverP[i].clear(); + + m_failFJvt_jet_ghostTrack_pt[i].reserve(nghostTracks); + m_failFJvt_jet_ghostTrack_eta[i].reserve(nghostTracks); + m_failFJvt_jet_ghostTrack_phi[i].reserve(nghostTracks); + m_failFJvt_jet_ghostTrack_e[i].reserve(nghostTracks); + m_failFJvt_jet_ghostTrack_d0[i].reserve(nghostTracks); + m_failFJvt_jet_ghostTrack_z0[i].reserve(nghostTracks); + m_failFJvt_jet_ghostTrack_qOverP[i].reserve(nghostTracks); + + + for (unsigned int iGhost = 0; iGhost < nghostTracks; ++iGhost) { + top::check(ghostTracks.at(iGhost), "Error in EventSaverFlatNtuple: Found jet with null pointer in ghost track vector."); + + if(ghostTracks.at(iGhost)->auxdataConst< char >("passPreORSelection") != 1) + { continue;} + + + m_failFJvt_jet_ghostTrack_pt[i].emplace_back(ghostTracks.at(iGhost)->pt()); + m_failFJvt_jet_ghostTrack_eta[i].emplace_back(ghostTracks.at(iGhost)->eta()); + m_failFJvt_jet_ghostTrack_phi[i].emplace_back(ghostTracks.at(iGhost)->phi()); + m_failFJvt_jet_ghostTrack_e[i].emplace_back(ghostTracks.at(iGhost)->e()); + m_failFJvt_jet_ghostTrack_d0[i].emplace_back(accD0(*ghostTracks.at(iGhost))); + m_failFJvt_jet_ghostTrack_z0[i].emplace_back(accZ0(*ghostTracks.at(iGhost))); + m_failFJvt_jet_ghostTrack_qOverP[i].emplace_back(accQOverP(*ghostTracks.at(iGhost))); } + + + } + } + + m_failFJvt_jet_jvt[i] = -1; + if (jetPtr->isAvailable<float>("AnalysisTop_JVT")) { + m_failFJvt_jet_jvt[i] = jetPtr->auxdataConst<float>("AnalysisTop_JVT"); + } + m_failFJvt_jet_passjvt[i] = -1; + if (jetPtr->isAvailable<char>("passJVT")) { + m_failFJvt_jet_passjvt[i] = jetPtr->getAttribute<char>("passJVT"); + } + m_failFJvt_jet_fjvt[i] = -1; + if (jetPtr->isAvailable<float>("fJvt")) { + m_failFJvt_jet_fjvt[i] = jetPtr->auxdataConst<float>("fJvt"); + } + + ++i; + } + }//ifSaveFJVT + + + //large-R jets + if (m_config->useLargeRJets()) { + unsigned int i(0); + const unsigned int nLargeRJets = event.m_largeJets.size(); + m_ljet_pt.resize(nLargeRJets); + m_ljet_eta.resize(nLargeRJets); + m_ljet_phi.resize(nLargeRJets); + m_ljet_e.resize(nLargeRJets); + m_ljet_m.resize(nLargeRJets); + + for (const std::pair<std::string,std::string>& it : m_config->largeRJetSubstructureVariables()) { + m_ljet_substructure[it.first].resize(nLargeRJets); + } + + for (const std::string& taggerName : m_boostedJetTaggersNames) + m_ljet_isTagged[taggerName].resize(nLargeRJets); + if (m_config->isMC()) { + m_ljet_truthLabel.resize(nLargeRJets); + for (const std::string& taggerName : m_boostedJetTaggersNamesCalibrated) + m_ljet_tagSF[taggerName].resize(nLargeRJets); + } + + for (const auto* const jetPtr : event.m_largeJets) { + m_ljet_pt[i] = jetPtr->pt(); + m_ljet_eta[i] = jetPtr->eta(); + m_ljet_phi[i] = jetPtr->phi(); + m_ljet_e[i] = jetPtr->e(); + m_ljet_m[i] = jetPtr->m(); + + for (const std::pair<std::string,std::string>& it : m_config->largeRJetSubstructureVariables()) { + m_ljet_substructure[it.first][i] = jetPtr->isAvailable<float>(it.second) ? jetPtr->auxdata<float>(it.second) : -999; + } + + for (const std::string& taggerName : m_boostedJetTaggersNames) { + m_ljet_isTagged[taggerName][i] = jetPtr->getAttribute<char>("isTagged_" + taggerName); } - //event info - m_eventNumber = event.m_info -> eventNumber(); - m_runNumber = event.m_info -> runNumber(); - m_randomRunNumber = 0; - if (m_config->isMC() && m_config->doPileupReweighting()) { - if (event.m_info->isAvailable<unsigned int>("RandomRunNumber")) - m_randomRunNumber = event.m_info->auxdataConst<unsigned int>("RandomRunNumber"); - } - m_mcChannelNumber = 0; - - if (m_config->isMC()) - m_mcChannelNumber = event.m_info -> mcChannelNumber(); - - // (non-collision-)background flags - m_backgroundFlags = 0; - if (event.m_info->isAvailable<unsigned int>("backgroundFlags")) - m_backgroundFlags = event.m_info->auxdataConst<unsigned int>("backgroundFlags"); - - // hasBadMuon flag - m_hasBadMuon = 0; - if (m_config->useMuons() && event.m_info->isAvailable<char>("AnalysisTop_HASBADMUON")) - m_hasBadMuon = event.m_info->auxdataConst<char>("AnalysisTop_HASBADMUON"); - - // mu values (original and corrected by pileup reweighting tool) - m_mu_original = event.m_info->averageInteractionsPerCrossing(); - - // set these all to zero (maybe not the most sensible value...) - m_mu = 0; - - if (m_config->isMC()) - m_mu = m_mu_original; - if (!m_config->isMC()) { - // If we have the corrected mu value from pileup reweighting then save that - // instead of mu value in (d)xAOD. - if( event.m_info->isAvailable<float>("corrected_averageInteractionsPerCrossing") ) - m_mu = event.m_info->auxdataConst<float>("corrected_averageInteractionsPerCrossing"); - } - - ATH_MSG_DEBUG(" mu = "<<m_mu_original<<" -> "<<m_mu); - - //electrons - if (m_config->useElectrons()) { - unsigned int i(0); - unsigned int n_electrons = event.m_electrons.size(); - m_el_pt.resize(n_electrons); - m_el_eta.resize(n_electrons); - m_el_cl_eta.resize(n_electrons); - m_el_phi.resize(n_electrons); - m_el_e.resize(n_electrons); - m_el_charge.resize(n_electrons); - m_el_topoetcone20.resize(n_electrons); - m_el_ptvarcone20.resize(n_electrons); - m_el_isTight.resize(n_electrons); - m_el_CF.resize(n_electrons); - for( const auto& trigger : m_el_trigMatched ) - m_el_trigMatched[trigger.first].resize(n_electrons); - m_el_d0sig.resize(n_electrons); - m_el_delta_z0_sintheta.resize(n_electrons); - if (m_config->isMC()) { - m_el_true_type.resize(n_electrons); - m_el_true_origin.resize(n_electrons); - m_el_true_typebkg.resize(n_electrons); - m_el_true_originbkg.resize(n_electrons); + if (m_config->isMC()) { + m_ljet_truthLabel[i] = jetPtr->auxdata<int>("R10TruthLabel_R21Consolidated"); + for (const std::pair<std::string, std::string>& tagSF : m_config->boostedTaggerSFnames()) { + m_ljet_tagSF[tagSF.first][i] = jetPtr->auxdata<float>(tagSF.second); + } + } + + ++i; + } + } + + //track jets + if (m_config->useTrackJets()) { + unsigned int i(0); + m_tjet_pt.resize(event.m_trackJets.size()); + m_tjet_eta.resize(event.m_trackJets.size()); + m_tjet_phi.resize(event.m_trackJets.size()); + m_tjet_e.resize(event.m_trackJets.size()); + if (m_config->bTagAlgo_MV2c10_used_trkJet()) { + m_tjet_mv2c10.resize(event.m_trackJets.size()); + } + for (const std::string& algo : m_config->bTagAlgo_available_trkJet()) { + m_tjet_DLx[algo].resize(event.m_trackJets.size()); + m_tjet_DLx_pb[algo].resize(event.m_trackJets.size()); + m_tjet_DLx_pc[algo].resize(event.m_trackJets.size()); + m_tjet_DLx_pu[algo].resize(event.m_trackJets.size()); + } + for (auto& tagWP : m_config->bTagWP_available_trkJet()) { + if (tagWP.find("Continuous") == std::string::npos) { + m_tjet_isbtagged[tagWP].resize(event.m_trackJets.size()); + if (std::find(m_config->bTagWP_calibrated_trkJet().begin(), + m_config->bTagWP_calibrated_trkJet().end(), tagWP) == m_config->bTagWP_calibrated_trkJet().end()) continue; + if (m_config->isMC() && m_config->storePerJetBtagSFs()) { + m_perjet_weight_trackjet_bTagSF[tagWP].resize(event.m_trackJets.size()); + m_perjet_weight_trackjet_bTagSF_eigen_B_up[tagWP].resize(event.m_trackJets.size(), std::vector<float>(m_config->trkjet_btagging_num_B_eigenvars(tagWP))); + m_perjet_weight_trackjet_bTagSF_eigen_B_down[tagWP].resize(event.m_trackJets.size(), std::vector<float>(m_config->trkjet_btagging_num_B_eigenvars(tagWP))); + m_perjet_weight_trackjet_bTagSF_eigen_C_up[tagWP].resize(event.m_trackJets.size(), std::vector<float>(m_config->trkjet_btagging_num_C_eigenvars(tagWP))); + m_perjet_weight_trackjet_bTagSF_eigen_C_down[tagWP].resize(event.m_trackJets.size(), std::vector<float>(m_config->trkjet_btagging_num_C_eigenvars(tagWP))); + m_perjet_weight_trackjet_bTagSF_eigen_Light_up[tagWP].resize(event.m_trackJets.size(), std::vector<float>(m_config->trkjet_btagging_num_Light_eigenvars(tagWP))); + m_perjet_weight_trackjet_bTagSF_eigen_Light_down[tagWP].resize(event.m_trackJets.size(), std::vector<float>(m_config->trkjet_btagging_num_Light_eigenvars(tagWP))); + for (const std::string& name : m_config->trkjet_btagging_namedSysts(tagWP)) { + m_perjet_weight_trackjet_bTagSF_named_up[tagWP][name].resize(event.m_trackJets.size()); + m_perjet_weight_trackjet_bTagSF_named_down[tagWP][name].resize(event.m_trackJets.size()); } + } + } else m_tjet_tagWeightBin[tagWP].resize(event.m_trackJets.size()); + } + for (const auto* const jetPtr : event.m_trackJets) { + m_tjet_pt[i] = jetPtr->pt(); + m_tjet_eta[i] = jetPtr->eta(); + m_tjet_phi[i] = jetPtr->phi(); + m_tjet_e[i] = jetPtr->e(); + + if (m_config->bTagAlgo_MV2c10_used_trkJet()) { + const xAOD::BTagging* btag(nullptr); + btag = jetPtr->btagging(); + double mvx = -999; + if (btag) btag->MVx_discriminant("MV2c10", mvx); + m_tjet_mv2c10[i] = mvx; + } - for (const auto* const elPtr : event.m_electrons) { - m_el_pt[i] = elPtr->pt(); - m_el_eta[i] = elPtr->eta(); - m_el_cl_eta[i] = elPtr->caloCluster()->etaBE(2); - m_el_phi[i] = elPtr->phi(); - m_el_e[i] = elPtr->e(); - m_el_charge[i] = elPtr->charge(); - elPtr->isolationValue( m_el_topoetcone20[i] , xAOD::Iso::topoetcone20 ); - elPtr->isolationValue( m_el_ptvarcone20[i] , xAOD::Iso::ptvarcone20 ); - if (event.m_isLoose) { - if (elPtr->isAvailable<char>("passPreORSelection")) { - m_el_isTight[i] = elPtr->auxdataConst<char>("passPreORSelection"); - } - } - if (elPtr->isAvailable<char>("passChargeID")) - m_el_CF[i] = elPtr->auxdataConst<char>("passChargeID"); - for( const auto& trigger : m_el_trigMatched ){ - std::string trig = "TRIGMATCH_"+trigger.first; - m_el_trigMatched[trigger.first][i] = elPtr->auxdataConst<char>(trig); - } - if( elPtr->isAvailable<float>("d0sig") ) - m_el_d0sig[i] = elPtr->auxdataConst<float>("d0sig"); - if( elPtr->isAvailable<float>("delta_z0_sintheta") ) - m_el_delta_z0_sintheta[i] = elPtr->auxdataConst<float>("delta_z0_sintheta"); - - //retrieve the truth-matching variables from MCTruthClassifier - if (m_config->isMC()) { - m_el_true_type[i] = 0; - m_el_true_origin[i] = 0; - m_el_true_typebkg[i] = 0; - m_el_true_originbkg[i] = 0; - static SG::AuxElement::Accessor<int> typeel("truthType"); - static SG::AuxElement::Accessor<int> origel("truthOrigin"); - static SG::AuxElement::Accessor<int> typebkgel("bkgTruthType"); - static SG::AuxElement::Accessor<int> origbkgel("bkgTruthOrigin"); - if (typeel.isAvailable(*elPtr)) m_el_true_type[i] = typeel(*elPtr); - if (origel.isAvailable(*elPtr)) m_el_true_origin[i] = origel(*elPtr); - if (typebkgel.isAvailable(*elPtr)) m_el_true_typebkg[i] = typebkgel(*elPtr); - if (origbkgel.isAvailable(*elPtr)) m_el_true_originbkg[i] = origbkgel(*elPtr); - } - ++i; + for (auto& tagWP : m_config->bTagWP_available_trkJet()) { + if (tagWP.find("Continuous") == std::string::npos) { + m_tjet_isbtagged[tagWP][i] = false; + if (jetPtr->isAvailable<char>("isbtagged_" + tagWP)) m_tjet_isbtagged[tagWP][i] = jetPtr->auxdataConst<char>("isbtagged_" + tagWP); + if (m_config->isMC() && m_config->storePerJetBtagSFs()) { + if (std::find(m_config->bTagWP_calibrated_trkJet().begin(), + m_config->bTagWP_calibrated_trkJet().end(), tagWP) == m_config->bTagWP_calibrated_trkJet().end()) continue; + m_perjet_weight_trackjet_bTagSF[tagWP][i] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_nom"); + for (size_t ivar = 0; ivar < m_config->trkjet_btagging_num_B_eigenvars(tagWP); ++ivar) { + m_perjet_weight_trackjet_bTagSF_eigen_B_up[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_B_" + std::to_string(ivar) + "__1up"); + m_perjet_weight_trackjet_bTagSF_eigen_B_down[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_B_" + std::to_string(ivar) + "__1down"); + } + for (size_t ivar = 0; ivar < m_config->trkjet_btagging_num_C_eigenvars(tagWP); ++ivar) { + m_perjet_weight_trackjet_bTagSF_eigen_C_up[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_C_" + std::to_string(ivar) + "__1up"); + m_perjet_weight_trackjet_bTagSF_eigen_C_down[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_C_" + std::to_string(ivar) + "__1down"); + } + for (size_t ivar = 0; ivar < m_config->trkjet_btagging_num_Light_eigenvars(tagWP); ++ivar) { + m_perjet_weight_trackjet_bTagSF_eigen_Light_up[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_Light_" + std::to_string(ivar) + "__1up"); + m_perjet_weight_trackjet_bTagSF_eigen_Light_down[tagWP][i][ivar] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_FT_EFF_Eigen_Light_" + std::to_string(ivar) + "__1down"); + } + for (const std::string& name : m_config->trkjet_btagging_namedSysts(tagWP)) { + m_perjet_weight_trackjet_bTagSF_named_up[tagWP][name][i] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_" + name + "__1up"); + m_perjet_weight_trackjet_bTagSF_named_down[tagWP][name][i] = jetPtr->auxdataConst<float>("btag_SF_" + tagWP + "_" + name + "__1down"); + } } + } else { + m_tjet_tagWeightBin[tagWP][i] = -2;// AT default value + if (jetPtr->isAvailable<int>("tagWeightBin_" + tagWP)) m_tjet_tagWeightBin[tagWP][i] = jetPtr->auxdataConst<int>("tagWeightBin_" + tagWP); + } } + ++i; + } - //muons - if (m_config->useMuons()) { - unsigned int i(0); - unsigned int n_muons = event.m_muons.size(); - m_mu_pt.resize(n_muons); - m_mu_eta.resize(n_muons); - m_mu_phi.resize(n_muons); - m_mu_e.resize(n_muons); - m_mu_charge.resize(n_muons); - m_mu_topoetcone20.resize(n_muons); - m_mu_ptvarcone30.resize(n_muons); - m_mu_isTight.resize(n_muons); - for( const auto& trigger : m_mu_trigMatched ) - m_mu_trigMatched[trigger.first].resize(n_muons); - m_mu_d0sig.resize(n_muons); - m_mu_delta_z0_sintheta.resize(n_muons); - if (m_config->isMC()) { - m_mu_true_type.resize(n_muons); - m_mu_true_origin.resize(n_muons); - } - - for (const auto* const muPtr : event.m_muons) { - m_mu_pt[i] = muPtr->pt(); - m_mu_eta[i] = muPtr->eta(); - m_mu_phi[i] = muPtr->phi(); - m_mu_e[i] = muPtr->e(); - m_mu_charge[i] = muPtr->charge(); - muPtr->isolation( m_mu_topoetcone20[i] , xAOD::Iso::topoetcone20 ); - muPtr->isolation( m_mu_ptvarcone30[i] , xAOD::Iso::ptvarcone30 ); - if (event.m_isLoose) { - if (muPtr->isAvailable<char>("passPreORSelection")) { - m_mu_isTight[i] = muPtr->auxdataConst<char>("passPreORSelection"); - } - } - for( const auto& trigger : m_mu_trigMatched ){ - std::string trig = "TRIGMATCH_"+trigger.first; - m_mu_trigMatched[trigger.first][i] = muPtr->auxdataConst<char>(trig); - } - if( muPtr->isAvailable<float>("d0sig") ) - m_mu_d0sig[i] = muPtr->auxdataConst<float>("d0sig"); - if( muPtr->isAvailable<float>("delta_z0_sintheta") ) - m_mu_delta_z0_sintheta[i] = muPtr->auxdataConst<float>("delta_z0_sintheta"); - - //retrieve the truth-matching variables from MCTruthClassifier - if (m_config->isMC()) { - static SG::AuxElement::Accessor<int> acc_mctt("truthType"); - static SG::AuxElement::Accessor<int> acc_mcto("truthOrigin"); - m_mu_true_type[i]=0; - m_mu_true_origin[i]=0; - const xAOD::TrackParticle* mutrack = muPtr->primaryTrackParticle(); - if (mutrack!=nullptr) { - if (acc_mctt.isAvailable(*mutrack)) m_mu_true_type[i] = acc_mctt(*mutrack); - if (acc_mcto.isAvailable(*mutrack)) m_mu_true_origin[i] = acc_mcto(*mutrack); - } - } - ++i; - } + // loop over selected DL1 algos and fill all track jet b-tagging information + // the accessor uses decoration created in TopSystematicObjectMaker/JetObjectCollectionMaker + // calculated by BtaggingSelectionTool + for (const std::string& algo : m_config->bTagAlgo_available_trkJet()) { + std::vector<float>& m_tjet_DLx_pick = m_tjet_DLx.at(algo); + std::vector<float>& m_tjet_DLx_pb_pick = m_tjet_DLx_pb.at(algo); + std::vector<float>& m_tjet_DLx_pc_pick = m_tjet_DLx_pc.at(algo); + std::vector<float>& m_tjet_DLx_pu_pick = m_tjet_DLx_pu.at(algo); + const SG::AuxElement::ConstAccessor<float>& DLx_acc = DLx.at(algo); + i = 0; + for (const auto* const jetPtr : event.m_trackJets) { + m_tjet_DLx_pick[i] = DLx_acc(*jetPtr); + + const xAOD::BTagging* btag(nullptr); + btag = jetPtr->btagging(); + if (btag) { + double pu = -999; + double pc = -999; + double pb = -999; + btag->pu(algo, pu); + btag->pc(algo, pc); + btag->pb(algo, pb); + m_tjet_DLx_pb_pick[i] = pb; + m_tjet_DLx_pc_pick[i] = pc; + m_tjet_DLx_pu_pick[i] = pu; + } + ++i; } + } + } - //photons - if (m_config->usePhotons()) { - unsigned int i(0); - m_ph_pt.resize(event.m_photons.size()); - m_ph_eta.resize(event.m_photons.size()); - m_ph_phi.resize(event.m_photons.size()); - m_ph_e.resize(event.m_photons.size()); - m_ph_iso.resize(event.m_photons.size()); - for (const auto* const phPtr : event.m_photons) { - m_ph_pt[i] = phPtr->pt(); - m_ph_eta[i] = phPtr->eta(); - m_ph_phi[i] = phPtr->phi(); - m_ph_e[i] = phPtr->e(); - - m_ph_iso[i] = 0.; - if (phPtr->isAvailable<float>("ptvarcone20")) - m_ph_iso[i] = phPtr->auxdata<float>("ptvarcone20"); - - ++i; - } - } + if (m_makeRCJets) { + // re-clustered jet substructure + static const SG::AuxElement::ConstAccessor<float> RCSplit12("Split12"); + static const SG::AuxElement::ConstAccessor<float> RCSplit23("Split23"); + + + + // re-clustered jet substructure from clusters + static const SG::AuxElement::ConstAccessor<float> Tau21_clstr("Tau21_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau32_clstr("Tau32_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau3_clstr("Tau3_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau2_clstr("Tau2_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau1_clstr("Tau1_clstr"); + static const SG::AuxElement::ConstAccessor<float> D2_clstr("D2_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF1_clstr("ECF1_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF2_clstr("ECF2_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF3_clstr("ECF3_clstr"); + static const SG::AuxElement::ConstAccessor<float> d12_clstr("d12_clstr"); + static const SG::AuxElement::ConstAccessor<float> d23_clstr("d23_clstr"); + static const SG::AuxElement::ConstAccessor<float> Qw_clstr("Qw_clstr"); + static const SG::AuxElement::ConstAccessor<float> nconstituent_clstr("nconstituent_clstr"); + + static const SG::AuxElement::ConstAccessor<float> gECF332_clstr("gECF332_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF461_clstr("gECF461_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF322_clstr("gECF322_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF331_clstr("gECF331_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF422_clstr("gECF422_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF441_clstr("gECF441_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF212_clstr("gECF212_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF321_clstr("gECF321_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF311_clstr("gECF311_clstr"); + static const SG::AuxElement::ConstAccessor<float> L1_clstr("L1_clstr"); + static const SG::AuxElement::ConstAccessor<float> L2_clstr("L2_clstr"); + static const SG::AuxElement::ConstAccessor<float> L3_clstr("L3_clstr"); + static const SG::AuxElement::ConstAccessor<float> L4_clstr("L4_clstr"); + static const SG::AuxElement::ConstAccessor<float> L5_clstr("L5_clstr"); + // store also the jet that is rebuilt to calculate the JSS + static const SG::AuxElement::ConstAccessor<float> RRCJet_pt("RRCJet_pt"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_eta("RRCJet_eta"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_phi("RRCJet_phi"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_e("RRCJet_e"); + + // Initialize the vectors to be saved as branches + unsigned int sizeOfRCjets(event.m_RCJets.size()); + + m_rcjet_pt.clear(); + m_rcjet_eta.clear(); + m_rcjet_phi.clear(); + m_rcjet_e.clear(); + m_rcjet_d12.clear(); + m_rcjet_d23.clear(); + m_rcjetsub_pt.clear(); + m_rcjetsub_eta.clear(); + m_rcjetsub_phi.clear(); + m_rcjetsub_e.clear(); + if (m_config->bTagAlgo_MV2c10_used()) { + m_rcjetsub_mv2c10.clear(); + } + m_rrcjet_pt.clear(); + m_rrcjet_eta.clear(); + m_rrcjet_phi.clear(); + m_rrcjet_e.clear(); + + + m_rcjet_tau32_clstr.clear(); + m_rcjet_tau21_clstr.clear(); + m_rcjet_tau3_clstr.clear(); + m_rcjet_tau2_clstr.clear(); + m_rcjet_tau1_clstr.clear(); + + m_rcjet_D2_clstr.clear(); + m_rcjet_ECF1_clstr.clear(); + m_rcjet_ECF2_clstr.clear(); + m_rcjet_ECF3_clstr.clear(); + + m_rcjet_d12_clstr.clear(); + m_rcjet_d23_clstr.clear(); + m_rcjet_Qw_clstr.clear(); + m_rcjet_nconstituent_clstr.clear(); + m_rcjet_gECF332_clstr.clear(); + m_rcjet_gECF461_clstr.clear(); + m_rcjet_gECF322_clstr.clear(); + m_rcjet_gECF331_clstr.clear(); + m_rcjet_gECF422_clstr.clear(); + m_rcjet_gECF441_clstr.clear(); + m_rcjet_gECF212_clstr.clear(); + m_rcjet_gECF321_clstr.clear(); + m_rcjet_gECF311_clstr.clear(); + m_rcjet_L1_clstr.clear(); + m_rcjet_L2_clstr.clear(); + m_rcjet_L3_clstr.clear(); + m_rcjet_L4_clstr.clear(); + m_rcjet_L5_clstr.clear(); + + m_rcjet_pt.resize(sizeOfRCjets, -999.); + m_rcjet_eta.resize(sizeOfRCjets, -999.); + m_rcjet_phi.resize(sizeOfRCjets, -999.); + m_rcjet_e.resize(sizeOfRCjets, -999.); + m_rcjet_d12.resize(sizeOfRCjets, -999.); + m_rcjet_d23.resize(sizeOfRCjets, -999.); + m_rcjetsub_pt.resize(sizeOfRCjets, std::vector<float>()); + m_rcjetsub_eta.resize(sizeOfRCjets, std::vector<float>()); + m_rcjetsub_phi.resize(sizeOfRCjets, std::vector<float>()); + m_rcjetsub_e.resize(sizeOfRCjets, std::vector<float>()); + if (m_config->bTagAlgo_MV2c10_used()) { + m_rcjetsub_mv2c10.resize(sizeOfRCjets, std::vector<float>()); + } + if (m_useRCJSS || m_useRCAdditionalJSS) { + m_rrcjet_pt.resize(sizeOfRCjets, -999.); + m_rrcjet_eta.resize(sizeOfRCjets, -999.); + m_rrcjet_phi.resize(sizeOfRCjets, -999.); + m_rrcjet_e.resize(sizeOfRCjets, -999.); + } + if (m_useRCJSS) { + m_rcjet_tau32_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_tau21_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_tau1_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_tau2_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_tau3_clstr.resize(sizeOfRCjets, -999.); + + m_rcjet_d12_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_d23_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_Qw_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_nconstituent_clstr.resize(sizeOfRCjets, -999.); + + m_rcjet_D2_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_ECF1_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_ECF2_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_ECF3_clstr.resize(sizeOfRCjets, -999.); + } + if (m_useRCAdditionalJSS) { + + m_rcjet_gECF332_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF461_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF322_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF331_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF422_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF441_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF212_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF321_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF311_clstr.resize(sizeOfRCjets, -999.); + + m_rcjet_L1_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_L2_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_L3_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_L4_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_L5_clstr.resize(sizeOfRCjets, -999.); + } + unsigned int i = 0; + for (auto jet_itr = event.m_RCJets.begin(); jet_itr != event.m_RCJets.end(); ++jet_itr) { + const xAOD::Jet* rc_jet = *jet_itr; - //taus - if (m_config->useTaus()) { - unsigned int i(0); - m_tau_pt.resize(event.m_tauJets.size()); - m_tau_eta.resize(event.m_tauJets.size()); - m_tau_phi.resize(event.m_tauJets.size()); - m_tau_charge.resize(event.m_tauJets.size()); - for (const auto* const tauPtr : event.m_tauJets) { - m_tau_pt[i] = tauPtr->pt(); - m_tau_eta[i] = tauPtr->eta(); - m_tau_phi[i] = tauPtr->phi(); - m_tau_charge[i] = tauPtr->charge(); - ++i; - } - } - //jets - if (m_config->useJets()) { - unsigned int i(0); - m_jet_pt.resize(event.m_jets.size()); - m_jet_eta.resize(event.m_jets.size()); - m_jet_phi.resize(event.m_jets.size()); - m_jet_e.resize(event.m_jets.size()); - m_jet_mv2c00.resize(event.m_jets.size()); - m_jet_mv2c10.resize(event.m_jets.size()); - m_jet_mv2c20.resize(event.m_jets.size()); - m_jet_ip3dsv1.resize(event.m_jets.size()); - m_jet_jvt.resize(event.m_jets.size()); - m_jet_passfjvt.resize(event.m_jets.size()); - if (m_config->isMC()) { - m_jet_truthflav.resize(event.m_jets.size()); - m_jet_truthPartonLabel.resize(event.m_jets.size()); - m_jet_isTrueHS.resize(event.m_jets.size()); - } - for( auto& tagWP : m_config -> bTagWP_available()){ - if (tagWP!= "Continuous") m_jet_isbtagged[tagWP].resize(event.m_jets.size()); - else m_jet_tagWeightBin.resize(event.m_jets.size()); - } - for (const auto* const jetPtr : event.m_jets) { - m_jet_pt[i] = jetPtr->pt(); - m_jet_eta[i] = jetPtr->eta(); - m_jet_phi[i] = jetPtr->phi(); - m_jet_e[i] = jetPtr->e(); - m_jet_ip3dsv1[i] = jetPtr->btagging()->SV1plusIP3D_discriminant(); - if (m_config->isMC()) { - m_jet_truthflav[i] = -99; - if(jetPtr->isAvailable<int>("HadronConeExclTruthLabelID")){ - jetPtr->getAttribute("HadronConeExclTruthLabelID", m_jet_truthflav[i]); - } - m_jet_truthPartonLabel[i] = -99; - if(jetPtr->isAvailable<int>("PartonTruthLabelID")){ - jetPtr->getAttribute("PartonTruthLabelID", m_jet_truthPartonLabel[i]); - } - m_jet_isTrueHS[i] = false; - if(jetPtr->isAvailable<char>("AnalysisTop_isHS")){ - jetPtr->getAttribute("AnalysisTop_isHS", m_jet_isTrueHS[i]); - } - } - for( auto& tagWP : m_config -> bTagWP_available()){ - if (tagWP!= "Continuous") { - m_jet_isbtagged[tagWP][i] = false; - if(jetPtr->isAvailable<char>("isbtagged_"+tagWP)) - m_jet_isbtagged[tagWP][i] = jetPtr->auxdataConst<char>("isbtagged_"+tagWP); - } - else { - m_jet_tagWeightBin[i] = -2;// AT default value - if(jetPtr->isAvailable<int>("tagWeightBin")) - m_jet_tagWeightBin[i] = jetPtr->auxdataConst<int>("tagWeightBin"); - } - } + m_rcjet_pt[i] = rc_jet->pt(); + m_rcjet_eta[i] = rc_jet->eta(); + m_rcjet_phi[i] = rc_jet->phi(); + m_rcjet_e[i] = rc_jet->e(); - // for studies on high performance b-tagging - // the following are in DC14 - double mvx = -999; - jetPtr->btagging()->MVx_discriminant("MV2c00", mvx); - m_jet_mv2c00[i] = mvx; - mvx = -999; - jetPtr->btagging()->MVx_discriminant("MV2c10", mvx); - m_jet_mv2c10[i] = mvx; - mvx = -999; - jetPtr->btagging()->MVx_discriminant("MV2c20", mvx); - m_jet_mv2c20[i] = mvx; - - m_jet_jvt[i] = -1; - if (jetPtr->isAvailable<float>("AnalysisTop_JVT")) { - m_jet_jvt[i] = jetPtr->auxdataConst<float>("AnalysisTop_JVT"); - } - m_jet_passfjvt[i] = -1; - if (jetPtr->isAvailable<char>("passFJVT")) { - m_jet_passfjvt[i] = jetPtr->getAttribute<char>("passFJVT"); - } + m_rcjet_d12[i] = (RCSplit12.isAvailable(*rc_jet)) ? RCSplit12(*rc_jet) : -999.; + m_rcjet_d23[i] = (RCSplit23.isAvailable(*rc_jet)) ? RCSplit23(*rc_jet) : -999.; - ++i; - } + if (m_useRCJSS || m_useRCAdditionalJSS) { + m_rrcjet_pt[i] = (RRCJet_pt.isAvailable(*rc_jet)) ? RRCJet_pt(*rc_jet) : -999.; + m_rrcjet_eta[i] = (RRCJet_eta.isAvailable(*rc_jet)) ? RRCJet_eta(*rc_jet) : -999.; + m_rrcjet_phi[i] = (RRCJet_phi.isAvailable(*rc_jet)) ? RRCJet_phi(*rc_jet) : -999.; + m_rrcjet_e[i] = (RRCJet_e.isAvailable(*rc_jet)) ? RRCJet_e(*rc_jet) : -999.; } + if (m_useRCJSS) { + m_rcjet_tau32_clstr[i] = (Tau32_clstr.isAvailable(*rc_jet)) ? Tau32_clstr(*rc_jet) : -999.; + m_rcjet_tau21_clstr[i] = (Tau21_clstr.isAvailable(*rc_jet)) ? Tau21_clstr(*rc_jet) : -999.; + m_rcjet_tau3_clstr[i] = (Tau3_clstr.isAvailable(*rc_jet)) ? Tau3_clstr(*rc_jet) : -999.; + m_rcjet_tau2_clstr[i] = (Tau2_clstr.isAvailable(*rc_jet)) ? Tau2_clstr(*rc_jet) : -999.; + m_rcjet_tau1_clstr[i] = (Tau1_clstr.isAvailable(*rc_jet)) ? Tau1_clstr(*rc_jet) : -999.; + + m_rcjet_d12_clstr[i] = (d12_clstr.isAvailable(*rc_jet)) ? d12_clstr(*rc_jet) : -999.; + m_rcjet_d23_clstr[i] = (d23_clstr.isAvailable(*rc_jet)) ? d23_clstr(*rc_jet) : -999.; + m_rcjet_Qw_clstr[i] = (Qw_clstr.isAvailable(*rc_jet)) ? Qw_clstr(*rc_jet) : -999.; + m_rcjet_nconstituent_clstr[i] = (nconstituent_clstr.isAvailable(*rc_jet)) ? nconstituent_clstr(*rc_jet) : -999.; + + m_rcjet_D2_clstr[i] = (D2_clstr.isAvailable(*rc_jet)) ? D2_clstr(*rc_jet) : -999.; + m_rcjet_ECF1_clstr[i] = (ECF1_clstr.isAvailable(*rc_jet)) ? ECF1_clstr(*rc_jet) : -999.; + m_rcjet_ECF2_clstr[i] = (ECF2_clstr.isAvailable(*rc_jet)) ? ECF2_clstr(*rc_jet) : -999.; + m_rcjet_ECF3_clstr[i] = (ECF3_clstr.isAvailable(*rc_jet)) ? ECF3_clstr(*rc_jet) : -999.; - //large-R jets - if (m_config->useLargeRJets()) { - unsigned int i(0); - m_ljet_pt.resize(event.m_largeJets.size()); - m_ljet_eta.resize(event.m_largeJets.size()); - m_ljet_phi.resize(event.m_largeJets.size()); - m_ljet_e.resize(event.m_largeJets.size()); - m_ljet_m.resize(event.m_largeJets.size()); - m_ljet_sd12.resize(event.m_largeJets.size()); - for (const auto* const jetPtr : event.m_largeJets) { - m_ljet_pt[i] = jetPtr->pt(); - m_ljet_eta[i] = jetPtr->eta(); - m_ljet_phi[i] = jetPtr->phi(); - m_ljet_e[i] = jetPtr->e(); - m_ljet_m[i] = jetPtr->m(); - m_ljet_sd12[i] = 0; - float Split12 = 0; - jetPtr->getAttribute("Split12", Split12); - m_ljet_sd12[i] = Split12; - - ++i; - } } - - //track jets - if (m_config->useTrackJets()) { - unsigned int i(0); - m_tjet_pt.resize(event.m_trackJets.size()); - m_tjet_eta.resize(event.m_trackJets.size()); - m_tjet_phi.resize(event.m_trackJets.size()); - m_tjet_e.resize(event.m_trackJets.size()); - m_tjet_mv2c00.resize(event.m_trackJets.size()); - m_tjet_mv2c10.resize(event.m_trackJets.size()); - m_tjet_mv2c20.resize(event.m_trackJets.size()); - for( auto& tagWP : m_config -> bTagWP_available_trkJet()) { - if (tagWP!= "Continuous") m_tjet_isbtagged[tagWP].resize(event.m_trackJets.size()); - else m_tjet_tagWeightBin.resize(event.m_trackJets.size()); - } - for (const auto* const jetPtr : event.m_trackJets) { - m_tjet_pt[i] = jetPtr->pt(); - m_tjet_eta[i] = jetPtr->eta(); - m_tjet_phi[i] = jetPtr->phi(); - m_tjet_e[i] = jetPtr->e(); - - double mvx = -999; - jetPtr->btagging()->MVx_discriminant("MV2c00", mvx); - m_tjet_mv2c00[i] = mvx; - mvx = -999; - jetPtr->btagging()->MVx_discriminant("MV2c10", mvx); - m_tjet_mv2c10[i] = mvx; - mvx = -999; - jetPtr->btagging()->MVx_discriminant("MV2c20", mvx); - m_tjet_mv2c20[i] = mvx; - for( auto& tagWP : m_config -> bTagWP_available_trkJet()){ - if (tagWP!= "Continuous") { - m_tjet_isbtagged[tagWP][i] = false; - if(jetPtr->isAvailable<char>("isbtagged_"+tagWP)) - m_tjet_isbtagged[tagWP][i] = jetPtr->auxdataConst<char>("isbtagged_"+tagWP); - } - else { - m_tjet_tagWeightBin[i] = -2;// AT default value - if(jetPtr->isAvailable<int>("tagWeightBin")) - m_tjet_tagWeightBin[i] = jetPtr->auxdataConst<int>("tagWeightBin"); - } - } - ++i; - } + if (m_useRCAdditionalJSS) { + + m_rcjet_gECF332_clstr[i] = (gECF332_clstr.isAvailable(*rc_jet)) ? gECF332_clstr(*rc_jet) : -999.; + m_rcjet_gECF461_clstr[i] = (gECF461_clstr.isAvailable(*rc_jet)) ? gECF461_clstr(*rc_jet) : -999.; + m_rcjet_gECF322_clstr[i] = (gECF322_clstr.isAvailable(*rc_jet)) ? gECF322_clstr(*rc_jet) : -999.; + m_rcjet_gECF331_clstr[i] = (gECF331_clstr.isAvailable(*rc_jet)) ? gECF331_clstr(*rc_jet) : -999.; + m_rcjet_gECF422_clstr[i] = (gECF422_clstr.isAvailable(*rc_jet)) ? gECF422_clstr(*rc_jet) : -999.; + m_rcjet_gECF441_clstr[i] = (gECF441_clstr.isAvailable(*rc_jet)) ? gECF441_clstr(*rc_jet) : -999.; + m_rcjet_gECF212_clstr[i] = (gECF212_clstr.isAvailable(*rc_jet)) ? gECF212_clstr(*rc_jet) : -999.; + m_rcjet_gECF321_clstr[i] = (gECF321_clstr.isAvailable(*rc_jet)) ? gECF321_clstr(*rc_jet) : -999.; + m_rcjet_gECF311_clstr[i] = (gECF311_clstr.isAvailable(*rc_jet)) ? gECF311_clstr(*rc_jet) : -999.; + + m_rcjet_L1_clstr[i] = (L1_clstr.isAvailable(*rc_jet)) ? L1_clstr(*rc_jet) : -999.; + m_rcjet_L2_clstr[i] = (L2_clstr.isAvailable(*rc_jet)) ? L2_clstr(*rc_jet) : -999.; + m_rcjet_L3_clstr[i] = (L3_clstr.isAvailable(*rc_jet)) ? L3_clstr(*rc_jet) : -999.; + m_rcjet_L4_clstr[i] = (L4_clstr.isAvailable(*rc_jet)) ? L4_clstr(*rc_jet) : -999.; + m_rcjet_L5_clstr[i] = (L5_clstr.isAvailable(*rc_jet)) ? L5_clstr(*rc_jet) : -999.; } - if (m_makeRCJets){ - // Execute the re-clustering code - // - make jet container of small-r jets in the event, put it in TStore, do re-clustering - top::check(m_rc->execute(event),"Failed to execute RCJetMC15 container"); + // loop over subjets + m_rcjetsub_pt[i].clear(); // clear the vector size (otherwise it grows out of control!) + m_rcjetsub_eta[i].clear(); + m_rcjetsub_phi[i].clear(); + m_rcjetsub_e[i].clear(); + if (m_config->bTagAlgo_MV2c10_used()) { + m_rcjetsub_mv2c10[i].clear(); + } - // Get the name of the container of re-clustered jets in TStore - m_RCJetContainer = m_rc->rcjetContainerName(event.m_hashValue,event.m_isLoose); + const xAOD::Jet* subjet(nullptr); + const xAOD::BTagging* btag(nullptr); + for (auto rc_jet_subjet : rc_jet->getConstituents()) { + subjet = static_cast<const xAOD::Jet*>(rc_jet_subjet->rawConstituent()); - // -- Retrieve the re-clustered jets from TStore & save good re-clustered jets -- // - const xAOD::JetContainer* rc_jets(nullptr); - top::check(evtStore()->retrieve(rc_jets,m_RCJetContainer),"Failed to retrieve RC JetContainer"); + if (m_config->bTagAlgo_MV2c10_used()) { + btag = subjet->btagging(); - // re-clustered jet substructure - static SG::AuxElement::ConstAccessor<float> RCSplit12("Split12"); - static SG::AuxElement::ConstAccessor<float> RCSplit23("Split23"); + double mvx10(-999.); // b-tagging mv2c10 - // Initialize the vectors to be saved as branches - unsigned int sizeOfRCjets(rc_jets->size()); + if (btag) { + btag->MVx_discriminant("MV2c10", mvx10); + } else { + mvx10 = -999.; + } + m_rcjetsub_mv2c10[i].push_back(mvx10); + } - m_rcjet_pt.resize(sizeOfRCjets,-999.); - m_rcjet_eta.resize(sizeOfRCjets,-999.); - m_rcjet_phi.resize(sizeOfRCjets,-999.); - m_rcjet_e.resize(sizeOfRCjets,-999.); - m_rcjet_d12.resize(sizeOfRCjets,-999.); - m_rcjet_d23.resize(sizeOfRCjets,-999.); - m_rcjetsub_pt.resize(sizeOfRCjets, std::vector<float>()); - m_rcjetsub_eta.resize(sizeOfRCjets, std::vector<float>()); - m_rcjetsub_phi.resize(sizeOfRCjets, std::vector<float>()); - m_rcjetsub_e.resize(sizeOfRCjets, std::vector<float>()); - m_rcjetsub_mv2c10.resize(sizeOfRCjets, std::vector<float>()); + m_rcjetsub_pt[i].push_back(subjet->pt()); + m_rcjetsub_eta[i].push_back(subjet->eta()); + m_rcjetsub_phi[i].push_back(subjet->phi()); + m_rcjetsub_e[i].push_back(subjet->e()); + } // end for-loop over subjets + ++i; + } // end for-loop over re-clustered jets + } // end if make rcjets + // end re-clustered jets + + /**********************************/ + // VarRC jets + if (m_makeVarRCJets) { + std::string VarRC = "vrcjet"; + for (auto& rho : m_VarRCJetRho) { + for (auto& mass_scale : m_VarRCJetMassScale) { + std::replace(rho.begin(), rho.end(), '.', '_'); + std::string name = rho + mass_scale; + + // re-clustered jet substructure + static const SG::AuxElement::ConstAccessor<float> VarRCSplit12("Split12"); + static const SG::AuxElement::ConstAccessor<float> VarRCSplit23("Split23"); + + // re-clustered jet substructure from clusters + static const SG::AuxElement::ConstAccessor<float> Tau21_clstr("Tau21_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau32_clstr("Tau32_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau3_clstr("Tau3_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau2_clstr("Tau2_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau1_clstr("Tau1_clstr"); + static const SG::AuxElement::ConstAccessor<float> D2_clstr("D2_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF1_clstr("ECF1_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF2_clstr("ECF2_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF3_clstr("ECF3_clstr"); + static const SG::AuxElement::ConstAccessor<float> d12_clstr("d12_clstr"); + static const SG::AuxElement::ConstAccessor<float> d23_clstr("d23_clstr"); + static const SG::AuxElement::ConstAccessor<float> Qw_clstr("Qw_clstr"); + + static const SG::AuxElement::ConstAccessor<float> gECF332_clstr("gECF332_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF461_clstr("gECF461_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF322_clstr("gECF322_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF331_clstr("gECF331_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF422_clstr("gECF422_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF441_clstr("gECF441_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF212_clstr("gECF212_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF321_clstr("gECF321_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF311_clstr("gECF311_clstr"); + static const SG::AuxElement::ConstAccessor<float> L1_clstr("L1_clstr"); + static const SG::AuxElement::ConstAccessor<float> L2_clstr("L2_clstr"); + static const SG::AuxElement::ConstAccessor<float> L3_clstr("L3_clstr"); + static const SG::AuxElement::ConstAccessor<float> L4_clstr("L4_clstr"); + static const SG::AuxElement::ConstAccessor<float> L5_clstr("L5_clstr"); + // store also the jet that is rebuilt to calculate the JSS + static const SG::AuxElement::ConstAccessor<float> RRCJet_pt("RRCJet_pt"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_eta("RRCJet_eta"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_phi("RRCJet_phi"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_e("RRCJet_e"); + + // Initialize the vectors to be saved as branches + + xAOD::JetContainer* vrc_jets = event.m_VarRCJets[name].get(); + unsigned int sizeOfRCjets = vrc_jets->size(); + m_VarRCjetBranches[VarRC + "_" + name + "_pt"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_eta"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_phi"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_e"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_d12"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_d23"].resize(sizeOfRCjets, -999.); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_pt"].resize(sizeOfRCjets, std::vector<float>()); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_eta"].resize(sizeOfRCjets, std::vector<float>()); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_phi"].resize(sizeOfRCjets, std::vector<float>()); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_e"].resize(sizeOfRCjets, std::vector<float>()); + if (m_config->bTagAlgo_MV2c10_used()) { + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_mv2c10"].resize(sizeOfRCjets, std::vector<float>()); + } - unsigned int i = 0; - for (xAOD::JetContainer::const_iterator jet_itr = rc_jets->begin(); jet_itr != rc_jets->end(); ++jet_itr) { - const xAOD::Jet* rc_jet = *jet_itr; + if (m_useVarRCJSS || m_useVarRCAdditionalJSS) { + m_VarRCjetBranches["vrrcjet_" + name + "_pt"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches["vrrcjet_" + name + "_eta"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches["vrrcjet_" + name + "_phi"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches["vrrcjet_" + name + "_e"].resize(sizeOfRCjets, -999.); + } + if (m_useVarRCJSS) { + m_VarRCjetBranches[VarRC + "_" + name + "_tau32_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_tau21_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_tau1_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_tau2_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_tau3_clstr"].resize(sizeOfRCjets, -999.); + + m_VarRCjetBranches[VarRC + "_" + name + "_d12_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_d23_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_Qw_clstr"].resize(sizeOfRCjets, -999.); + + m_VarRCjetBranches[VarRC + "_" + name + "_D2_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_ECF1_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_ECF2_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_ECF3_clstr"].resize(sizeOfRCjets, -999.); + } + if (m_useVarRCAdditionalJSS) { + m_VarRCjetBranches[VarRC + "_" + name + "_gECF332_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_gECF461_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_gECF322_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_gECF331_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_gECF422_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_gECF441_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_gECF212_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_gECF321_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_gECF311_clstr"].resize(sizeOfRCjets, -999.); + + m_VarRCjetBranches[VarRC + "_" + name + "_L1_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_L2_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_L3_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_L4_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranches[VarRC + "_" + name + "_L5_clstr"].resize(sizeOfRCjets, -999.); + } - if (!m_rc->passSelection(*rc_jet)) - continue; - m_rcjet_pt[i] = rc_jet->pt(); - m_rcjet_eta[i] = rc_jet->eta(); - m_rcjet_phi[i] = rc_jet->phi(); - m_rcjet_e[i] = rc_jet->e(); + unsigned int i = 0; - m_rcjet_d12[i] = (RCSplit12.isAvailable(*rc_jet)) ? RCSplit12(*rc_jet) : -999.; - m_rcjet_d23[i] = (RCSplit23.isAvailable(*rc_jet)) ? RCSplit23(*rc_jet) : -999.; + for (auto jet_ptr : *vrc_jets) { + const xAOD::Jet* rc_jet = jet_ptr; - // loop over subjets - m_rcjetsub_pt[i].clear(); // clear the vector size (otherwise it grows out of control!) - m_rcjetsub_eta[i].clear(); - m_rcjetsub_phi[i].clear(); - m_rcjetsub_e[i].clear(); - m_rcjetsub_mv2c10[i].clear(); + m_VarRCjetBranches[VarRC + "_" + name + "_pt"][i] = rc_jet->pt(); + m_VarRCjetBranches[VarRC + "_" + name + "_eta"][i] = rc_jet->eta(); + m_VarRCjetBranches[VarRC + "_" + name + "_phi"][i] = rc_jet->phi(); + m_VarRCjetBranches[VarRC + "_" + name + "_e"][i] = rc_jet->e(); - const xAOD::Jet* subjet(nullptr); - const xAOD::BTagging* btag(nullptr); - for(auto rc_jet_subjet : rc_jet->getConstituents()){ - subjet = static_cast<const xAOD::Jet*>(rc_jet_subjet->rawConstituent()); - btag = subjet->btagging(); + m_VarRCjetBranches[VarRC + "_" + name + "_d12"][i] = (VarRCSplit12.isAvailable(*rc_jet)) ? VarRCSplit12(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_d23"][i] = (VarRCSplit23.isAvailable(*rc_jet)) ? VarRCSplit23(*rc_jet) : -999.; - double mvx10(-999.); // b-tagging mv2c10 + if (m_useVarRCJSS || m_useVarRCAdditionalJSS) { + m_VarRCjetBranches["vrrcjet_" + name + "_pt"][i] = (RRCJet_pt.isAvailable(*rc_jet)) ? RRCJet_pt(*rc_jet) : -999.; + m_VarRCjetBranches["vrrcjet_" + name + "_eta"][i] = (RRCJet_eta.isAvailable(*rc_jet)) ? RRCJet_eta(*rc_jet) : -999.; + m_VarRCjetBranches["vrrcjet_" + name + "_phi"][i] = (RRCJet_phi.isAvailable(*rc_jet)) ? RRCJet_phi(*rc_jet) : -999.; + m_VarRCjetBranches["vrrcjet_" + name + "_e"][i] = (RRCJet_e.isAvailable(*rc_jet)) ? RRCJet_e(*rc_jet) : -999.; + } + if (m_useVarRCJSS) { + m_VarRCjetBranches[VarRC + "_" + name + "_tau32_clstr"][i] = (Tau32_clstr.isAvailable(*rc_jet)) ? Tau32_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_tau21_clstr"][i] = (Tau21_clstr.isAvailable(*rc_jet)) ? Tau21_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_tau3_clstr"][i] = (Tau3_clstr.isAvailable(*rc_jet)) ? Tau3_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_tau2_clstr"][i] = (Tau2_clstr.isAvailable(*rc_jet)) ? Tau2_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_tau1_clstr"][i] = (Tau1_clstr.isAvailable(*rc_jet)) ? Tau1_clstr(*rc_jet) : -999.; + + m_VarRCjetBranches[VarRC + "_" + name + "_d12_clstr"][i] = (d12_clstr.isAvailable(*rc_jet)) ? d12_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_d23_clstr"][i] = (d23_clstr.isAvailable(*rc_jet)) ? d23_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_Qw_clstr"][i] = (Qw_clstr.isAvailable(*rc_jet)) ? Qw_clstr(*rc_jet) : -999.; - if (btag){ - btag->MVx_discriminant("MV2c10",mvx10); - } - else{ - mvx10 = -999.; - } - - m_rcjetsub_pt[i].push_back(subjet->pt()); - m_rcjetsub_eta[i].push_back(subjet->eta()); - m_rcjetsub_phi[i].push_back(subjet->phi()); - m_rcjetsub_e[i].push_back(subjet->e()); - m_rcjetsub_mv2c10[i].push_back(mvx10); - } // end for-loop over subjets - ++i; - } // end for-loop over re-clustered jets - - m_rcjet_pt.resize(i); - m_rcjet_eta.resize(i); - m_rcjet_phi.resize(i); - m_rcjet_e.resize(i); - m_rcjet_d12.resize(i); - m_rcjet_d23.resize(i); - m_rcjetsub_pt.resize(i, std::vector<float>()); - m_rcjetsub_eta.resize(i, std::vector<float>()); - m_rcjetsub_phi.resize(i, std::vector<float>()); - m_rcjetsub_e.resize(i, std::vector<float>()); - m_rcjetsub_mv2c10.resize(i, std::vector<float>()); - } // end if make rcjets - // end re-clustered jets - - /**********************************/ - // VarRC jets - if (m_makeVarRCJets){ - // Execute the re-clustering code - // - make jet container, put it in TStore, do re-clustering - std::string VarRC = "vrcjet"; - for (auto& rho : m_VarRCJetRho){ - for (auto& mass_scale : m_VarRCJetMassScale){ - std::replace( rho.begin(), rho.end(), '.', '_'); - std::string name = rho+mass_scale; - - top::check(m_VarRC[name]->execute(event),"Failed to execute RCJetMC15 container"); - - // Get the name of the container of re-clustered jets in TStore - m_RCJetContainer = m_VarRC[name]->rcjetContainerName(event.m_hashValue,event.m_isLoose); - - // -- Retrieve the re-clustered jets from TStore & save good re-clustered jets -- // - const xAOD::JetContainer* vrc_jets(nullptr); - top::check(evtStore()->retrieve(vrc_jets,m_RCJetContainer),"Failed to retrieve RC JetContainer"); - - // re-clustered jet substructure - static SG::AuxElement::ConstAccessor<float> VarRCSplit12("Split12"); - static SG::AuxElement::ConstAccessor<float> VarRCSplit23("Split23"); - - // Initialize the vectors to be saved as branches - unsigned int sizeOfRCjets(vrc_jets->size()); - m_VarRCjetBranches[VarRC+"_"+name+"_pt"].resize(sizeOfRCjets,-999.); - m_VarRCjetBranches[VarRC+"_"+name+"_eta"].resize(sizeOfRCjets,-999.); - m_VarRCjetBranches[VarRC+"_"+name+"_phi"].resize(sizeOfRCjets,-999.); - m_VarRCjetBranches[VarRC+"_"+name+"_e"].resize(sizeOfRCjets,-999.); - m_VarRCjetBranches[VarRC+"_"+name+"_d12"].resize(sizeOfRCjets,-999.); - m_VarRCjetBranches[VarRC+"_"+name+"_d23"].resize(sizeOfRCjets,-999.); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_pt"].resize(sizeOfRCjets, std::vector<float>()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_eta"].resize(sizeOfRCjets, std::vector<float>()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_phi"].resize(sizeOfRCjets, std::vector<float>()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_e"].resize(sizeOfRCjets, std::vector<float>()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_mv2c10"].resize(sizeOfRCjets, std::vector<float>()); - - unsigned int i = 0; - for (xAOD::JetContainer::const_iterator jet_itr = vrc_jets->begin(); jet_itr != vrc_jets->end(); ++jet_itr) { - const xAOD::Jet* rc_jet = *jet_itr; - - if (!m_VarRC[name]->passSelection(*rc_jet)) - continue; - - m_VarRCjetBranches[VarRC+"_"+name+"_pt"][i] = rc_jet->pt(); - m_VarRCjetBranches[VarRC+"_"+name+"_eta"][i] = rc_jet->eta(); - m_VarRCjetBranches[VarRC+"_"+name+"_phi"][i] = rc_jet->phi(); - m_VarRCjetBranches[VarRC+"_"+name+"_e"][i] = rc_jet->e(); - - m_VarRCjetBranches[VarRC+"_"+name+"_d12"][i] = (VarRCSplit12.isAvailable(*rc_jet)) ? VarRCSplit12(*rc_jet) : -999.; - m_VarRCjetBranches[VarRC+"_"+name+"_d23"][i] = (VarRCSplit23.isAvailable(*rc_jet)) ? VarRCSplit23(*rc_jet) : -999.; - - // loop over subjets - const xAOD::Jet* subjet(nullptr); - const xAOD::BTagging* btag(nullptr); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_pt"][i].clear(); // clear the vector size (otherwise it grows out of control!) - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_eta"][i].clear(); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_phi"][i].clear(); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_e"][i].clear(); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_mv2c10"][i].clear(); - for(auto rc_jet_subjet : rc_jet->getConstituents()){ - subjet = static_cast<const xAOD::Jet*>(rc_jet_subjet->rawConstituent()); - btag = subjet->btagging(); - - double mvx10(-999.); // b-tagging mv2c10 - - if (btag){ - btag->MVx_discriminant("MV2c10",mvx10); - } - else{ - mvx10 = -999.; - } - - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_pt"][i].push_back(subjet->pt()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_eta"][i].push_back(subjet->eta()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_phi"][i].push_back(subjet->phi()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_e"][i].push_back(subjet->e()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_mv2c10"][i].push_back(mvx10); - } // end for-loop over subjets - ++i; - - } // end for-loop over re-clustered jets - - m_VarRCjetBranches[VarRC+"_"+name+"_pt"].resize(i); - m_VarRCjetBranches[VarRC+"_"+name+"_eta"].resize(i); - m_VarRCjetBranches[VarRC+"_"+name+"_phi"].resize(i); - m_VarRCjetBranches[VarRC+"_"+name+"_e"].resize(i); - m_VarRCjetBranches[VarRC+"_"+name+"_d12"].resize(i); - m_VarRCjetBranches[VarRC+"_"+name+"_d23"].resize(i); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_pt"].resize(i, std::vector<float>()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_eta"].resize(i, std::vector<float>()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_phi"].resize(i, std::vector<float>()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_e"].resize(i, std::vector<float>()); - m_VarRCjetsubBranches[VarRC+"_"+name+"_sub_mv2c10"].resize(i, std::vector<float>()); - } // end loop over mass parameters - } // end loop over multipliers for mass scale - } // end if make VarRC jets - // end VarRC jets - - - //met - m_met_met = event.m_met->met(); - m_met_phi = event.m_met->phi(); - - //KLFitter - if (m_config->doKLFitter()) { - unsigned int nPermutations(0),iPerm(0),bestPerm(0); - bool validKLFitter(false); - m_klfitter_selected = 0; - if (event.m_KLFitterResults != nullptr) { - validKLFitter = true; - m_klfitter_selected = 1; - nPermutations = event.m_KLFitterResults->size(); + m_VarRCjetBranches[VarRC + "_" + name + "_D2_clstr"][i] = (D2_clstr.isAvailable(*rc_jet)) ? D2_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_ECF1_clstr"][i] = (ECF1_clstr.isAvailable(*rc_jet)) ? ECF1_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_ECF2_clstr"][i] = (ECF2_clstr.isAvailable(*rc_jet)) ? ECF2_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_ECF3_clstr"][i] = (ECF3_clstr.isAvailable(*rc_jet)) ? ECF3_clstr(*rc_jet) : -999.; + } + if (m_useVarRCAdditionalJSS) { + m_VarRCjetBranches[VarRC + "_" + name + "_gECF332_clstr"][i] = (gECF332_clstr.isAvailable(*rc_jet)) ? gECF332_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_gECF461_clstr"][i] = (gECF461_clstr.isAvailable(*rc_jet)) ? gECF461_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_gECF322_clstr"][i] = (gECF322_clstr.isAvailable(*rc_jet)) ? gECF322_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_gECF331_clstr"][i] = (gECF331_clstr.isAvailable(*rc_jet)) ? gECF331_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_gECF422_clstr"][i] = (gECF422_clstr.isAvailable(*rc_jet)) ? gECF422_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_gECF441_clstr"][i] = (gECF441_clstr.isAvailable(*rc_jet)) ? gECF441_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_gECF212_clstr"][i] = (gECF212_clstr.isAvailable(*rc_jet)) ? gECF212_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_gECF321_clstr"][i] = (gECF321_clstr.isAvailable(*rc_jet)) ? gECF321_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_gECF311_clstr"][i] = (gECF311_clstr.isAvailable(*rc_jet)) ? gECF311_clstr(*rc_jet) : -999.; + + m_VarRCjetBranches[VarRC + "_" + name + "_L1_clstr"][i] = (L1_clstr.isAvailable(*rc_jet)) ? L1_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_L2_clstr"][i] = (L2_clstr.isAvailable(*rc_jet)) ? L2_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_L3_clstr"][i] = (L3_clstr.isAvailable(*rc_jet)) ? L3_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_L4_clstr"][i] = (L4_clstr.isAvailable(*rc_jet)) ? L4_clstr(*rc_jet) : -999.; + m_VarRCjetBranches[VarRC + "_" + name + "_L5_clstr"][i] = (L5_clstr.isAvailable(*rc_jet)) ? L5_clstr(*rc_jet) : -999.; } - m_klfitter_minuitDidNotConverge.resize(nPermutations); - m_klfitter_fitAbortedDueToNaN.resize(nPermutations); - m_klfitter_atLeastOneFitParameterAtItsLimit.resize(nPermutations); - m_klfitter_invalidTransferFunctionAtConvergence.resize(nPermutations); - - /// Global result - m_klfitter_bestPermutation.resize(nPermutations); - m_klfitter_logLikelihood.resize(nPermutations); - m_klfitter_eventProbability.resize(nPermutations); - m_klfitter_parameters.resize(nPermutations); - m_klfitter_parameterErrors.resize(nPermutations); - - /// Model - m_klfitter_model_bhad_pt.resize(nPermutations); - m_klfitter_model_bhad_eta.resize(nPermutations); - m_klfitter_model_bhad_phi.resize(nPermutations); - m_klfitter_model_bhad_E.resize(nPermutations); - m_klfitter_model_bhad_jetIndex.resize(nPermutations); - - m_klfitter_model_blep_pt.resize(nPermutations); - m_klfitter_model_blep_eta.resize(nPermutations); - m_klfitter_model_blep_phi.resize(nPermutations); - m_klfitter_model_blep_E.resize(nPermutations); - m_klfitter_model_blep_jetIndex.resize(nPermutations); - - m_klfitter_model_lq1_pt.resize(nPermutations); - m_klfitter_model_lq1_eta.resize(nPermutations); - m_klfitter_model_lq1_phi.resize(nPermutations); - m_klfitter_model_lq1_E.resize(nPermutations); - m_klfitter_model_lq1_jetIndex.resize(nPermutations); - - m_klfitter_model_lq2_pt.resize(nPermutations); - m_klfitter_model_lq2_eta.resize(nPermutations); - m_klfitter_model_lq2_phi.resize(nPermutations); - m_klfitter_model_lq2_E.resize(nPermutations); - m_klfitter_model_lq2_jetIndex.resize(nPermutations); - - if(m_config -> KLFitterLH() == "ttH"){ - - m_klfitter_model_Higgs_b1_pt.resize(nPermutations); - m_klfitter_model_Higgs_b1_eta.resize(nPermutations); - m_klfitter_model_Higgs_b1_phi.resize(nPermutations); - m_klfitter_model_Higgs_b1_E.resize(nPermutations); - m_klfitter_model_Higgs_b1_jetIndex.resize(nPermutations); - - m_klfitter_model_Higgs_b2_pt.resize(nPermutations); - m_klfitter_model_Higgs_b2_eta.resize(nPermutations); - m_klfitter_model_Higgs_b2_phi.resize(nPermutations); - m_klfitter_model_Higgs_b2_E.resize(nPermutations); - m_klfitter_model_Higgs_b2_jetIndex.resize(nPermutations); - } + // loop over subjets + const xAOD::Jet* subjet(nullptr); + const xAOD::BTagging* btag(nullptr); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_pt"][i].clear(); // clear the vector size (otherwise it + // grows out of control!) + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_eta"][i].clear(); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_phi"][i].clear(); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_e"][i].clear(); + if (m_config->bTagAlgo_MV2c10_used()) { + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_mv2c10"][i].clear(); + } + for (auto rc_jet_subjet : rc_jet->getConstituents()) { + subjet = static_cast<const xAOD::Jet*>(rc_jet_subjet->rawConstituent()); - m_klfitter_model_lep_pt.resize(nPermutations); - m_klfitter_model_lep_eta.resize(nPermutations); - m_klfitter_model_lep_phi.resize(nPermutations); - m_klfitter_model_lep_E.resize(nPermutations); - - m_klfitter_model_nu_pt.resize(nPermutations); - m_klfitter_model_nu_eta.resize(nPermutations); - m_klfitter_model_nu_phi.resize(nPermutations); - m_klfitter_model_nu_E.resize(nPermutations); - - if (validKLFitter) { - for (const auto* const klPtr : *event.m_KLFitterResults) { - m_klfitter_minuitDidNotConverge[iPerm] = klPtr->minuitDidNotConverge(); - m_klfitter_fitAbortedDueToNaN[iPerm] = klPtr->fitAbortedDueToNaN(); - m_klfitter_atLeastOneFitParameterAtItsLimit[iPerm] = klPtr->atLeastOneFitParameterAtItsLimit(); - m_klfitter_invalidTransferFunctionAtConvergence[iPerm] = klPtr->invalidTransferFunctionAtConvergence(); - - /// Global result - m_klfitter_bestPermutation[iPerm] = klPtr->bestPermutation(); - if (klPtr->bestPermutation() == 1){ - bestPerm = iPerm; - } - m_klfitter_logLikelihood[iPerm] = klPtr->logLikelihood(); - m_klfitter_eventProbability[iPerm] = klPtr->eventProbability(); - m_klfitter_parameters[iPerm] = klPtr->parameters(); - m_klfitter_parameterErrors[iPerm] = klPtr->parameterErrors(); - - /// Model - m_klfitter_model_bhad_pt[iPerm] = klPtr->model_bhad_pt(); - m_klfitter_model_bhad_eta[iPerm] = klPtr->model_bhad_eta(); - m_klfitter_model_bhad_phi[iPerm] = klPtr->model_bhad_phi(); - m_klfitter_model_bhad_E[iPerm] = klPtr->model_bhad_E(); - m_klfitter_model_bhad_jetIndex[iPerm] = klPtr->model_bhad_jetIndex(); - - m_klfitter_model_blep_pt[iPerm] = klPtr->model_blep_pt(); - m_klfitter_model_blep_eta[iPerm] = klPtr->model_blep_eta(); - m_klfitter_model_blep_phi[iPerm] = klPtr->model_blep_phi(); - m_klfitter_model_blep_E[iPerm] = klPtr->model_blep_E(); - m_klfitter_model_blep_jetIndex[iPerm] = klPtr->model_blep_jetIndex(); - - m_klfitter_model_lq1_pt[iPerm] = klPtr->model_lq1_pt(); - m_klfitter_model_lq1_eta[iPerm] = klPtr->model_lq1_eta(); - m_klfitter_model_lq1_phi[iPerm] = klPtr->model_lq1_phi(); - m_klfitter_model_lq1_E[iPerm] = klPtr->model_lq1_E(); - m_klfitter_model_lq1_jetIndex[iPerm] = klPtr->model_lq1_jetIndex(); - - m_klfitter_model_lq2_pt[iPerm] = klPtr->model_lq2_pt(); - m_klfitter_model_lq2_eta[iPerm] = klPtr->model_lq2_eta(); - m_klfitter_model_lq2_phi[iPerm] = klPtr->model_lq2_phi(); - m_klfitter_model_lq2_E[iPerm] = klPtr->model_lq2_E(); - m_klfitter_model_lq2_jetIndex[iPerm] = klPtr->model_lq2_jetIndex(); - - if(m_config -> KLFitterLH() == "ttH"){ - - m_klfitter_model_Higgs_b1_pt[iPerm] = klPtr->model_Higgs_b1_pt(); - m_klfitter_model_Higgs_b1_eta[iPerm] = klPtr->model_Higgs_b1_eta(); - m_klfitter_model_Higgs_b1_phi[iPerm] = klPtr->model_Higgs_b1_phi(); - m_klfitter_model_Higgs_b1_E[iPerm] = klPtr->model_Higgs_b1_E(); - m_klfitter_model_Higgs_b1_jetIndex[iPerm] = klPtr->model_Higgs_b1_jetIndex(); - - m_klfitter_model_Higgs_b2_pt[iPerm] = klPtr->model_Higgs_b2_pt(); - m_klfitter_model_Higgs_b2_eta[iPerm] = klPtr->model_Higgs_b2_eta(); - m_klfitter_model_Higgs_b2_phi[iPerm] = klPtr->model_Higgs_b2_phi(); - m_klfitter_model_Higgs_b2_E[iPerm] = klPtr->model_Higgs_b2_E(); - m_klfitter_model_Higgs_b2_jetIndex[iPerm] = klPtr->model_Higgs_b2_jetIndex(); - - } - - m_klfitter_model_lep_pt[iPerm] = klPtr->model_lep_pt(); - m_klfitter_model_lep_eta[iPerm] = klPtr->model_lep_eta(); - m_klfitter_model_lep_phi[iPerm] = klPtr->model_lep_phi(); - m_klfitter_model_lep_E[iPerm] = klPtr->model_lep_E(); - - m_klfitter_model_nu_pt[iPerm] = klPtr->model_nu_pt(); - m_klfitter_model_nu_eta[iPerm] = klPtr->model_nu_eta(); - m_klfitter_model_nu_phi[iPerm] = klPtr->model_nu_phi(); - m_klfitter_model_nu_E[iPerm] = klPtr->model_nu_E(); - - - ++iPerm; - } + if (m_config->bTagAlgo_MV2c10_used()) { + btag = subjet->btagging(); - // now take the best permutation and build the tops and the ttbar system! + double mvx10(-999.); // b-tagging mv2c10 - TLorentzVector bhad,blep,lq1,lq2,lep,nu,top_had,top_lep,ttbar; + if (btag) { + btag->MVx_discriminant("MV2c10", mvx10); + } else { + mvx10 = -999.; + } + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_mv2c10"][i].push_back(mvx10); + } - bhad.SetPtEtaPhiE(m_klfitter_model_bhad_pt[bestPerm], m_klfitter_model_bhad_eta[bestPerm], m_klfitter_model_bhad_phi[bestPerm], m_klfitter_model_bhad_E[bestPerm]); - blep.SetPtEtaPhiE(m_klfitter_model_blep_pt[bestPerm], m_klfitter_model_blep_eta[bestPerm], m_klfitter_model_blep_phi[bestPerm], m_klfitter_model_blep_E[bestPerm]); - lq1.SetPtEtaPhiE(m_klfitter_model_lq1_pt[bestPerm], m_klfitter_model_lq1_eta[bestPerm], m_klfitter_model_lq1_phi[bestPerm], m_klfitter_model_lq1_E[bestPerm]); - lq2.SetPtEtaPhiE(m_klfitter_model_lq2_pt[bestPerm], m_klfitter_model_lq2_eta[bestPerm], m_klfitter_model_lq2_phi[bestPerm], m_klfitter_model_lq2_E[bestPerm]); - lep.SetPtEtaPhiE(m_klfitter_model_lep_pt[bestPerm], m_klfitter_model_lep_eta[bestPerm], m_klfitter_model_lep_phi[bestPerm], m_klfitter_model_lep_E[bestPerm]); - nu.SetPtEtaPhiE(m_klfitter_model_nu_pt[bestPerm], m_klfitter_model_nu_eta[bestPerm], m_klfitter_model_nu_phi[bestPerm], m_klfitter_model_nu_E[bestPerm]); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_pt"][i].push_back(subjet->pt()); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_eta"][i].push_back(subjet->eta()); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_phi"][i].push_back(subjet->phi()); + m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_e"][i].push_back(subjet->e()); + } // end for-loop over subjets + ++i; + } // end for-loop over re-clustered jets + } // end loop over mass parameters + } // end loop over multipliers for mass scale + } // end if make VarRC jets + // end VarRC jets - top_had = bhad+lq1+lq2; - top_lep = blep+lep+nu; - ttbar = top_had+top_lep; - m_klfitter_bestPerm_topLep_pt = top_lep.Pt(); - m_klfitter_bestPerm_topLep_eta = top_lep.Eta(); - m_klfitter_bestPerm_topLep_phi = top_lep.Phi(); - m_klfitter_bestPerm_topLep_E = top_lep.E(); - m_klfitter_bestPerm_topLep_m = top_lep.M(); + //met + m_met_met = event.m_met->met(); + m_met_phi = event.m_met->phi(); + + if(m_config->writeMETBuiltWithLooseObjects()) + { + const xAOD::MissingETContainer* mets(nullptr); + if(event.m_isLoose) top::check(evtStore()->retrieve(mets, m_config->sgKeyMissingEtLoose(event.m_hashValue)+"WithLooseObjects"), "Failed to retrieve MET"); + else top::check(evtStore()->retrieve(mets, m_config->sgKeyMissingEt(event.m_hashValue)+"WithLooseObjects"), "Failed to retrieve MET"); + + m_met_met_withLooseObjects=(*mets)["FinalTrk"]->met(); + m_met_phi_withLooseObjects=(*mets)["FinalTrk"]->phi(); + } - m_klfitter_bestPerm_topHad_pt = top_had.Pt(); - m_klfitter_bestPerm_topHad_eta = top_had.Eta(); - m_klfitter_bestPerm_topHad_phi = top_had.Phi(); - m_klfitter_bestPerm_topHad_E = top_had.E(); - m_klfitter_bestPerm_topHad_m = top_had.M(); + //KLFitter + if (m_config->doKLFitter()) { + unsigned int nPermutations(0), iPerm(0), bestPerm(0); + bool validKLFitter(false); + m_klfitter_selected = 0; + if (event.m_KLFitterResults != nullptr) { + validKLFitter = true; + m_klfitter_selected = 1; + nPermutations = event.m_KLFitterResults->size(); + } - m_klfitter_bestPerm_ttbar_pt = ttbar.Pt(); - m_klfitter_bestPerm_ttbar_eta = ttbar.Eta(); - m_klfitter_bestPerm_ttbar_phi = ttbar.Phi(); - m_klfitter_bestPerm_ttbar_E = ttbar.E(); - m_klfitter_bestPerm_ttbar_m = ttbar.M(); + m_klfitter_selection.resize(nPermutations); + m_klfitter_minuitDidNotConverge.resize(nPermutations); + m_klfitter_fitAbortedDueToNaN.resize(nPermutations); + m_klfitter_atLeastOneFitParameterAtItsLimit.resize(nPermutations); + m_klfitter_invalidTransferFunctionAtConvergence.resize(nPermutations); + + /// Global result + m_klfitter_bestPermutation.resize(nPermutations); + m_klfitter_logLikelihood.resize(nPermutations); + m_klfitter_eventProbability.resize(nPermutations); + m_klfitter_parameters_size.resize(nPermutations); + m_klfitter_parameters.resize(nPermutations); + m_klfitter_parameterErrors.resize(nPermutations); + + if (m_config->KLFitterLH() == "ttbar" || m_config->KLFitterLH() == "ttZTrilepton" || m_config->KLFitterLH() == "ttH" || m_config->KLFitterLH() == "ttbar_JetAngles" || m_config->KLFitterLH() == "ttbar_BoostedLJets") { + /// Model + m_klfitter_model_bhad_pt.resize(nPermutations); + m_klfitter_model_bhad_eta.resize(nPermutations); + m_klfitter_model_bhad_phi.resize(nPermutations); + m_klfitter_model_bhad_E.resize(nPermutations); + m_klfitter_model_bhad_jetIndex.resize(nPermutations); + + m_klfitter_model_blep_pt.resize(nPermutations); + m_klfitter_model_blep_eta.resize(nPermutations); + m_klfitter_model_blep_phi.resize(nPermutations); + m_klfitter_model_blep_E.resize(nPermutations); + m_klfitter_model_blep_jetIndex.resize(nPermutations); + + m_klfitter_model_lq1_pt.resize(nPermutations); + m_klfitter_model_lq1_eta.resize(nPermutations); + m_klfitter_model_lq1_phi.resize(nPermutations); + m_klfitter_model_lq1_E.resize(nPermutations); + m_klfitter_model_lq1_jetIndex.resize(nPermutations); + + if (m_config->KLFitterLH() != "ttbar_BoostedLJets") { + m_klfitter_model_lq2_pt.resize(nPermutations); + m_klfitter_model_lq2_eta.resize(nPermutations); + m_klfitter_model_lq2_phi.resize(nPermutations); + m_klfitter_model_lq2_E.resize(nPermutations); + m_klfitter_model_lq2_jetIndex.resize(nPermutations); + + if (m_config->KLFitterLH() == "ttH") { + m_klfitter_model_Higgs_b1_pt.resize(nPermutations); + m_klfitter_model_Higgs_b1_eta.resize(nPermutations); + m_klfitter_model_Higgs_b1_phi.resize(nPermutations); + m_klfitter_model_Higgs_b1_E.resize(nPermutations); + m_klfitter_model_Higgs_b1_jetIndex.resize(nPermutations); + + m_klfitter_model_Higgs_b2_pt.resize(nPermutations); + m_klfitter_model_Higgs_b2_eta.resize(nPermutations); + m_klfitter_model_Higgs_b2_phi.resize(nPermutations); + m_klfitter_model_Higgs_b2_E.resize(nPermutations); + m_klfitter_model_Higgs_b2_jetIndex.resize(nPermutations); + } + } - + m_klfitter_model_lep_pt.resize(nPermutations); + m_klfitter_model_lep_eta.resize(nPermutations); + m_klfitter_model_lep_phi.resize(nPermutations); + m_klfitter_model_lep_E.resize(nPermutations); + m_klfitter_model_lep_index.resize(nPermutations); + + m_klfitter_model_lepZ1_pt.resize(nPermutations); + m_klfitter_model_lepZ1_eta.resize(nPermutations); + m_klfitter_model_lepZ1_phi.resize(nPermutations); + m_klfitter_model_lepZ1_E.resize(nPermutations); + m_klfitter_model_lepZ1_index.resize(nPermutations); + + m_klfitter_model_lepZ2_pt.resize(nPermutations); + m_klfitter_model_lepZ2_eta.resize(nPermutations); + m_klfitter_model_lepZ2_phi.resize(nPermutations); + m_klfitter_model_lepZ2_E.resize(nPermutations); + m_klfitter_model_lepZ2_index.resize(nPermutations); + + m_klfitter_model_nu_pt.resize(nPermutations); + m_klfitter_model_nu_eta.resize(nPermutations); + m_klfitter_model_nu_phi.resize(nPermutations); + m_klfitter_model_nu_E.resize(nPermutations); + } else if (m_config->KLFitterLH() == "ttbar_AllHadronic") { + m_klfitter_model_b_from_top1_pt.resize(nPermutations); + m_klfitter_model_b_from_top1_eta.resize(nPermutations); + m_klfitter_model_b_from_top1_phi.resize(nPermutations); + m_klfitter_model_b_from_top1_E.resize(nPermutations); + m_klfitter_model_b_from_top1_jetIndex.resize(nPermutations); + + m_klfitter_model_b_from_top2_pt.resize(nPermutations); + m_klfitter_model_b_from_top2_eta.resize(nPermutations); + m_klfitter_model_b_from_top2_phi.resize(nPermutations); + m_klfitter_model_b_from_top2_E.resize(nPermutations); + m_klfitter_model_b_from_top2_jetIndex.resize(nPermutations); + + m_klfitter_model_lj1_from_top1_pt.resize(nPermutations); + m_klfitter_model_lj1_from_top1_eta.resize(nPermutations); + m_klfitter_model_lj1_from_top1_phi.resize(nPermutations); + m_klfitter_model_lj1_from_top1_E.resize(nPermutations); + m_klfitter_model_lj1_from_top1_jetIndex.resize(nPermutations); + + m_klfitter_model_lj2_from_top1_pt.resize(nPermutations); + m_klfitter_model_lj2_from_top1_eta.resize(nPermutations); + m_klfitter_model_lj2_from_top1_phi.resize(nPermutations); + m_klfitter_model_lj2_from_top1_E.resize(nPermutations); + m_klfitter_model_lj2_from_top1_jetIndex.resize(nPermutations); + + m_klfitter_model_lj1_from_top2_pt.resize(nPermutations); + m_klfitter_model_lj1_from_top2_eta.resize(nPermutations); + m_klfitter_model_lj1_from_top2_phi.resize(nPermutations); + m_klfitter_model_lj1_from_top2_E.resize(nPermutations); + m_klfitter_model_lj1_from_top2_jetIndex.resize(nPermutations); + + m_klfitter_model_lj2_from_top2_pt.resize(nPermutations); + m_klfitter_model_lj2_from_top2_eta.resize(nPermutations); + m_klfitter_model_lj2_from_top2_phi.resize(nPermutations); + m_klfitter_model_lj2_from_top2_E.resize(nPermutations); + m_klfitter_model_lj2_from_top2_jetIndex.resize(nPermutations); + } + if (validKLFitter) { + for (const auto* const klPtr : *event.m_KLFitterResults) { + m_klfitter_selection[iPerm] = "unknown"; + std::hash<std::string> st_hash; + for (unsigned int s = 0; s < m_config->allSelectionNames()->size(); ++s) { + if (st_hash(m_config->allSelectionNames()->at(s)) == klPtr->selectionCode()) { + m_klfitter_selection[iPerm] = m_config->allSelectionNames()->at(s); + break; } + } + m_klfitter_minuitDidNotConverge[iPerm] = klPtr->minuitDidNotConverge(); + m_klfitter_fitAbortedDueToNaN[iPerm] = klPtr->fitAbortedDueToNaN(); + m_klfitter_atLeastOneFitParameterAtItsLimit[iPerm] = klPtr->atLeastOneFitParameterAtItsLimit(); + m_klfitter_invalidTransferFunctionAtConvergence[iPerm] = klPtr->invalidTransferFunctionAtConvergence(); + + /// Global result + m_klfitter_bestPermutation[iPerm] = klPtr->bestPermutation(); + if (klPtr->bestPermutation() == 1) { + bestPerm = iPerm; + } + m_klfitter_logLikelihood[iPerm] = klPtr->logLikelihood(); + m_klfitter_eventProbability[iPerm] = klPtr->eventProbability(); + m_klfitter_parameters_size[iPerm] = klPtr->parameters().size(); + m_klfitter_parameters[iPerm] = klPtr->parameters(); + m_klfitter_parameterErrors[iPerm] = klPtr->parameterErrors(); + + /// Model + if (m_config->KLFitterLH() == "ttbar" || m_config->KLFitterLH() == "ttZTrilepton" || m_config->KLFitterLH() == "ttH" || m_config->KLFitterLH() == "ttbar_JetAngles" || m_config->KLFitterLH() == "ttbar_BoostedLJets") { + m_klfitter_model_bhad_pt[iPerm] = klPtr->model_bhad_pt(); + m_klfitter_model_bhad_eta[iPerm] = klPtr->model_bhad_eta(); + m_klfitter_model_bhad_phi[iPerm] = klPtr->model_bhad_phi(); + m_klfitter_model_bhad_E[iPerm] = klPtr->model_bhad_E(); + m_klfitter_model_bhad_jetIndex[iPerm] = klPtr->model_bhad_jetIndex(); + + m_klfitter_model_blep_pt[iPerm] = klPtr->model_blep_pt(); + m_klfitter_model_blep_eta[iPerm] = klPtr->model_blep_eta(); + m_klfitter_model_blep_phi[iPerm] = klPtr->model_blep_phi(); + m_klfitter_model_blep_E[iPerm] = klPtr->model_blep_E(); + m_klfitter_model_blep_jetIndex[iPerm] = klPtr->model_blep_jetIndex(); + + m_klfitter_model_lq1_pt[iPerm] = klPtr->model_lq1_pt(); + m_klfitter_model_lq1_eta[iPerm] = klPtr->model_lq1_eta(); + m_klfitter_model_lq1_phi[iPerm] = klPtr->model_lq1_phi(); + m_klfitter_model_lq1_E[iPerm] = klPtr->model_lq1_E(); + m_klfitter_model_lq1_jetIndex[iPerm] = klPtr->model_lq1_jetIndex(); + + if (m_config->KLFitterLH() != "ttbar_BoostedLJets") { + m_klfitter_model_lq2_pt[iPerm] = klPtr->model_lq2_pt(); + m_klfitter_model_lq2_eta[iPerm] = klPtr->model_lq2_eta(); + m_klfitter_model_lq2_phi[iPerm] = klPtr->model_lq2_phi(); + m_klfitter_model_lq2_E[iPerm] = klPtr->model_lq2_E(); + m_klfitter_model_lq2_jetIndex[iPerm] = klPtr->model_lq2_jetIndex(); + + if (m_config->KLFitterLH() == "ttH") { + m_klfitter_model_Higgs_b1_pt[iPerm] = klPtr->model_Higgs_b1_pt(); + m_klfitter_model_Higgs_b1_eta[iPerm] = klPtr->model_Higgs_b1_eta(); + m_klfitter_model_Higgs_b1_phi[iPerm] = klPtr->model_Higgs_b1_phi(); + m_klfitter_model_Higgs_b1_E[iPerm] = klPtr->model_Higgs_b1_E(); + m_klfitter_model_Higgs_b1_jetIndex[iPerm] = klPtr->model_Higgs_b1_jetIndex(); + + m_klfitter_model_Higgs_b2_pt[iPerm] = klPtr->model_Higgs_b2_pt(); + m_klfitter_model_Higgs_b2_eta[iPerm] = klPtr->model_Higgs_b2_eta(); + m_klfitter_model_Higgs_b2_phi[iPerm] = klPtr->model_Higgs_b2_phi(); + m_klfitter_model_Higgs_b2_E[iPerm] = klPtr->model_Higgs_b2_E(); + m_klfitter_model_Higgs_b2_jetIndex[iPerm] = klPtr->model_Higgs_b2_jetIndex(); + } + } + m_klfitter_model_lep_pt[iPerm] = klPtr->model_lep_pt(); + m_klfitter_model_lep_eta[iPerm] = klPtr->model_lep_eta(); + m_klfitter_model_lep_phi[iPerm] = klPtr->model_lep_phi(); + m_klfitter_model_lep_E[iPerm] = klPtr->model_lep_E(); + m_klfitter_model_lep_index[iPerm] = klPtr->model_lep_index(); + + m_klfitter_model_lepZ1_pt[iPerm] = klPtr->model_lepZ1_pt(); + m_klfitter_model_lepZ1_eta[iPerm] = klPtr->model_lepZ1_eta(); + m_klfitter_model_lepZ1_phi[iPerm] = klPtr->model_lepZ1_phi(); + m_klfitter_model_lepZ1_E[iPerm] = klPtr->model_lepZ1_E(); + m_klfitter_model_lepZ1_index[iPerm] = klPtr->model_lepZ1_index(); + + m_klfitter_model_lepZ2_pt[iPerm] = klPtr->model_lepZ2_pt(); + m_klfitter_model_lepZ2_eta[iPerm] = klPtr->model_lepZ2_eta(); + m_klfitter_model_lepZ2_phi[iPerm] = klPtr->model_lepZ2_phi(); + m_klfitter_model_lepZ2_E[iPerm] = klPtr->model_lepZ2_E(); + m_klfitter_model_lepZ2_index[iPerm] = klPtr->model_lepZ2_index(); + + m_klfitter_model_nu_pt[iPerm] = klPtr->model_nu_pt(); + m_klfitter_model_nu_eta[iPerm] = klPtr->model_nu_eta(); + m_klfitter_model_nu_phi[iPerm] = klPtr->model_nu_phi(); + m_klfitter_model_nu_E[iPerm] = klPtr->model_nu_E(); + } else if (m_config->KLFitterLH() == "ttbar_AllHadronic") { + m_klfitter_model_b_from_top1_pt[iPerm] = klPtr->model_b_from_top1_pt(); + m_klfitter_model_b_from_top1_eta[iPerm] = klPtr->model_b_from_top1_eta(); + m_klfitter_model_b_from_top1_phi[iPerm] = klPtr->model_b_from_top1_phi(); + m_klfitter_model_b_from_top1_E[iPerm] = klPtr->model_b_from_top1_E(); + m_klfitter_model_b_from_top1_jetIndex[iPerm] = klPtr->model_b_from_top1_jetIndex(); + + m_klfitter_model_b_from_top2_pt[iPerm] = klPtr->model_b_from_top2_pt(); + m_klfitter_model_b_from_top2_eta[iPerm] = klPtr->model_b_from_top2_eta(); + m_klfitter_model_b_from_top2_phi[iPerm] = klPtr->model_b_from_top2_phi(); + m_klfitter_model_b_from_top2_E[iPerm] = klPtr->model_b_from_top2_E(); + m_klfitter_model_b_from_top2_jetIndex[iPerm] = klPtr->model_b_from_top2_jetIndex(); + + m_klfitter_model_lj1_from_top1_pt[iPerm] = klPtr->model_lj1_from_top1_pt(); + m_klfitter_model_lj1_from_top1_eta[iPerm] = klPtr->model_lj1_from_top1_eta(); + m_klfitter_model_lj1_from_top1_phi[iPerm] = klPtr->model_lj1_from_top1_phi(); + m_klfitter_model_lj1_from_top1_E[iPerm] = klPtr->model_lj1_from_top1_E(); + m_klfitter_model_lj1_from_top1_jetIndex[iPerm] = klPtr->model_lj1_from_top1_jetIndex(); + + m_klfitter_model_lj2_from_top1_pt[iPerm] = klPtr->model_lj2_from_top1_pt(); + m_klfitter_model_lj2_from_top1_eta[iPerm] = klPtr->model_lj2_from_top1_eta(); + m_klfitter_model_lj2_from_top1_phi[iPerm] = klPtr->model_lj2_from_top1_phi(); + m_klfitter_model_lj2_from_top1_E[iPerm] = klPtr->model_lj2_from_top1_E(); + m_klfitter_model_lj2_from_top1_jetIndex[iPerm] = klPtr->model_lj2_from_top1_jetIndex(); + + m_klfitter_model_lj1_from_top2_pt[iPerm] = klPtr->model_lj1_from_top2_pt(); + m_klfitter_model_lj1_from_top2_eta[iPerm] = klPtr->model_lj1_from_top2_eta(); + m_klfitter_model_lj1_from_top2_phi[iPerm] = klPtr->model_lj1_from_top2_phi(); + m_klfitter_model_lj1_from_top2_E[iPerm] = klPtr->model_lj1_from_top2_E(); + m_klfitter_model_lj1_from_top2_jetIndex[iPerm] = klPtr->model_lj1_from_top2_jetIndex(); + + m_klfitter_model_lj2_from_top2_pt[iPerm] = klPtr->model_lj2_from_top2_pt(); + m_klfitter_model_lj2_from_top2_eta[iPerm] = klPtr->model_lj2_from_top2_eta(); + m_klfitter_model_lj2_from_top2_phi[iPerm] = klPtr->model_lj2_from_top2_phi(); + m_klfitter_model_lj2_from_top2_E[iPerm] = klPtr->model_lj2_from_top2_E(); + m_klfitter_model_lj2_from_top2_jetIndex[iPerm] = klPtr->model_lj2_from_top2_jetIndex(); + } - } - - if(m_config->doPseudoTop()){ - - const xAOD::PseudoTopResultContainer* pseudoTopResultContainer(nullptr); - const xAOD::PseudoTopResult* pseudoTopResult(nullptr); - if (evtStore()->contains<xAOD::PseudoTopResultContainer>(m_config->sgKeyPseudoTop(event.m_hashValue))) { - top::check(evtStore()->retrieve(pseudoTopResultContainer, m_config->sgKeyPseudoTop(event.m_hashValue)),"Failed to retrieve PseudoTop"); + ++iPerm; + } - pseudoTopResult = pseudoTopResultContainer->at(0); + // now take the best permutation and build the tops and the ttbar system! + if (m_config->KLFitterLH() == "ttbar" || m_config->KLFitterLH() == "ttZTrilepton" || m_config->KLFitterLH() == "ttH" || m_config->KLFitterLH() == "ttbar_JetAngles") { + if (nPermutations != 0) { + TLorentzVector bhad, blep, lq1, lq2, lep, nu, top_had, top_lep, ttbar; + + bhad.SetPtEtaPhiE(m_klfitter_model_bhad_pt[bestPerm], m_klfitter_model_bhad_eta[bestPerm], m_klfitter_model_bhad_phi[bestPerm], m_klfitter_model_bhad_E[bestPerm]); + blep.SetPtEtaPhiE(m_klfitter_model_blep_pt[bestPerm], m_klfitter_model_blep_eta[bestPerm], m_klfitter_model_blep_phi[bestPerm], m_klfitter_model_blep_E[bestPerm]); + lq1.SetPtEtaPhiE(m_klfitter_model_lq1_pt[bestPerm], m_klfitter_model_lq1_eta[bestPerm], m_klfitter_model_lq1_phi[bestPerm], m_klfitter_model_lq1_E[bestPerm]); + lq2.SetPtEtaPhiE(m_klfitter_model_lq2_pt[bestPerm], m_klfitter_model_lq2_eta[bestPerm], m_klfitter_model_lq2_phi[bestPerm], m_klfitter_model_lq2_E[bestPerm]); + lep.SetPtEtaPhiE(m_klfitter_model_lep_pt[bestPerm], m_klfitter_model_lep_eta[bestPerm], m_klfitter_model_lep_phi[bestPerm], m_klfitter_model_lep_E[bestPerm]); + nu.SetPtEtaPhiE(m_klfitter_model_nu_pt[bestPerm], m_klfitter_model_nu_eta[bestPerm], m_klfitter_model_nu_phi[bestPerm], m_klfitter_model_nu_E[bestPerm]); + + top_had = bhad + lq1 + lq2; + top_lep = blep + lep + nu; + ttbar = top_had + top_lep; + + m_klfitter_bestPerm_topLep_pt = top_lep.Pt(); + m_klfitter_bestPerm_topLep_eta = top_lep.Eta(); + m_klfitter_bestPerm_topLep_phi = top_lep.Phi(); + m_klfitter_bestPerm_topLep_E = top_lep.E(); + m_klfitter_bestPerm_topLep_m = top_lep.M(); + + m_klfitter_bestPerm_topHad_pt = top_had.Pt(); + m_klfitter_bestPerm_topHad_eta = top_had.Eta(); + m_klfitter_bestPerm_topHad_phi = top_had.Phi(); + m_klfitter_bestPerm_topHad_E = top_had.E(); + m_klfitter_bestPerm_topHad_m = top_had.M(); + + m_klfitter_bestPerm_ttbar_pt = ttbar.Pt(); + m_klfitter_bestPerm_ttbar_eta = ttbar.Eta(); + m_klfitter_bestPerm_ttbar_phi = ttbar.Phi(); + m_klfitter_bestPerm_ttbar_E = ttbar.E(); + m_klfitter_bestPerm_ttbar_m = ttbar.M(); + } + } + } + } - m_PseudoTop_Reco_ttbar_pt = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_ttbar_pt"); - m_PseudoTop_Reco_ttbar_eta = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_ttbar_eta"); - m_PseudoTop_Reco_ttbar_phi = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_ttbar_phi"); - m_PseudoTop_Reco_ttbar_m = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_ttbar_m"); + if (m_config->doPseudoTop()) { + const xAOD::PseudoTopResultContainer* pseudoTopResultContainer(nullptr); + const xAOD::PseudoTopResult* pseudoTopResult(nullptr); - m_PseudoTop_Reco_top_lep_pt = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_top_lep_pt"); - m_PseudoTop_Reco_top_lep_eta = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_top_lep_eta"); - m_PseudoTop_Reco_top_lep_phi = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_top_lep_phi"); - m_PseudoTop_Reco_top_lep_m = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_top_lep_m"); + if ((!event.m_isLoose && evtStore()->contains<xAOD::PseudoTopResultContainer>(topConfig()->sgKeyPseudoTop(event.m_hashValue))) || + (event.m_isLoose && evtStore()->contains<xAOD::PseudoTopResultContainer>(topConfig()->sgKeyPseudoTopLoose(event.m_hashValue)))) { + if (!event.m_isLoose) { + top::check(evtStore()->retrieve(pseudoTopResultContainer, topConfig()->sgKeyPseudoTop(event.m_hashValue)), "Failed to retrieve PseudoTop"); + } else { + top::check(evtStore()->retrieve(pseudoTopResultContainer, topConfig()->sgKeyPseudoTopLoose(event.m_hashValue)), "Failed to retrieve PseudoTop"); + } - m_PseudoTop_Reco_top_had_pt = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_top_had_pt"); - m_PseudoTop_Reco_top_had_eta = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_top_had_eta"); - m_PseudoTop_Reco_top_had_phi = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_top_had_phi"); - m_PseudoTop_Reco_top_had_m = pseudoTopResult -> auxdecor<float>("PseudoTop_Reco_top_had_m"); + pseudoTopResult = pseudoTopResultContainer->at(0); + m_PseudoTop_Reco_ttbar_pt = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_ttbar_pt"); + m_PseudoTop_Reco_ttbar_eta = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_ttbar_eta"); + m_PseudoTop_Reco_ttbar_phi = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_ttbar_phi"); + m_PseudoTop_Reco_ttbar_m = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_ttbar_m"); - } - } + m_PseudoTop_Reco_top_lep_pt = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_top_lep_pt"); + m_PseudoTop_Reco_top_lep_eta = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_top_lep_eta"); + m_PseudoTop_Reco_top_lep_phi = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_top_lep_phi"); + m_PseudoTop_Reco_top_lep_m = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_top_lep_m"); - //do it! - m_treeManagers[event.m_ttreeIndex]->fill(); + m_PseudoTop_Reco_top_had_pt = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_top_had_pt"); + m_PseudoTop_Reco_top_had_eta = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_top_had_eta"); + m_PseudoTop_Reco_top_had_phi = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_top_had_phi"); + m_PseudoTop_Reco_top_had_m = pseudoTopResult->auxdecor<float>("PseudoTop_Reco_top_had_m"); + } + } + } + + void EventSaverFlatNtuple::fillEvent(const top::Event& event) { + //do it! + m_treeManagers[event.m_ttreeIndex]->fill(); + } + + void EventSaverFlatNtuple::saveTruthEvent() { + this->cleanTruthEvent(); + this->calculateTruthEvent(); + this->fillTruthEvent(); + } + + void EventSaverFlatNtuple::cleanTruthEvent() { + /* Doing nothing for now, but we should put here the (re-)initialisation to dummy values + * of all variables later calculated in cleanTruthEvent() + * For example all weights set to 1, all vectors cleaned, all kinematic or angular variables set to -99999. + */ + } + + void EventSaverFlatNtuple::calculateTruthEvent() { + + const xAOD::EventInfo* eventInfo(nullptr); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); + + m_weight_mc = eventInfo->auxdataConst<float>("AnalysisTop_eventWeight"); + m_eventNumber = eventInfo->eventNumber(); + m_runNumber = eventInfo->runNumber(); + m_mcChannelNumber = eventInfo->mcChannelNumber(); + m_mu = eventInfo->averageInteractionsPerCrossing(); + m_mu_actual = eventInfo->actualInteractionsPerCrossing(); + + if (m_config->doPileupReweighting() && !m_config->isTruthDxAOD()) { + m_weight_pileup = eventInfo->auxdataConst<float>("PileupWeight"); + m_randomRunNumber = eventInfo->auxdataConst<unsigned int>("RandomRunNumber"); + } else { + m_weight_pileup = NAN; + m_randomRunNumber = 0; } + //MC particle + if (m_config->useTruthParticles() && m_config->doTruthBlockInfo()) { + const xAOD::TruthParticleContainer* truth(nullptr); + top::check(evtStore()->retrieve(truth, m_config->sgKeyMCParticle()), "Failed to retrieve TruthParticleContainer"); + + if (truth != nullptr) { + unsigned int i(0); + unsigned int truthSize = truth->size(); + m_mc_pt.resize(truthSize); + m_mc_eta.resize(truthSize); + m_mc_phi.resize(truthSize); + m_mc_e.resize(truthSize); + m_mc_pdgId.resize(truthSize); + m_mc_charge.resize(truthSize); + m_mc_status.resize(truthSize); + m_mc_barcode.resize(truthSize); + + for (const auto* const mcPtr : *truth) { + // Fix for + // Warning in <TVector3::PseudoRapidity>: transvers momentum = 0! return +/- 10e10 + + float eta(-999.9); + + if (!(mcPtr->p4().CosTheta() * mcPtr->p4().CosTheta() >= 1 && mcPtr->p4().Pz() != 0)) { + eta = mcPtr->eta(); + } - void EventSaverFlatNtuple::saveTruthEvent() - { + m_mc_pt[i] = mcPtr->pt(); + m_mc_eta[i] = eta; + m_mc_phi[i] = mcPtr->phi(); + m_mc_e[i] = mcPtr->e(); + m_mc_pdgId[i] = mcPtr->pdgId(); + m_mc_charge[i] = mcPtr->charge(); + m_mc_status[i] = mcPtr->status(); + m_mc_barcode[i] = mcPtr->barcode(); - const xAOD::EventInfo* eventInfo(nullptr); - top::check( evtStore()->retrieve(eventInfo,m_config->sgKeyEventInfo()) , "Failed to retrieve EventInfo" ); - - const xAOD::TruthEventContainer * truthEvent(nullptr); - top::check( evtStore()->retrieve(truthEvent, m_config->sgKeyTruthEvent()) , "Failed to retrieve truth event container" ); - unsigned int truthEventSize = truthEvent->size(); - top::check( truthEventSize==1 , "Failed to retrieve truth PDF info - truth event container size is different from 1 (strange)" ); - -// m_weight_mc = eventInfo -> mcEventWeight(); - m_weight_mc = truthEvent->at(0)->weights()[0];// FIXME temporary bugfix - m_eventNumber = eventInfo -> eventNumber(); - m_runNumber = eventInfo -> runNumber(); - m_mcChannelNumber = eventInfo -> mcChannelNumber(); - m_mu = eventInfo->averageInteractionsPerCrossing(); - if (m_config->doPileupReweighting() && !m_config->isTruthDxAOD()) { - m_weight_pileup = eventInfo->auxdataConst<float>("PileupWeight"); - m_randomRunNumber = eventInfo->auxdataConst<unsigned int>("RandomRunNumber"); - } - else { - m_weight_pileup = NAN; - m_randomRunNumber = 0; - } - - //MC particle - if (m_config->useTruthParticles() && m_config->doTruthBlockInfo()) { - - const xAOD::TruthParticleContainer* truth(nullptr); - top::check( evtStore()->retrieve(truth,m_config->sgKeyMCParticle()) , "Failed to retrieve TruthParticleContainer" ); - - if (truth != nullptr) { - unsigned int i(0); - unsigned int truthSize = truth->size(); - m_mc_pt.resize(truthSize); - m_mc_eta.resize(truthSize); - m_mc_phi.resize(truthSize); - m_mc_e.resize(truthSize); - m_mc_pdgId.resize(truthSize); - for (const auto* const mcPtr : *truth) { - - // Fix for - // Warning in <TVector3::PseudoRapidity>: transvers momentum = 0! return +/- 10e10 - - float eta(-999.9); - - if ( !( mcPtr->p4().CosTheta()*mcPtr->p4().CosTheta() >= 1 && mcPtr->p4().Pz() != 0 ) ) { - eta = mcPtr->eta(); - } - - m_mc_pt[i] = mcPtr->pt(); - m_mc_eta[i] = eta; - m_mc_phi[i] = mcPtr->phi(); - m_mc_e[i] = mcPtr->e(); - m_mc_pdgId[i] = mcPtr->pdgId(); - ++i; - } - } + ++i; } + } + } - if (m_config->doTruthPDFInfo()) { - // delegate to helper function. - loadPdfInfo(); + if (m_config->doTopPartonHistory()) { + const xAOD::PartonHistoryContainer* partonHistoryContainer(nullptr); + const xAOD::PartonHistory* partonHistory(nullptr); + if (evtStore()->contains<xAOD::PartonHistoryContainer>(m_config->sgKeyTopPartonHistory())) { + top::check(evtStore()->retrieve(partonHistoryContainer, m_config->sgKeyTopPartonHistory()), "Failed to retrieve Top Parton History"); + if (partonHistoryContainer->size() == 1) { + partonHistory = partonHistoryContainer->at(0); } + } - if (m_config->doMCGeneratorWeights()) { - // delegate to helper function. - loadMCGeneratorWeights(); + if (partonHistory != nullptr) { + if (!m_config->isTopPartonHistoryRegisteredInNtuple()) { + registerObjectIntoTruthTree(*(partonHistory)); + m_config->setTopPartonHistoryRegisteredInNtuple(); } + saveObjectIntoTruthTree(*(partonHistory)); + } + } + } - if (m_config->doTopPartonHistory()) { - - const xAOD::PartonHistoryContainer* partonHistoryContainer(nullptr); - const xAOD::PartonHistory* partonHistory(nullptr); - if (evtStore()->contains<xAOD::PartonHistoryContainer>(m_config->sgKeyTopPartonHistory())) { - top::check(evtStore()->retrieve(partonHistoryContainer, m_config->sgKeyTopPartonHistory()),"Failed to retrieve Top Parton History"); - if (partonHistoryContainer->size() == 1) { - partonHistory = partonHistoryContainer->at(0); - } - } + void EventSaverFlatNtuple::fillTruthEvent() { + if(m_config->doTopPartonLevel()) m_truthTreeManager->fill(); + } - if (partonHistory != nullptr) { - if (!m_config->isTopPartonHistoryRegisteredInNtuple()) { - registerObjectIntoTruthTree( *(partonHistory) ); - m_config->setTopPartonHistoryRegisteredInNtuple(); - } - saveObjectIntoTruthTree( *(partonHistory) ); - } + void EventSaverFlatNtuple::saveParticleLevelEvent(const top::ParticleLevelEvent& plEvent) { + // Quick return if particle level is disabled. + if (not m_config->doTopParticleLevel()) { + return; + } + // No need to attempt to write out anything for non-MC data. + if (!m_config->isMC()) { + return; + } + this->cleanParticleLevelEvent(); + this->calculateParticleLevelEvent(plEvent); + this->fillParticleLevelEvent(); + } + + void EventSaverFlatNtuple::cleanParticleLevelEvent() { + /* Doing nothing for now, but we should put here the (re-)initialisation to dummy values + * of all variables later calculated in calculateParticleLevelEvent(const top::ParticleLevelEvent& plEvent) + * For example all weights set to 1, all vectors cleaned, all kinematic or angular variables set to -99999. + */ + } + + void EventSaverFlatNtuple::calculateParticleLevelEvent(const top::ParticleLevelEvent& plEvent) { + for (auto& selectionDecision : m_particleLevel_SelectionDecisions) { + selectionDecision.second = plEvent.m_selectionDecisions[ selectionDecision.first ]; + } - } + m_weight_mc = plEvent.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); - if( m_config->saveLHAPDFEvent() ){ - // Delegate to helper function. - loadPdfWeights(); - } + m_eventNumber = plEvent.m_info->eventNumber(); + m_runNumber = plEvent.m_info->runNumber(); + m_mcChannelNumber = plEvent.m_info->mcChannelNumber(); - m_truthTreeManager->fill(); + m_mu = plEvent.m_info->averageInteractionsPerCrossing(); + m_mu_actual = plEvent.m_info->actualInteractionsPerCrossing(); + if (m_config->doPileupReweighting() && !m_config->isTruthDxAOD()) { + m_weight_pileup = plEvent.m_info->auxdataConst<float>("PileupWeight"); + m_randomRunNumber = plEvent.m_info->auxdataConst<unsigned int>("RandomRunNumber"); + } else { + m_weight_pileup = NAN; + m_randomRunNumber = 0; } - void EventSaverFlatNtuple::saveParticleLevelEvent(const top::ParticleLevelEvent& plEvent){ - // Quick return if particle level is disabled. No tree will be created! - if ( not m_config->doTopParticleLevel() ){ - return; - } + //electrons + if (m_config->useTruthElectrons()) { + unsigned int i = 0; + + m_el_pt.resize(plEvent.m_electrons->size()); + m_el_eta.resize(plEvent.m_electrons->size()); + m_el_phi.resize(plEvent.m_electrons->size()); + m_el_e.resize(plEvent.m_electrons->size()); + m_el_charge.resize(plEvent.m_electrons->size()); + + m_el_pt_bare.resize(plEvent.m_electrons->size()); + m_el_eta_bare.resize(plEvent.m_electrons->size()); + m_el_phi_bare.resize(plEvent.m_electrons->size()); + m_el_e_bare.resize(plEvent.m_electrons->size()); + + m_el_true_type.resize(plEvent.m_electrons->size()); + m_el_true_origin.resize(plEvent.m_electrons->size()); + + for (const auto& elPtr : *plEvent.m_electrons) { + m_el_pt[i] = elPtr->pt(); + m_el_eta[i] = elPtr->eta(); + m_el_phi[i] = elPtr->phi(); + m_el_e[i] = elPtr->e(); + m_el_charge[i] = elPtr->charge(); + + m_el_pt_bare[i] = elPtr->auxdata<float>("pt_bare"); + m_el_eta_bare[i] = elPtr->auxdata<float>("eta_bare"); + m_el_phi_bare[i] = elPtr->auxdata<float>("phi_bare"); + m_el_e_bare[i] = elPtr->auxdata<float>("e_bare"); + + if(elPtr->isAvailable<unsigned int>("particleType")) m_el_true_type[i] = elPtr->auxdata<unsigned int>("particleType"); + else if(elPtr->isAvailable<unsigned int>("classifierParticleType")) m_el_true_type[i] = elPtr->auxdata<unsigned int>("classifierParticleType"); + else m_el_true_type[i] = 0; + + if(elPtr->isAvailable<unsigned int>("particleOrigin")) m_el_true_origin[i] = elPtr->auxdata<unsigned int>("particleOrigin"); + else if(elPtr->isAvailable<unsigned int>("classifierParticleOrigin")) m_el_true_origin[i] = elPtr->auxdata<unsigned int>("classifierParticleOrigin"); + else m_el_true_origin[i] = 0; - // Setup the TTree. This should come at the very top in order to make sure - // that event for non-MC data, the TTree will be created (but remains empty). - setupParticleLevelTreeManager( plEvent ); + ++i; + } + } - // No need to attempt to write out anything for non-MC data. - if ( ! m_config->isMC() ){ - return; - } + //muons + if (m_config->useTruthMuons()) { + unsigned int i = 0; + + m_mu_pt.resize(plEvent.m_muons->size()); + m_mu_eta.resize(plEvent.m_muons->size()); + m_mu_phi.resize(plEvent.m_muons->size()); + m_mu_e.resize(plEvent.m_muons->size()); + m_mu_charge.resize(plEvent.m_muons->size()); + + m_mu_pt_bare.resize(plEvent.m_muons->size()); + m_mu_eta_bare.resize(plEvent.m_muons->size()); + m_mu_phi_bare.resize(plEvent.m_muons->size()); + m_mu_e_bare.resize(plEvent.m_muons->size()); + + m_mu_true_type.resize(plEvent.m_muons->size()); + m_mu_true_origin.resize(plEvent.m_muons->size()); + + for (const auto& muPtr : *plEvent.m_muons) { + m_mu_pt[i] = muPtr->pt(); + m_mu_eta[i] = muPtr->eta(); + m_mu_phi[i] = muPtr->phi(); + m_mu_e[i] = muPtr->e(); + m_mu_charge[i] = muPtr->charge(); + + m_mu_pt_bare[i] = muPtr->auxdata<float>("pt_bare"); + m_mu_eta_bare[i] = muPtr->auxdata<float>("eta_bare"); + m_mu_phi_bare[i] = muPtr->auxdata<float>("phi_bare"); + m_mu_e_bare[i] = muPtr->auxdata<float>("e_bare"); + + if(muPtr->isAvailable<unsigned int>("particleType")) m_mu_true_type[i] = muPtr->auxdata<unsigned int>("particleType"); + else if(muPtr->isAvailable<unsigned int>("classifierParticleType")) m_mu_true_type[i] = muPtr->auxdata<unsigned int>("classifierParticleType"); + else m_mu_true_type[i] = 0; + + if(muPtr->isAvailable<unsigned int>("particleOrigin")) m_mu_true_origin[i] = muPtr->auxdata<unsigned int>("particleOrigin"); + else if(muPtr->isAvailable<unsigned int>("classifierParticleOrigin")) m_mu_true_origin[i] = muPtr->auxdata<unsigned int>("classifierParticleOrigin"); + else m_mu_true_origin[i] = 0; - for ( auto & selectionDecision : m_particleLevel_SelectionDecisions ){ - selectionDecision.second = plEvent.m_selectionDecisions[ selectionDecision.first ]; + ++i; + } + + i=0; + if(m_config->useSoftMuons()) { + + m_softmu_pt.resize(plEvent.m_softmuons->size()); + m_softmu_eta.resize(plEvent.m_softmuons->size()); + m_softmu_phi.resize(plEvent.m_softmuons->size()); + m_softmu_e.resize(plEvent.m_softmuons->size()); + m_softmu_charge.resize(plEvent.m_softmuons->size()); + + m_softmu_true_type.resize(plEvent.m_softmuons->size()); + m_softmu_true_origin.resize(plEvent.m_softmuons->size()); + + if(m_config->softmuonAdditionalTruthInfo()) + { + m_softmu_parton_origin_flag.resize(plEvent.m_softmuons->size()); + m_softmu_particle_origin_flag.resize(plEvent.m_softmuons->size()); + m_softmu_parent_pdgid.resize(plEvent.m_softmuons->size()); + m_softmu_b_hadron_parent_pdgid.resize(plEvent.m_softmuons->size()); + m_softmu_c_hadron_parent_pdgid.resize(plEvent.m_softmuons->size()); } - // to get the fixed mc weight - const xAOD::TruthEventContainer * truthEvent(nullptr); - top::check( evtStore()->retrieve(truthEvent, m_config->sgKeyTruthEvent()) , "Failed to retrieve truth event container" ); - unsigned int truthEventSize = truthEvent->size(); - top::check( truthEventSize==1 , "Failed to retrieve truth PDF info - truth event container size is different from 1 (strange)" ); - -// m_weight_mc = plEvent.m_info->mcEventWeight(); - m_weight_mc = truthEvent->at(0)->weights()[0];// FIXME temporary bugfix - - m_eventNumber = plEvent.m_info->eventNumber(); - m_runNumber = plEvent.m_info->runNumber(); - m_mcChannelNumber = plEvent.m_info->mcChannelNumber(); - - m_mu = plEvent.m_info->averageInteractionsPerCrossing(); - - if (m_config->doPileupReweighting() && !m_config->isTruthDxAOD()) { - m_weight_pileup = plEvent.m_info->auxdataConst<float>("PileupWeight"); - m_randomRunNumber = plEvent.m_info->auxdataConst<unsigned int>("RandomRunNumber"); - } - else { - m_weight_pileup = NAN; - m_randomRunNumber = 0; - } - - //electrons - if ( m_config->useTruthElectrons() ){ - unsigned int i = 0; - - m_el_pt.resize(plEvent.m_electrons->size()); - m_el_eta.resize(plEvent.m_electrons->size()); - m_el_phi.resize(plEvent.m_electrons->size()); - m_el_e.resize(plEvent.m_electrons->size()); - m_el_charge.resize(plEvent.m_electrons->size()); - - m_el_pt_bare.resize(plEvent.m_electrons->size()); - m_el_eta_bare.resize(plEvent.m_electrons->size()); - m_el_phi_bare.resize(plEvent.m_electrons->size()); - m_el_e_bare.resize(plEvent.m_electrons->size()); - - for (const auto & elPtr : * plEvent.m_electrons) { - m_el_pt[i] = elPtr->pt(); - m_el_eta[i] = elPtr->eta(); - m_el_phi[i] = elPtr->phi(); - m_el_e[i] = elPtr->e(); - m_el_charge[i] = elPtr->charge(); - - m_el_pt_bare[i] = elPtr->auxdata<float>( "pt_bare" ); - m_el_eta_bare[i] = elPtr->auxdata<float>( "eta_bare" ); - m_el_phi_bare[i] = elPtr->auxdata<float>( "phi_bare" ); - m_el_e_bare[i] = elPtr->auxdata<float>( "e_bare" ); - - ++i; + for (const auto& muPtr : *plEvent.m_softmuons) { + m_softmu_pt[i] = muPtr->pt(); + m_softmu_eta[i] = muPtr->eta(); + m_softmu_phi[i] = muPtr->phi(); + m_softmu_e[i] = muPtr->e(); + m_softmu_charge[i] = muPtr->charge(); + + if(muPtr->isAvailable<unsigned int>("particleType")) m_softmu_true_type[i] = muPtr->auxdata<unsigned int>("particleType"); + else if(muPtr->isAvailable<unsigned int>("classifierParticleType")) m_softmu_true_type[i] = muPtr->auxdata<unsigned int>("classifierParticleType"); + else m_softmu_true_type[i] = 0; + + if(muPtr->isAvailable<unsigned int>("particleOrigin")) m_softmu_true_origin[i] = muPtr->auxdata<unsigned int>("particleOrigin"); + else if(muPtr->isAvailable<unsigned int>("classifierParticleOrigin")) m_softmu_true_origin[i] = muPtr->auxdata<unsigned int>("classifierParticleOrigin"); + else m_softmu_true_origin[i] = 0; + + if(m_config->softmuonAdditionalTruthInfo()) + { + + m_softmu_parton_origin_flag[i]=0; + if(m_config->softmuonAdditionalTruthInfoCheckPartonOrigin()) + { + static const SG::AuxElement::Accessor<top::LepPartonOriginFlag> leppartonoriginflag("LepPartonOriginFlag"); + if(leppartonoriginflag.isAvailable(*muPtr)) m_softmu_parton_origin_flag[i]=static_cast<int>(leppartonoriginflag(*muPtr)); } - } - - //muons - if ( m_config->useTruthMuons() ){ - unsigned int i = 0; - - m_mu_pt.resize(plEvent.m_muons->size()); - m_mu_eta.resize(plEvent.m_muons->size()); - m_mu_phi.resize(plEvent.m_muons->size()); - m_mu_e.resize(plEvent.m_muons->size()); - m_mu_charge.resize(plEvent.m_muons->size()); + m_softmu_particle_origin_flag[i]=0; + m_softmu_parent_pdgid[i]=0; + m_softmu_b_hadron_parent_pdgid[i]=0; + m_softmu_c_hadron_parent_pdgid[i]=0; + static const SG::AuxElement::Accessor<top::LepParticleOriginFlag> lepparticleoriginflag("LepParticleOriginFlag"); + if(lepparticleoriginflag.isAvailable(*muPtr)) m_softmu_particle_origin_flag[i]=static_cast<int>(lepparticleoriginflag(*muPtr)); + + static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> Mother("truthMotherLink"); + const xAOD::TruthParticle* mother = 0; + if(Mother.isAvailable(*muPtr)) mother=Mother(*muPtr); + if(mother) m_softmu_parent_pdgid[i]=mother->pdgId(); + + static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> BMother("truthBMotherLink"); + const xAOD::TruthParticle* Bmother = 0; + if(BMother.isAvailable(*muPtr)) Bmother=BMother(*muPtr); + if(Bmother) m_softmu_b_hadron_parent_pdgid[i]=Bmother->pdgId(); + + static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> CMother("truthCMotherLink"); + const xAOD::TruthParticle* Cmother = 0; + if(CMother.isAvailable(*muPtr)) Cmother=CMother(*muPtr); + if(Cmother) m_softmu_c_hadron_parent_pdgid[i]=Cmother->pdgId(); + + if(m_config->softmuonAdditionalTruthInfoDoVerbose()) asg::msgUserCode::ATH_MSG_INFO("writing truth soft muon with pt="<<m_softmu_pt[i] <<" parton_origin_flag="<<m_softmu_parton_origin_flag[i]<<" particle_origin_flag="<<m_softmu_particle_origin_flag[i]<<" parent_pdg_id="<<m_softmu_parent_pdgid[i]<<" b_hadron_parent_pdg_id="<<m_softmu_b_hadron_parent_pdgid[i]<<" c_hadron_parent_pdg_id="<<m_softmu_c_hadron_parent_pdgid[i]); + } + + ++i; + } + }//end of soft muons part + }//end of muons part + + //photons + if (m_config->useTruthPhotons()) { + unsigned int i(0); + m_ph_pt.resize(plEvent.m_photons->size()); + m_ph_eta.resize(plEvent.m_photons->size()); + m_ph_phi.resize(plEvent.m_photons->size()); + m_ph_e.resize(plEvent.m_photons->size()); + for (const auto* const phPtr : *plEvent.m_photons) { + m_ph_pt[i] = phPtr->pt(); + m_ph_eta[i] = phPtr->eta(); + m_ph_phi[i] = phPtr->phi(); + m_ph_e[i] = phPtr->e(); + + ++i; + } + } - m_mu_pt_bare.resize(plEvent.m_muons->size()); - m_mu_eta_bare.resize(plEvent.m_muons->size()); - m_mu_phi_bare.resize(plEvent.m_muons->size()); - m_mu_e_bare.resize(plEvent.m_muons->size()); + static const SG::AuxElement::ConstAccessor<int> ghostBHadronsFinalCount("GhostBHadronsFinalCount"); + static const SG::AuxElement::ConstAccessor<int> ghostCHadronsFinalCount("GhostCHadronsFinalCount"); + + //jets + if (m_config->useTruthJets()) { + unsigned int i = 0; + + m_jet_pt.resize(plEvent.m_jets->size()); + m_jet_eta.resize(plEvent.m_jets->size()); + m_jet_phi.resize(plEvent.m_jets->size()); + m_jet_e.resize(plEvent.m_jets->size()); + m_jet_Ghosts_BHadron_Final_Count.resize(plEvent.m_jets->size()); + m_jet_Ghosts_CHadron_Final_Count.resize(plEvent.m_jets->size()); + for (const auto& jetPtr : *plEvent.m_jets) { + m_jet_pt[i] = jetPtr->pt(); + m_jet_eta[i] = jetPtr->eta(); + m_jet_phi[i] = jetPtr->phi(); + m_jet_e[i] = jetPtr->e(); + + if(ghostBHadronsFinalCount.isAvailable(*jetPtr)) { + m_jet_Ghosts_BHadron_Final_Count[i] = ghostBHadronsFinalCount(*jetPtr); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostBHadronFinalCount auxdata"); + m_jet_Ghosts_BHadron_Final_Count[i] = 0; + } + + if(ghostCHadronsFinalCount.isAvailable(*jetPtr)) { + m_jet_Ghosts_CHadron_Final_Count[i] = ghostCHadronsFinalCount(*jetPtr); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostCHadronFinalCount auxdata"); + m_jet_Ghosts_CHadron_Final_Count[i] = 0; + } - for (const auto & muPtr : * plEvent.m_muons) { - m_mu_pt[i] = muPtr->pt(); - m_mu_eta[i] = muPtr->eta(); - m_mu_phi[i] = muPtr->phi(); - m_mu_e[i] = muPtr->e(); - m_mu_charge[i] = muPtr->charge(); + ++i; + } + } - m_mu_pt_bare[i] = muPtr->auxdata<float>( "pt_bare" ); - m_mu_eta_bare[i] = muPtr->auxdata<float>( "eta_bare" ); - m_mu_phi_bare[i] = muPtr->auxdata<float>( "phi_bare" ); - m_mu_e_bare[i] = muPtr->auxdata<float>( "e_bare" ); + //large R jets + if (m_config->useTruthLargeRJets()) { + unsigned int i = 0; + + m_ljet_pt.resize(plEvent.m_largeRJets->size()); + m_ljet_eta.resize(plEvent.m_largeRJets->size()); + m_ljet_phi.resize(plEvent.m_largeRJets->size()); + m_ljet_e.resize(plEvent.m_largeRJets->size()); + m_ljet_Ghosts_BHadron_Final_Count.resize(plEvent.m_largeRJets->size()); + m_ljet_Ghosts_CHadron_Final_Count.resize(plEvent.m_largeRJets->size()); + for (const auto& jetPtr : *plEvent.m_largeRJets) { + m_ljet_pt[i] = jetPtr->pt(); + m_ljet_eta[i] = jetPtr->eta(); + m_ljet_phi[i] = jetPtr->phi(); + m_ljet_e[i] = jetPtr->e(); + + if(ghostBHadronsFinalCount.isAvailable(*jetPtr)) { + m_ljet_Ghosts_BHadron_Final_Count[i] = ghostBHadronsFinalCount(*jetPtr); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostBHadronFinalCount auxdata"); + m_ljet_Ghosts_BHadron_Final_Count[i] = 0; + } + + if(ghostCHadronsFinalCount.isAvailable(*jetPtr)) { + m_ljet_Ghosts_CHadron_Final_Count[i] = ghostCHadronsFinalCount(*jetPtr); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostCHadronFinalCount auxdata"); + m_ljet_Ghosts_CHadron_Final_Count[i] = 0; + } - ++i; - } - } + ++i; + } + } - //photons - if (m_config->useTruthPhotons()) { - unsigned int i(0); - m_ph_pt.resize(plEvent.m_photons->size()); - m_ph_eta.resize(plEvent.m_photons->size()); - m_ph_phi.resize(plEvent.m_photons->size()); - m_ph_e.resize(plEvent.m_photons->size()); - for (const auto* const phPtr : * plEvent.m_photons) { - m_ph_pt[i] = phPtr->pt(); - m_ph_eta[i] = phPtr->eta(); - m_ph_phi[i] = phPtr->phi(); - m_ph_e[i] = phPtr->e(); - - ++i; - } + //Taus + if (m_config->useTruthTaus()) { + unsigned int i = 0; + + m_tau_pt.resize(plEvent.m_taus->size()); + m_tau_eta.resize(plEvent.m_taus->size()); + m_tau_phi.resize(plEvent.m_taus->size()); + m_tau_e.resize(plEvent.m_taus->size()); + m_tau_charge.resize(plEvent.m_taus->size()); + m_tau_isHadronic.resize(plEvent.m_taus->size()); + + for (const auto& tauPtr : *plEvent.m_taus) { + m_tau_pt[i] = tauPtr->pt(); + m_tau_eta[i] = tauPtr->eta(); + m_tau_phi[i] = tauPtr->phi(); + m_tau_e[i] = tauPtr->e(); + m_tau_charge[i] = tauPtr->charge(); + if (tauPtr->isAvailable<char>("IsHadronicTau")) { + m_tau_isHadronic[i] = tauPtr->auxdata<char>("IsHadronicTau"); } - //jets - if ( m_config->useTruthJets() ){ - unsigned int i = 0; - - m_jet_pt.resize(plEvent.m_jets->size()); - m_jet_eta.resize(plEvent.m_jets->size()); - m_jet_phi.resize(plEvent.m_jets->size()); - m_jet_e.resize(plEvent.m_jets->size()); - m_jet_Ghosts_BHadron_Final_Count.resize(plEvent.m_jets->size()); - m_jet_Ghosts_CHadron_Final_Count.resize(plEvent.m_jets->size()); - for (const auto & jetPtr : * plEvent.m_jets) { - m_jet_pt[i] = jetPtr->pt(); - m_jet_eta[i] = jetPtr->eta(); - m_jet_phi[i] = jetPtr->phi(); - m_jet_e[i] = jetPtr->e(); - - m_jet_Ghosts_BHadron_Final_Count[i] = jetPtr->auxdata<int>( "GhostBHadronsFinalCount" ); - m_jet_Ghosts_CHadron_Final_Count[i] = jetPtr->auxdata<int>( "GhostCHadronsFinalCount" ); + ++i; + } + } - ++i; - } + if (m_makeRCJets) { + // re-clustered jet substructure + static const SG::AuxElement::ConstAccessor<float> RCSplit12("Split12"); + static const SG::AuxElement::ConstAccessor<float> RCSplit23("Split23"); + + // re-clustered jet substructure from clusters + static const SG::AuxElement::ConstAccessor<float> Tau21_clstr("Tau21_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau32_clstr("Tau32_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau3_clstr("Tau3_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau2_clstr("Tau2_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau1_clstr("Tau1_clstr"); + static const SG::AuxElement::ConstAccessor<float> D2_clstr("D2_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF1_clstr("ECF1_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF2_clstr("ECF2_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF3_clstr("ECF3_clstr"); + static const SG::AuxElement::ConstAccessor<float> d12_clstr("d12_clstr"); + static const SG::AuxElement::ConstAccessor<float> d23_clstr("d23_clstr"); + static const SG::AuxElement::ConstAccessor<float> Qw_clstr("Qw_clstr"); + static const SG::AuxElement::ConstAccessor<float> nconstituent_clstr("nconstituent_clstr"); + + static const SG::AuxElement::ConstAccessor<float> gECF332_clstr("gECF332_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF461_clstr("gECF461_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF322_clstr("gECF322_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF331_clstr("gECF331_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF422_clstr("gECF422_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF441_clstr("gECF441_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF212_clstr("gECF212_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF321_clstr("gECF321_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF311_clstr("gECF311_clstr"); + static const SG::AuxElement::ConstAccessor<float> L1_clstr("L1_clstr"); + static const SG::AuxElement::ConstAccessor<float> L2_clstr("L2_clstr"); + static const SG::AuxElement::ConstAccessor<float> L3_clstr("L3_clstr"); + static const SG::AuxElement::ConstAccessor<float> L4_clstr("L4_clstr"); + static const SG::AuxElement::ConstAccessor<float> L5_clstr("L5_clstr"); + // store also the jet that is rebuilt to calculate the JSS + static const SG::AuxElement::ConstAccessor<float> RRCJet_pt("RRCJet_pt"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_eta("RRCJet_eta"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_phi("RRCJet_phi"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_e("RRCJet_e"); + + + // Initialize the vectors to be saved as branches + unsigned int sizeOfRCjets(plEvent.m_RCJets.size()); + + m_rcjet_pt.clear(); + m_rcjet_eta.clear(); + m_rcjet_phi.clear(); + m_rcjet_e.clear(); + m_rcjet_d12.clear(); + m_rcjet_d23.clear(); + m_rcjetsub_pt.clear(); + m_rcjetsub_eta.clear(); + m_rcjetsub_phi.clear(); + m_rcjetsub_e.clear(); + m_rcjetsub_Ghosts_BHadron_Final_Count.clear(); + m_rcjetsub_Ghosts_CHadron_Final_Count.clear(); + + + m_rcjet_tau32_clstr.clear(); + m_rcjet_tau21_clstr.clear(); + m_rcjet_tau3_clstr.clear(); + m_rcjet_tau2_clstr.clear(); + m_rcjet_tau1_clstr.clear(); + m_rcjet_D2_clstr.clear(); + m_rcjet_ECF1_clstr.clear(); + m_rcjet_ECF2_clstr.clear(); + m_rcjet_ECF3_clstr.clear(); + m_rcjet_d12_clstr.clear(); + m_rcjet_d23_clstr.clear(); + m_rcjet_Qw_clstr.clear(); + m_rcjet_nconstituent_clstr.clear(); + + m_rcjet_gECF332_clstr.clear(); + m_rcjet_gECF461_clstr.clear(); + m_rcjet_gECF322_clstr.clear(); + m_rcjet_gECF331_clstr.clear(); + m_rcjet_gECF422_clstr.clear(); + m_rcjet_gECF441_clstr.clear(); + m_rcjet_gECF212_clstr.clear(); + m_rcjet_gECF321_clstr.clear(); + m_rcjet_gECF311_clstr.clear(); + m_rcjet_L1_clstr.clear(); + m_rcjet_L2_clstr.clear(); + m_rcjet_L3_clstr.clear(); + m_rcjet_L4_clstr.clear(); + m_rcjet_L5_clstr.clear(); + + m_rcjet_pt.resize(sizeOfRCjets, -999.); + m_rcjet_eta.resize(sizeOfRCjets, -999.); + m_rcjet_phi.resize(sizeOfRCjets, -999.); + m_rcjet_e.resize(sizeOfRCjets, -999.); + m_rcjet_d12.resize(sizeOfRCjets, -999.); + m_rcjet_d23.resize(sizeOfRCjets, -999.); + m_rcjetsub_pt.resize(sizeOfRCjets, std::vector<float>()); + m_rcjetsub_eta.resize(sizeOfRCjets, std::vector<float>()); + m_rcjetsub_phi.resize(sizeOfRCjets, std::vector<float>()); + m_rcjetsub_e.resize(sizeOfRCjets, std::vector<float>()); + m_rcjetsub_Ghosts_BHadron_Final_Count.resize(sizeOfRCjets, std::vector<int>()); + m_rcjetsub_Ghosts_CHadron_Final_Count.resize(sizeOfRCjets, std::vector<int>()); + + if (m_useRCJSS || m_useRCAdditionalJSS) { + m_rrcjet_pt.resize(sizeOfRCjets, -999.); + m_rrcjet_eta.resize(sizeOfRCjets, -999.); + m_rrcjet_phi.resize(sizeOfRCjets, -999.); + m_rrcjet_e.resize(sizeOfRCjets, -999.); + } + if (m_useRCJSS) { + m_rcjet_tau32_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_tau21_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_tau1_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_tau2_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_tau3_clstr.resize(sizeOfRCjets, -999.); + + m_rcjet_d12_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_d23_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_Qw_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_nconstituent_clstr.resize(sizeOfRCjets, -999.); + + m_rcjet_D2_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_ECF1_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_ECF2_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_ECF3_clstr.resize(sizeOfRCjets, -999.); + } + if (m_useRCAdditionalJSS) { + m_rcjet_gECF332_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF461_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF322_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF331_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF422_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF441_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF212_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF321_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_gECF311_clstr.resize(sizeOfRCjets, -999.); + + m_rcjet_L1_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_L2_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_L3_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_L4_clstr.resize(sizeOfRCjets, -999.); + m_rcjet_L5_clstr.resize(sizeOfRCjets, -999.); + } + unsigned int i = 0; + for (auto rc_jet : plEvent.m_RCJets) { + m_rcjet_pt[i] = rc_jet->pt(); + m_rcjet_eta[i] = rc_jet->eta(); + m_rcjet_phi[i] = rc_jet->phi(); + m_rcjet_e[i] = rc_jet->e(); + + m_rcjet_d12[i] = (RCSplit12.isAvailable(*rc_jet)) ? RCSplit12(*rc_jet) : -999.; + m_rcjet_d23[i] = (RCSplit23.isAvailable(*rc_jet)) ? RCSplit23(*rc_jet) : -999.; + + if (m_useRCJSS || m_useRCAdditionalJSS) { + m_rrcjet_pt[i] = (RRCJet_pt.isAvailable(*rc_jet)) ? RRCJet_pt(*rc_jet) : -999.; + m_rrcjet_eta[i] = (RRCJet_eta.isAvailable(*rc_jet)) ? RRCJet_eta(*rc_jet) : -999.; + m_rrcjet_phi[i] = (RRCJet_phi.isAvailable(*rc_jet)) ? RRCJet_phi(*rc_jet) : -999.; + m_rrcjet_e[i] = (RRCJet_e.isAvailable(*rc_jet)) ? RRCJet_e(*rc_jet) : -999.; + } + if (m_useRCJSS) { + m_rcjet_tau32_clstr[i] = (Tau32_clstr.isAvailable(*rc_jet)) ? Tau32_clstr(*rc_jet) : -999.; + m_rcjet_tau21_clstr[i] = (Tau21_clstr.isAvailable(*rc_jet)) ? Tau21_clstr(*rc_jet) : -999.; + m_rcjet_tau3_clstr[i] = (Tau3_clstr.isAvailable(*rc_jet)) ? Tau3_clstr(*rc_jet) : -999.; + m_rcjet_tau2_clstr[i] = (Tau2_clstr.isAvailable(*rc_jet)) ? Tau2_clstr(*rc_jet) : -999.; + m_rcjet_tau1_clstr[i] = (Tau1_clstr.isAvailable(*rc_jet)) ? Tau1_clstr(*rc_jet) : -999.; + + m_rcjet_d12_clstr[i] = (d12_clstr.isAvailable(*rc_jet)) ? d12_clstr(*rc_jet) : -999.; + m_rcjet_d23_clstr[i] = (d23_clstr.isAvailable(*rc_jet)) ? d23_clstr(*rc_jet) : -999.; + m_rcjet_Qw_clstr[i] = (Qw_clstr.isAvailable(*rc_jet)) ? Qw_clstr(*rc_jet) : -999.; + m_rcjet_nconstituent_clstr[i] = (nconstituent_clstr.isAvailable(*rc_jet)) ? nconstituent_clstr(*rc_jet) : -999.; + + m_rcjet_D2_clstr[i] = (D2_clstr.isAvailable(*rc_jet)) ? D2_clstr(*rc_jet) : -999.; + m_rcjet_ECF1_clstr[i] = (ECF1_clstr.isAvailable(*rc_jet)) ? ECF1_clstr(*rc_jet) : -999.; + m_rcjet_ECF2_clstr[i] = (ECF2_clstr.isAvailable(*rc_jet)) ? ECF2_clstr(*rc_jet) : -999.; + m_rcjet_ECF3_clstr[i] = (ECF3_clstr.isAvailable(*rc_jet)) ? ECF3_clstr(*rc_jet) : -999.; + } + if (m_useRCAdditionalJSS) { + m_rcjet_gECF332_clstr[i] = (gECF332_clstr.isAvailable(*rc_jet)) ? gECF332_clstr(*rc_jet) : -999.; + m_rcjet_gECF461_clstr[i] = (gECF461_clstr.isAvailable(*rc_jet)) ? gECF461_clstr(*rc_jet) : -999.; + m_rcjet_gECF322_clstr[i] = (gECF322_clstr.isAvailable(*rc_jet)) ? gECF322_clstr(*rc_jet) : -999.; + m_rcjet_gECF331_clstr[i] = (gECF331_clstr.isAvailable(*rc_jet)) ? gECF331_clstr(*rc_jet) : -999.; + m_rcjet_gECF422_clstr[i] = (gECF422_clstr.isAvailable(*rc_jet)) ? gECF422_clstr(*rc_jet) : -999.; + m_rcjet_gECF441_clstr[i] = (gECF441_clstr.isAvailable(*rc_jet)) ? gECF441_clstr(*rc_jet) : -999.; + m_rcjet_gECF212_clstr[i] = (gECF212_clstr.isAvailable(*rc_jet)) ? gECF212_clstr(*rc_jet) : -999.; + m_rcjet_gECF321_clstr[i] = (gECF321_clstr.isAvailable(*rc_jet)) ? gECF321_clstr(*rc_jet) : -999.; + m_rcjet_gECF311_clstr[i] = (gECF311_clstr.isAvailable(*rc_jet)) ? gECF311_clstr(*rc_jet) : -999.; + + m_rcjet_L1_clstr[i] = (L1_clstr.isAvailable(*rc_jet)) ? L1_clstr(*rc_jet) : -999.; + m_rcjet_L2_clstr[i] = (L2_clstr.isAvailable(*rc_jet)) ? L2_clstr(*rc_jet) : -999.; + m_rcjet_L3_clstr[i] = (L3_clstr.isAvailable(*rc_jet)) ? L3_clstr(*rc_jet) : -999.; + m_rcjet_L4_clstr[i] = (L4_clstr.isAvailable(*rc_jet)) ? L4_clstr(*rc_jet) : -999.; + m_rcjet_L5_clstr[i] = (L5_clstr.isAvailable(*rc_jet)) ? L5_clstr(*rc_jet) : -999.; } - //large R jets - if ( m_config->useTruthLargeRJets() ){ - unsigned int i = 0; - - m_ljet_pt.resize(plEvent.m_largeRJets->size()); - m_ljet_eta.resize(plEvent.m_largeRJets->size()); - m_ljet_phi.resize(plEvent.m_largeRJets->size()); - m_ljet_e.resize(plEvent.m_largeRJets->size()); - m_ljet_Ghosts_BHadron_Final_Count.resize(plEvent.m_largeRJets->size()); - m_ljet_Ghosts_CHadron_Final_Count.resize(plEvent.m_largeRJets->size()); - for (const auto & jetPtr : * plEvent.m_largeRJets) { - m_ljet_pt[i] = jetPtr->pt(); - m_ljet_eta[i] = jetPtr->eta(); - m_ljet_phi[i] = jetPtr->phi(); - m_ljet_e[i] = jetPtr->e(); + // loop over subjets + m_rcjetsub_pt[i].clear(); // clear the vector size (otherwise it grows out of control!) + m_rcjetsub_eta[i].clear(); + m_rcjetsub_phi[i].clear(); + m_rcjetsub_e[i].clear(); + + const xAOD::Jet* subjet(nullptr); + for (auto rc_jet_subjet : rc_jet->getConstituents()) { + subjet = static_cast<const xAOD::Jet*>(rc_jet_subjet->rawConstituent()); + m_rcjetsub_pt[i].push_back(subjet->pt()); + m_rcjetsub_eta[i].push_back(subjet->eta()); + m_rcjetsub_phi[i].push_back(subjet->phi()); + m_rcjetsub_e[i].push_back(subjet->e()); + + if(ghostBHadronsFinalCount.isAvailable(*subjet)) { + m_rcjetsub_Ghosts_BHadron_Final_Count[i].push_back(ghostBHadronsFinalCount(*subjet)); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostBHadronFinalCount auxdata"); + m_rcjetsub_Ghosts_BHadron_Final_Count[i].push_back(0); + } + + if(ghostCHadronsFinalCount.isAvailable(*subjet)) { + m_rcjetsub_Ghosts_CHadron_Final_Count[i].push_back(ghostCHadronsFinalCount(*subjet)); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostCHadronFinalCount auxdata"); + m_rcjetsub_Ghosts_CHadron_Final_Count[i].push_back(0); + } + + } // end for-loop over subjets + ++i; + } // end for-loop over re-clustered jets + } - m_ljet_Ghosts_BHadron_Final_Count[i] = jetPtr->auxdata<int>( "GhostBHadronsFinalCount" ); - m_ljet_Ghosts_CHadron_Final_Count[i] = jetPtr->auxdata<int>( "GhostCHadronsFinalCount" ); + // VarRC jets + if (m_makeVarRCJets) { + std::string VarRC = "vrcjet"; + for (auto& rho : m_VarRCJetRho) { + for (auto& mass_scale : m_VarRCJetMassScale) { + std::replace(rho.begin(), rho.end(), '.', '_'); + std::string name = rho + mass_scale; + + // re-clustered jet substructure + static const SG::AuxElement::ConstAccessor<float> VarRCSplit12("Split12"); + static const SG::AuxElement::ConstAccessor<float> VarRCSplit23("Split23"); + // re-clustered jet substructure from clusters + static const SG::AuxElement::ConstAccessor<float> Tau21_clstr("Tau21_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau32_clstr("Tau32_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau3_clstr("Tau3_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau2_clstr("Tau2_clstr"); + static const SG::AuxElement::ConstAccessor<float> Tau1_clstr("Tau1_clstr"); + static const SG::AuxElement::ConstAccessor<float> D2_clstr("D2_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF1_clstr("ECF1_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF2_clstr("ECF2_clstr"); + static const SG::AuxElement::ConstAccessor<float> ECF3_clstr("ECF3_clstr"); + static const SG::AuxElement::ConstAccessor<float> d12_clstr("d12_clstr"); + static const SG::AuxElement::ConstAccessor<float> d23_clstr("d23_clstr"); + static const SG::AuxElement::ConstAccessor<float> Qw_clstr("Qw_clstr"); + + static const SG::AuxElement::ConstAccessor<float> gECF332_clstr("gECF332_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF461_clstr("gECF461_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF322_clstr("gECF322_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF331_clstr("gECF331_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF422_clstr("gECF422_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF441_clstr("gECF441_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF212_clstr("gECF212_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF321_clstr("gECF321_clstr"); + static const SG::AuxElement::ConstAccessor<float> gECF311_clstr("gECF311_clstr"); + static const SG::AuxElement::ConstAccessor<float> L1_clstr("L1_clstr"); + static const SG::AuxElement::ConstAccessor<float> L2_clstr("L2_clstr"); + static const SG::AuxElement::ConstAccessor<float> L3_clstr("L3_clstr"); + static const SG::AuxElement::ConstAccessor<float> L4_clstr("L4_clstr"); + static const SG::AuxElement::ConstAccessor<float> L5_clstr("L5_clstr"); + // store also the jet that is rebuilt to calculate the JSS + static const SG::AuxElement::ConstAccessor<float> RRCJet_pt("RRCJet_pt"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_eta("RRCJet_eta"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_phi("RRCJet_phi"); + static const SG::AuxElement::ConstAccessor<float> RRCJet_e("RRCJet_e"); + + // Initialize the vectors to be saved as branches + + xAOD::JetContainer* vrc_jets = plEvent.m_VarRCJets[name].get(); + unsigned int sizeOfRCjets = vrc_jets->size(); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_pt"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_eta"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_phi"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_e"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d12"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d23"].resize(sizeOfRCjets, -999.); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_pt"].resize(sizeOfRCjets, std::vector<float>()); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_eta"].resize(sizeOfRCjets, std::vector<float>()); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_phi"].resize(sizeOfRCjets, std::vector<float>()); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_e"].resize(sizeOfRCjets, std::vector<float>()); + if (m_useVarRCJSS || m_useVarRCAdditionalJSS) { + m_VarRCjetBranchesParticle["vrrcjet_" + name + "_pt"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle["vrrcjet_" + name + "_eta"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle["vrrcjet_" + name + "_phi"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle["vrrcjet_" + name + "_e"].resize(sizeOfRCjets, -999.); + } + if (m_useVarRCJSS) { + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau32_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau21_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau1_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau2_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau3_clstr"].resize(sizeOfRCjets, -999.); + + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d12_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d23_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_Qw_clstr"].resize(sizeOfRCjets, -999.); + + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_D2_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_ECF1_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_ECF2_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_ECF3_clstr"].resize(sizeOfRCjets, -999.); + } + if (m_useVarRCAdditionalJSS) { + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF332_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF461_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF322_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF331_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF422_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF441_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF212_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF321_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF311_clstr"].resize(sizeOfRCjets, -999.); + + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L1_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L2_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L3_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L4_clstr"].resize(sizeOfRCjets, -999.); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L5_clstr"].resize(sizeOfRCjets, -999.); + } - ++i; - } - } + unsigned int i = 0; - //met - if ( m_config->useTruthMET() ){ - m_met_met = plEvent.m_met->met(); - m_met_phi = plEvent.m_met->phi(); - } + for (auto jet_ptr : *vrc_jets) { + const xAOD::Jet* rc_jet = jet_ptr; - // Let us write the PDF Info into the branch variable(s). - if ( m_config->doTruthPDFInfo() ) { - // Delegate to helper function. - loadPdfInfo(); - } + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_pt"][i] = rc_jet->pt(); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_eta"][i] = rc_jet->eta(); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_phi"][i] = rc_jet->phi(); + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_e"][i] = rc_jet->e(); - if (m_config->doMCGeneratorWeights()) { - // delegate to helper function. - loadMCGeneratorWeights(); - } + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d12"][i] = (VarRCSplit12.isAvailable(*rc_jet)) ? VarRCSplit12(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d23"][i] = (VarRCSplit23.isAvailable(*rc_jet)) ? VarRCSplit23(*rc_jet) : -999.; - // Let us write the PDF weights into the branch variable(s). - if( m_config->saveLHAPDFEvent() ){ - // Delegate to helper function. - loadPdfWeights(); - } + if (m_useVarRCJSS || m_useVarRCAdditionalJSS) { + m_VarRCjetBranchesParticle["vrrcjet_" + name + "_pt"][i] = (RRCJet_pt.isAvailable(*rc_jet)) ? RRCJet_pt(*rc_jet) : -999.; + m_VarRCjetBranchesParticle["vrrcjet_" + name + "_eta"][i] = (RRCJet_eta.isAvailable(*rc_jet)) ? RRCJet_eta(*rc_jet) : -999.; + m_VarRCjetBranchesParticle["vrrcjet_" + name + "_phi"][i] = (RRCJet_phi.isAvailable(*rc_jet)) ? RRCJet_phi(*rc_jet) : -999.; + m_VarRCjetBranchesParticle["vrrcjet_" + name + "_e"][i] = (RRCJet_e.isAvailable(*rc_jet)) ? RRCJet_e(*rc_jet) : -999.; + } + if (m_useVarRCJSS) { + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau32_clstr"][i] = (Tau32_clstr.isAvailable(*rc_jet)) ? Tau32_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau21_clstr"][i] = (Tau21_clstr.isAvailable(*rc_jet)) ? Tau21_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau3_clstr"][i] = (Tau3_clstr.isAvailable(*rc_jet)) ? Tau3_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau2_clstr"][i] = (Tau2_clstr.isAvailable(*rc_jet)) ? Tau2_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_tau1_clstr"][i] = (Tau1_clstr.isAvailable(*rc_jet)) ? Tau1_clstr(*rc_jet) : -999.; + + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d12_clstr"][i] = (d12_clstr.isAvailable(*rc_jet)) ? d12_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_d23_clstr"][i] = (d23_clstr.isAvailable(*rc_jet)) ? d23_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_Qw_clstr"][i] = (Qw_clstr.isAvailable(*rc_jet)) ? Qw_clstr(*rc_jet) : -999.; + + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_D2_clstr"][i] = (D2_clstr.isAvailable(*rc_jet)) ? D2_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_ECF1_clstr"][i] = (ECF1_clstr.isAvailable(*rc_jet)) ? ECF1_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_ECF2_clstr"][i] = (ECF2_clstr.isAvailable(*rc_jet)) ? ECF2_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_ECF3_clstr"][i] = (ECF3_clstr.isAvailable(*rc_jet)) ? ECF3_clstr(*rc_jet) : -999.; + } + if (m_useVarRCAdditionalJSS) { + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF332_clstr"][i] = (gECF332_clstr.isAvailable(*rc_jet)) ? gECF332_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF461_clstr"][i] = (gECF461_clstr.isAvailable(*rc_jet)) ? gECF461_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF322_clstr"][i] = (gECF322_clstr.isAvailable(*rc_jet)) ? gECF322_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF331_clstr"][i] = (gECF331_clstr.isAvailable(*rc_jet)) ? gECF331_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF422_clstr"][i] = (gECF422_clstr.isAvailable(*rc_jet)) ? gECF422_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF441_clstr"][i] = (gECF441_clstr.isAvailable(*rc_jet)) ? gECF441_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF212_clstr"][i] = (gECF212_clstr.isAvailable(*rc_jet)) ? gECF212_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF321_clstr"][i] = (gECF321_clstr.isAvailable(*rc_jet)) ? gECF321_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_gECF311_clstr"][i] = (gECF311_clstr.isAvailable(*rc_jet)) ? gECF311_clstr(*rc_jet) : -999.; + + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L1_clstr"][i] = (L1_clstr.isAvailable(*rc_jet)) ? L1_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L2_clstr"][i] = (L2_clstr.isAvailable(*rc_jet)) ? L2_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L3_clstr"][i] = (L3_clstr.isAvailable(*rc_jet)) ? L3_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L4_clstr"][i] = (L4_clstr.isAvailable(*rc_jet)) ? L4_clstr(*rc_jet) : -999.; + m_VarRCjetBranchesParticle[VarRC + "_" + name + "_L5_clstr"][i] = (L5_clstr.isAvailable(*rc_jet)) ? L5_clstr(*rc_jet) : -999.; + } - if(m_config->doPseudoTop()){ + // loop over subjets + const xAOD::Jet* subjet(nullptr); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_pt"][i].clear(); // clear the vector size + // (otherwise it grows out of + // control!) + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_eta"][i].clear(); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_phi"][i].clear(); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_e"][i].clear(); + for (auto rc_jet_subjet : rc_jet->getConstituents()) { + subjet = static_cast<const xAOD::Jet*>(rc_jet_subjet->rawConstituent()); + + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_pt"][i].push_back(subjet->pt()); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_eta"][i].push_back(subjet->eta()); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_phi"][i].push_back(subjet->phi()); + m_VarRCjetsubBranchesParticle[VarRC + "_" + name + "_sub_e"][i].push_back(subjet->e()); + } // end for-loop over subjets + ++i; + } // end for-loop over re-clustered jets + } // end loop over mass parameters + } // end loop over multipliers for mass scale + } // end if make VarRC jets + // end VarRC jets - const xAOD::PseudoTopResultContainer* pseudoTopResultContainer(nullptr); - const xAOD::PseudoTopResult* pseudoTopResult(nullptr); - if (evtStore()->contains<xAOD::PseudoTopResultContainer>(m_config->sgKeyPseudoTop(0))) { - top::check(evtStore()->retrieve(pseudoTopResultContainer, m_config->sgKeyPseudoTop(0)), "Failed to retrieve PseudoTop"); - pseudoTopResult = pseudoTopResultContainer->at(0); + //met + if (m_config->useTruthMET()) { + m_met_met = plEvent.m_met->met(); + m_met_phi = plEvent.m_met->phi(); + } - m_PseudoTop_Particle_ttbar_pt = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_ttbar_pt"); - m_PseudoTop_Particle_ttbar_eta = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_ttbar_eta"); - m_PseudoTop_Particle_ttbar_phi = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_ttbar_phi"); - m_PseudoTop_Particle_ttbar_m = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_ttbar_m"); + if (m_config->doPseudoTop()) { + const xAOD::PseudoTopResultContainer* pseudoTopResultContainer(nullptr); + const xAOD::PseudoTopResult* pseudoTopResult(nullptr); - m_PseudoTop_Particle_top_lep_pt = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_top_lep_pt"); - m_PseudoTop_Particle_top_lep_eta = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_top_lep_eta"); - m_PseudoTop_Particle_top_lep_phi = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_top_lep_phi"); - m_PseudoTop_Particle_top_lep_m = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_top_lep_m"); + if (evtStore()->contains<xAOD::PseudoTopResultContainer>(m_config->sgKeyPseudoTop(0))) { + top::check(evtStore()->retrieve(pseudoTopResultContainer, m_config->sgKeyPseudoTop(0)), "Failed to retrieve PseudoTop"); - m_PseudoTop_Particle_top_had_pt = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_top_had_pt"); - m_PseudoTop_Particle_top_had_eta = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_top_had_eta"); - m_PseudoTop_Particle_top_had_phi = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_top_had_phi"); - m_PseudoTop_Particle_top_had_m = pseudoTopResult -> auxdecor<float>("PseudoTop_Particle_top_had_m"); + pseudoTopResult = pseudoTopResultContainer->at(0); + m_PseudoTop_Particle_ttbar_pt = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_ttbar_pt"); + m_PseudoTop_Particle_ttbar_eta = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_ttbar_eta"); + m_PseudoTop_Particle_ttbar_phi = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_ttbar_phi"); + m_PseudoTop_Particle_ttbar_m = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_ttbar_m"); - } - } + m_PseudoTop_Particle_top_lep_pt = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_top_lep_pt"); + m_PseudoTop_Particle_top_lep_eta = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_top_lep_eta"); + m_PseudoTop_Particle_top_lep_phi = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_top_lep_phi"); + m_PseudoTop_Particle_top_lep_m = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_top_lep_m"); + m_PseudoTop_Particle_top_had_pt = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_top_had_pt"); + m_PseudoTop_Particle_top_had_eta = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_top_had_eta"); + m_PseudoTop_Particle_top_had_phi = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_top_had_phi"); + m_PseudoTop_Particle_top_had_m = pseudoTopResult->auxdecor<float>("PseudoTop_Particle_top_had_m"); + } + } + } + void EventSaverFlatNtuple::fillParticleLevelEvent() { + //do it! + m_particleLevelTreeManager->fill(); + } - //do it! - m_particleLevelTreeManager->fill(); + void EventSaverFlatNtuple::saveUpgradeEvent(const top::ParticleLevelEvent& upgradeEvent) { + // Quick return if upgrade is disabled. + if (not m_config->HLLHC()) { + return; + } + // No need to attempt to write out anything for non-MC data. + if (!m_config->isMC()) { + return; + } + this->cleanUpgradeEvent(); + this->calculateUpgradeEvent(upgradeEvent); + this->fillUpgradeEvent(); + } + + void EventSaverFlatNtuple::cleanUpgradeEvent() { + /* Doing nothing for now, but we should put here the (re-)initialisation to dummy values + * of all variables later calculated in calculateParticleLevelEvent(const top::ParticleLevelEvent& plEvent) + * For example all weights set to 1, all vectors cleaned, all kinematic or angular variables set to -99999. + */ + } + + void EventSaverFlatNtuple::calculateUpgradeEvent(const top::ParticleLevelEvent& upgradeEvent) { + for (auto& selectionDecision : m_upgrade_SelectionDecisions) { + selectionDecision.second = upgradeEvent.m_selectionDecisions[ selectionDecision.first ]; } - void EventSaverFlatNtuple::saveUpgradeEvent(const top::ParticleLevelEvent& upgradeEvent){ - // Quick return if upgrade is disabled. No tree will be created! - if ( not m_config->HLLHC() ){ - return; - } - - // Setup the TTree. This should come at the very top in order to make sure - // that event for non-MC data, the TTree will be created (but remains empty). - setupUpgradeTreeManager( /*upgradeEvent*/ ); + m_weight_mc = upgradeEvent.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); + + m_eventNumber = upgradeEvent.m_info->eventNumber(); + m_runNumber = upgradeEvent.m_info->runNumber(); + m_mcChannelNumber = upgradeEvent.m_info->mcChannelNumber(); + + m_mu = upgradeEvent.m_info->averageInteractionsPerCrossing(); + m_mu_actual = upgradeEvent.m_info->actualInteractionsPerCrossing(); + + // save electrons + unsigned int i = 0; + m_el_pt.resize(upgradeEvent.m_electrons->size()); + m_el_eta.resize(upgradeEvent.m_electrons->size()); + m_el_phi.resize(upgradeEvent.m_electrons->size()); + m_el_e.resize(upgradeEvent.m_electrons->size()); + m_el_etcone20.resize(upgradeEvent.m_electrons->size()); + m_el_ptcone30.resize(upgradeEvent.m_electrons->size()); + m_el_charge.resize(upgradeEvent.m_electrons->size()); + m_el_true_type.resize(upgradeEvent.m_electrons->size()); + m_el_true_origin.resize(upgradeEvent.m_electrons->size()); + //m_el_true_firstEgMotherTruthOrigin.resize(upgradeEvent.m_electrons->size()); + //m_el_true_firstEgMotherTruthType.resize(upgradeEvent.m_electrons->size()); + //m_el_true_isPrompt.resize(upgradeEvent.m_electrons->size()); + if (m_config->HLLHCFakes()) m_el_faketype.resize(upgradeEvent.m_electrons->size()); + + for (const auto elPtr : *upgradeEvent.m_electrons) { + m_el_pt[i] = elPtr->pt(); + m_el_eta[i] = elPtr->eta(); + m_el_phi[i] = elPtr->phi(); + m_el_e[i] = elPtr->e(); + m_el_charge[i] = elPtr->charge(); + + m_el_true_type[i] = 0; + m_el_true_origin[i] = 0; + //m_el_true_firstEgMotherTruthType[i] = 0; + //m_el_true_firstEgMotherTruthOrigin[i] = 0; + //m_el_true_isPrompt[i] = 0; + + if (elPtr->isAvailable<float>("etcone20")) { + m_el_etcone20[i] = elPtr->auxdata<float>("etcone20"); + } else { + m_el_etcone20[i] = -999; + } + if (elPtr->isAvailable<float>("ptcone30")) { + m_el_ptcone30[i] = elPtr->auxdata<float>("ptcone30"); + } else { + m_el_ptcone30[i] = -999; + } - // No need to attempt to write out anything for non-MC data. - if ( ! m_config->isMC() ){ - return; + if (!m_config->HLLHCFakes()) { + if (elPtr->isAvailable<unsigned int>("particleType")) { + m_el_true_type[i] = elPtr->auxdata<unsigned int>("particleType"); + } else if (elPtr->isAvailable<unsigned int>("classifierParticleType")) { + m_el_true_type[i] = elPtr->auxdata<unsigned int>("classifierParticleType"); + } else { + top::check(false, "Could not obtain truth Type decoration for electron!"); } - - // to get the fixed mc weight - const xAOD::TruthEventContainer * truthEvent(nullptr); - top::check( evtStore()->retrieve(truthEvent, m_config->sgKeyTruthEvent()) , "Failed to retrieve truth event container" ); - unsigned int truthEventSize = truthEvent->size(); - top::check( truthEventSize==1 , "Failed to retrieve truth PDF info - truth event container size is different from 1 (strange)" ); - -// m_weight_mc = plEvent.m_info->mcEventWeight(); - m_weight_mc = truthEvent->at(0)->weights()[0];// FIXME temporary bugfix - - m_eventNumber = upgradeEvent.m_info->eventNumber(); - m_runNumber = upgradeEvent.m_info->runNumber(); - m_mcChannelNumber = upgradeEvent.m_info->mcChannelNumber(); - - m_mu = upgradeEvent.m_info->averageInteractionsPerCrossing(); - - // save electrons - unsigned int i = 0; - m_el_pt.resize(upgradeEvent.m_electrons->size()); - m_el_eta.resize(upgradeEvent.m_electrons->size()); - m_el_phi.resize(upgradeEvent.m_electrons->size()); - m_el_e.resize(upgradeEvent.m_electrons->size()); - m_el_charge.resize(upgradeEvent.m_electrons->size()); - - for (const auto elPtr : * upgradeEvent.m_electrons) { - m_el_pt[i] = elPtr->pt(); - m_el_eta[i] = elPtr->eta(); - m_el_phi[i] = elPtr->phi(); - m_el_e[i] = elPtr->e(); - m_el_charge[i] = elPtr->charge(); - ++i; - } - - // save muons - i = 0; - m_mu_pt.resize(upgradeEvent.m_muons->size()); - m_mu_eta.resize(upgradeEvent.m_muons->size()); - m_mu_phi.resize(upgradeEvent.m_muons->size()); - m_mu_e.resize(upgradeEvent.m_muons->size()); - m_mu_charge.resize(upgradeEvent.m_muons->size()); - - for (const auto muPtr : * upgradeEvent.m_muons) { - m_mu_pt[i] = muPtr->pt(); - m_mu_eta[i] = muPtr->eta(); - m_mu_phi[i] = muPtr->phi(); - m_mu_e[i] = muPtr->e(); - m_mu_charge[i] = muPtr->charge(); - ++i; - } - - // save jets - i = 0; - m_jet_pt.resize(upgradeEvent.m_jets->size()); - m_jet_eta.resize(upgradeEvent.m_jets->size()); - m_jet_phi.resize(upgradeEvent.m_jets->size()); - m_jet_e.resize(upgradeEvent.m_jets->size()); - m_jet_mv1eff.resize(upgradeEvent.m_jets->size()); - m_jet_isPileup.resize(upgradeEvent.m_jets->size()); - m_jet_Ghosts_BHadron_Final_Count.resize(upgradeEvent.m_jets->size()); - m_jet_Ghosts_CHadron_Final_Count.resize(upgradeEvent.m_jets->size()); - for (const auto & jetPtr : * upgradeEvent.m_jets) { - m_jet_pt[i] = jetPtr->pt(); - m_jet_eta[i] = jetPtr->eta(); - m_jet_phi[i] = jetPtr->phi(); - m_jet_e[i] = jetPtr->e(); - - m_jet_mv1eff[i] = jetPtr->auxdata<float>("mv1TagEff"); - - if(jetPtr->auxdata<int>("pileUp")==0) { - m_jet_isPileup[i]=0; - m_jet_Ghosts_BHadron_Final_Count[i] = jetPtr->auxdata<int>( "GhostBHadronsFinalCount" ); - m_jet_Ghosts_CHadron_Final_Count[i] = jetPtr->auxdata<int>( "GhostCHadronsFinalCount" ); - } else { - m_jet_isPileup[i]=1; - m_jet_Ghosts_BHadron_Final_Count[i] = 0; - m_jet_Ghosts_CHadron_Final_Count[i] = 0; - } - - ++i; - } - - // MET - m_met_met = upgradeEvent.m_met->met(); - m_met_phi = upgradeEvent.m_met->phi(); - - // fill the tree - m_upgradeTreeManager->fill(); - - }//saveUpgradeEvent - - void EventSaverFlatNtuple::finalize() - { - m_outputFile->Write(); - } - - void EventSaverFlatNtuple::loadPdfInfo(){ - const xAOD::TruthEventContainer * truthEvent(nullptr); - top::check( evtStore()->retrieve(truthEvent, m_config->sgKeyTruthEvent()) , "Failed to retrieve truth PDF info" ); - - if (truthEvent != nullptr) { - unsigned int i(0); - unsigned int truthEventSize = truthEvent->size(); - m_PDFinfo_X1.resize(truthEventSize); - m_PDFinfo_X2.resize(truthEventSize); - m_PDFinfo_PDGID1.resize(truthEventSize); - m_PDFinfo_PDGID2.resize(truthEventSize); - m_PDFinfo_Q.resize(truthEventSize); - m_PDFinfo_XF1.resize(truthEventSize); - m_PDFinfo_XF2.resize(truthEventSize); - - for (const auto * const tePtr : * truthEvent) { - // LMTODO: ASG tools/pdfInfo() can't be used yet, since scale Q is not available - // xAOD::TruthEvent::PdfInfo _pdfInfo=tePtr->pdfInfo(); - // if _pdfInfo.valid() { m_PDFinfo_X1[i] = _pdfInfo.x1; //etc. } - std::string PDFinfoVarName="X1"; - if (truthEvent->isAvailable<float>(PDFinfoVarName)) - m_PDFinfo_X1[i] = (*tePtr).auxdataConst< float >( PDFinfoVarName ); - PDFinfoVarName="X2"; - if (truthEvent->isAvailable<float>(PDFinfoVarName)) - m_PDFinfo_X2[i] = (*tePtr).auxdataConst< float >( PDFinfoVarName ); - PDFinfoVarName="PDGID1"; - if (truthEvent->isAvailable<int>(PDFinfoVarName)) - m_PDFinfo_PDGID1[i] = (*tePtr).auxdataConst< int >( PDFinfoVarName ); - PDFinfoVarName="PDGID2"; - if (truthEvent->isAvailable<int>(PDFinfoVarName)) - m_PDFinfo_PDGID2[i] = (*tePtr).auxdataConst< int >( PDFinfoVarName ); - PDFinfoVarName="XF1"; - if (truthEvent->isAvailable<float>(PDFinfoVarName)) - m_PDFinfo_XF1[i] = (*tePtr).auxdataConst< float >( PDFinfoVarName ); - PDFinfoVarName="XF2"; - if (truthEvent->isAvailable<float>(PDFinfoVarName)) - m_PDFinfo_XF2[i] = (*tePtr).auxdataConst< float >( PDFinfoVarName ); - PDFinfoVarName="Q"; - if (truthEvent->isAvailable<float>(PDFinfoVarName)) - m_PDFinfo_Q[i] = (*tePtr).auxdataConst< float >( PDFinfoVarName ); - ++i; - } + if (elPtr->isAvailable<unsigned int>("particleOrigin")) { + m_el_true_origin[i] = elPtr->auxdata<unsigned int>("particleOrigin"); + } else if (elPtr->isAvailable<unsigned int>("classifierParticleOrigin")) { + m_el_true_origin[i] = elPtr->auxdata<unsigned int>("classifierParticleOrigin"); + } else { + top::check(false, "Could not obtain truth Origin decoration for electron!"); + } + //if (elPtr->isAvailable<unsigned int>("firstEgMotherTruthType")) { + // m_el_true_firstEgMotherTruthType[i] = elPtr->auxdata<unsigned int>("firstEgMotherTruthType"); + //} else { + // top::check(false, "Could not obtain mother's truth Type decoration for electron!"); + //} + //if (elPtr->isAvailable<unsigned int>("firstEgMotherTruthOrigin")) { + // m_el_true_firstEgMotherTruthOrigin[i] = elPtr->auxdata<unsigned int>("firstEgMotherTruthOrigin"); + //} else { + // top::check(false, "Could not obtain mother's truth Origin decoration for electron!"); + //} + //m_el_true_isPrompt[i] = isPromptElectron(m_el_true_type[i], m_el_true_origin[i], + // m_el_true_firstEgMotherTruthType[i], m_el_true_firstEgMotherTruthOrigin[i]); + } else { + if (elPtr->isAvailable<int>("FakeType")) { + m_el_faketype[i] = elPtr->auxdata<int>("FakeType"); + } else { + top::check(false, "Could not obtain FakeType decoration for electron!"); } + if (m_el_faketype[i] == 0) { // truthType/Origin only available for true electron (also for electron fake, but + // we are not interested in its truth info) + if (elPtr->isAvailable<unsigned int>("particleType")) { + m_el_true_type[i] = elPtr->auxdata<unsigned int>("particleType"); + } else if (elPtr->isAvailable<unsigned int>("classifierParticleType")) { + m_el_true_type[i] = elPtr->auxdata<unsigned int>("classifierParticleType"); + } else { + top::check(false, "Could not obtain truth Type decoration for electron!"); + } + if (elPtr->isAvailable<unsigned int>("particleOrigin")) { + m_el_true_origin[i] = elPtr->auxdata<unsigned int>("particleOrigin"); + } else if (elPtr->isAvailable<unsigned int>("classifierParticleOrigin")) { + m_el_true_origin[i] = elPtr->auxdata<unsigned int>("classifierParticleOrigin"); + } else { + top::check(false, "Could not obtain truth Origin decoration for electron!"); + } + //if (elPtr->isAvailable<unsigned int>("firstEgMotherTruthType")) { + // m_el_true_firstEgMotherTruthType[i] = elPtr->auxdata<unsigned int>("firstEgMotherTruthType"); + //} else { + // top::check(false, "Could not obtain mother's truth Type decoration for electron!"); + //} + //if (elPtr->isAvailable<unsigned int>("firstEgMotherTruthOrigin")) { + // m_el_true_firstEgMotherTruthOrigin[i] = elPtr->auxdata<unsigned int>("firstEgMotherTruthOrigin"); + //} else { + // top::check(false, "Could not obtain mother's truth Origin decoration for electron!"); + //} + //m_el_true_isPrompt[i] = isPromptElectron(m_el_true_type[i], m_el_true_origin[i], + // m_el_true_firstEgMotherTruthType[i], m_el_true_firstEgMotherTruthOrigin[i]); + } + } + + ++i; } - void EventSaverFlatNtuple::loadPdfWeights(){ - const xAOD::TruthEventContainer * truthEvent(nullptr); - top::check( evtStore()->retrieve(truthEvent, m_config->sgKeyTruthEvent()) , "Failed to retrieve truth PDF info" ); + // save muons + i = 0; + m_mu_pt.resize(upgradeEvent.m_muons->size()); + m_mu_eta.resize(upgradeEvent.m_muons->size()); + m_mu_phi.resize(upgradeEvent.m_muons->size()); + m_mu_e.resize(upgradeEvent.m_muons->size()); + m_mu_etcone20.resize(upgradeEvent.m_muons->size()); + m_mu_ptcone30.resize(upgradeEvent.m_muons->size()); + m_mu_charge.resize(upgradeEvent.m_muons->size()); + m_mu_true_type.resize(upgradeEvent.m_muons->size()); + m_mu_true_origin.resize(upgradeEvent.m_muons->size()); + m_mu_true_isPrompt.resize(upgradeEvent.m_muons->size()); + m_mu_prodVtx_z.resize(upgradeEvent.m_muons->size()); + m_mu_prodVtx_perp.resize(upgradeEvent.m_muons->size()); + m_mu_prodVtx_phi.resize(upgradeEvent.m_muons->size()); + + for (const auto muPtr : *upgradeEvent.m_muons) { + m_mu_pt[i] = muPtr->pt(); + m_mu_eta[i] = muPtr->eta(); + m_mu_phi[i] = muPtr->phi(); + m_mu_e[i] = muPtr->e(); + m_mu_charge[i] = muPtr->charge(); + + m_mu_true_type[i] = 0; + m_mu_true_origin[i] = 0; + m_mu_true_isPrompt[i] = 0; + m_mu_prodVtx_z[i] = -999; + m_mu_prodVtx_perp[i] = -999; + m_mu_prodVtx_phi[i] = -999; + if (muPtr->isAvailable<unsigned int>("particleType")) { + m_mu_true_type[i] = muPtr->auxdata<unsigned int>("particleType"); + } else if (muPtr->isAvailable<unsigned int>("classifierParticleType")) { + m_mu_true_type[i] = muPtr->auxdata<unsigned int>("classifierParticleType"); + } else { + top::check(false, "Could not obtain truth Type decoration for muon!"); + } + if (muPtr->isAvailable<unsigned int>("particleOrigin")) { + m_mu_true_origin[i] = muPtr->auxdata<unsigned int>("particleOrigin"); + } else if (muPtr->isAvailable<unsigned int>("classifierParticleOrigin")) { + m_mu_true_origin[i] = muPtr->auxdata<unsigned int>("classifierParticleOrigin"); + } else { + top::check(false, "Could not obtain truth Origin decoration for muon!"); + } + m_mu_true_isPrompt[i] = isPromptMuon(m_mu_true_type[i], m_mu_true_origin[i]); + if (muPtr->isAvailable<float>("prodVtx_z")) { + m_mu_prodVtx_z[i] = muPtr->auxdata<float>("prodVtx_z"); + } + if (muPtr->isAvailable<float>("prodVtx_perp")) { + m_mu_prodVtx_perp[i] = muPtr->auxdata<float>("prodVtx_perp"); + } + if (muPtr->isAvailable<float>("etcone20")) { + m_mu_etcone20[i] = muPtr->auxdata<float>("etcone20"); + } else { + m_mu_etcone20[i] = -999; + } + if (muPtr->isAvailable<float>("ptcone30")) { + m_mu_ptcone30[i] = muPtr->auxdata<float>("ptcone30"); + } else { + m_mu_ptcone30[i] = -999; + } + if (muPtr->isAvailable<float>("prodVtx_phi")) { + m_mu_prodVtx_phi[i] = muPtr->auxdata<float>("prodVtx_phi"); + } - for( auto tePtr : * truthEvent ){ - for( const std::string & pdf_name : m_config->LHAPDFSets() ){ - if( tePtr->isAvailable<std::vector<float> >( "AnalysisTop_" + pdf_name + "_Weights") ){ - m_PDF_eventWeights[ pdf_name ] = tePtr->auxdata<std::vector<float> >("AnalysisTop_" + pdf_name + "_Weights"); - } - } - } + ++i; } - void EventSaverFlatNtuple::loadMCGeneratorWeights(){ - const xAOD::TruthEventContainer * truthEvent(nullptr); - top::check( evtStore()->retrieve(truthEvent, m_config->sgKeyTruthEvent()) , "Failed to retrieve MC Generator weights - impossible to retrieve truth event container" ); - unsigned int truthEventSize = truthEvent->size(); - top::check( truthEventSize==1 , "Failed to retrieve truth PDF info - truth event container size is different from 1 (strange)" ); - m_mc_generator_weights = truthEvent->at(0)->weights(); + static const SG::AuxElement::ConstAccessor<int> ghostBHadronsFinalCount("GhostBHadronsFinalCount"); + static const SG::AuxElement::ConstAccessor<int> ghostCHadronsFinalCount("GhostCHadronsFinalCount"); + + // save jets + i = 0; + m_jet_pt.resize(upgradeEvent.m_jets->size()); + m_jet_eta.resize(upgradeEvent.m_jets->size()); + m_jet_phi.resize(upgradeEvent.m_jets->size()); + m_jet_e.resize(upgradeEvent.m_jets->size()); + m_jet_mv1eff.resize(upgradeEvent.m_jets->size()); + m_jet_isPileup.resize(upgradeEvent.m_jets->size()); + m_jet_Ghosts_BHadron_Final_Count.resize(upgradeEvent.m_jets->size()); + m_jet_Ghosts_CHadron_Final_Count.resize(upgradeEvent.m_jets->size()); + for (const auto& jetPtr : *upgradeEvent.m_jets) { + m_jet_pt[i] = jetPtr->pt(); + m_jet_eta[i] = jetPtr->eta(); + m_jet_phi[i] = jetPtr->phi(); + m_jet_e[i] = jetPtr->e(); + + m_jet_mv1eff[i] = jetPtr->auxdata<float>("mv1TagEff"); + + if (jetPtr->auxdata<int>("pileUp") == 0) { + m_jet_isPileup[i] = 0; + + if(ghostBHadronsFinalCount.isAvailable(*jetPtr)) { + m_jet_Ghosts_BHadron_Final_Count[i] = ghostBHadronsFinalCount(*jetPtr); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostBHadronFinalCount auxdata"); + m_jet_Ghosts_BHadron_Final_Count[i] = 0; + } + + if(ghostCHadronsFinalCount.isAvailable(*jetPtr)) { + m_jet_Ghosts_CHadron_Final_Count[i] = ghostCHadronsFinalCount(*jetPtr); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostCHadronFinalCount auxdata"); + m_jet_Ghosts_CHadron_Final_Count[i] = 0; + } + + } else { + m_jet_isPileup[i] = 1; + m_jet_Ghosts_BHadron_Final_Count[i] = 0; + m_jet_Ghosts_CHadron_Final_Count[i] = 0; + } + + ++i; } + //large R jets + if (m_config->useTruthLargeRJets()) { + unsigned int i = 0; + + m_ljet_pt.resize(upgradeEvent.m_largeRJets->size()); + m_ljet_eta.resize(upgradeEvent.m_largeRJets->size()); + m_ljet_phi.resize(upgradeEvent.m_largeRJets->size()); + m_ljet_e.resize(upgradeEvent.m_largeRJets->size()); + m_ljet_Ghosts_BHadron_Final_Count.resize(upgradeEvent.m_largeRJets->size()); + m_ljet_Ghosts_CHadron_Final_Count.resize(upgradeEvent.m_largeRJets->size()); + for (const auto& jetPtr : *upgradeEvent.m_largeRJets) { + m_ljet_pt[i] = jetPtr->pt(); + m_ljet_eta[i] = jetPtr->eta(); + m_ljet_phi[i] = jetPtr->phi(); + m_ljet_e[i] = jetPtr->e(); + + if(ghostBHadronsFinalCount.isAvailable(*jetPtr)) { + m_ljet_Ghosts_BHadron_Final_Count[i] = ghostBHadronsFinalCount(*jetPtr); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostBHadronFinalCount auxdata"); + m_ljet_Ghosts_BHadron_Final_Count[i] = 0; + } + + if(ghostCHadronsFinalCount.isAvailable(*jetPtr)) { + m_ljet_Ghosts_CHadron_Final_Count[i] = ghostCHadronsFinalCount(*jetPtr); + } + else { + ATH_MSG_DEBUG("Found a jet with no GhostCHadronFinalCount auxdata"); + m_ljet_Ghosts_CHadron_Final_Count[i] = 0; + } - // This bit is new - // It is not optimal and can do with a lot of improvement - // Consider it a first pass - // - // We can save xAOD objects into flat ntuple by looking at their SG::AuxElement data - // - // inspired by: - // https://svnweb.cern.ch/trac/atlasoff/browser/Event/xAOD/xAODCore/tags/xAODCore-00-00-93/Root/PrintHelpers.cxx + ++i; + } + } - void EventSaverFlatNtuple::registerObjectIntoTruthTree(const SG::AuxElement& obj) - { - // If the container doesn't have an auxiliary store, bail now: - if (!obj.container()->getConstStore()) - return; - - // Get a convenience pointer to the aux type registry: - SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance(); - - // Get the auxiliary IDs of the object: - const SG::auxid_set_t& auxids = - ( obj.container()->getConstStore() ? - obj.container()->getConstStore()->getAuxIDs() : - obj.getConstStore()->getAuxIDs() ); - - // find the variables and fill them - for (SG::auxid_t auxid : auxids) { - // get the type of the variable - const std::type_info* ti = reg.getType( auxid ); - // get the name of the variable - const std::string name = reg.getName( auxid ); - - // Add variable - if (*ti == typeid( int ) ){ - m_extraTruthVars_int.insert( std::make_pair( name , new int ) ); - } - else if (*ti == typeid( float ) ){ - m_extraTruthVars_float.insert( std::make_pair( name , new float ) ); + //photons + if (m_config->useTruthPhotons()) { + unsigned int i(0); + m_ph_pt.resize(upgradeEvent.m_photons->size()); + m_ph_eta.resize(upgradeEvent.m_photons->size()); + m_ph_phi.resize(upgradeEvent.m_photons->size()); + m_ph_e.resize(upgradeEvent.m_photons->size()); + m_ph_true_type.resize(upgradeEvent.m_photons->size()); + m_ph_true_origin.resize(upgradeEvent.m_photons->size()); + if (m_config->HLLHCFakes()) m_ph_faketype.resize(upgradeEvent.m_photons->size()); + + for (const auto* const phPtr : *upgradeEvent.m_photons) { + m_ph_pt[i] = phPtr->pt(); + m_ph_eta[i] = phPtr->eta(); + m_ph_phi[i] = phPtr->phi(); + m_ph_e[i] = phPtr->e(); + if (!m_config->HLLHCFakes()) { + if (phPtr->isAvailable<unsigned int>("particleType")) { + m_ph_true_type[i] = phPtr->auxdata<unsigned int>("particleType"); + } else if (phPtr->isAvailable<unsigned int>("classifierParticleType")) { + m_ph_true_type[i] = phPtr->auxdata<unsigned int>("classifierParticleType"); + } else { + top::check(false, "Could not obtain truth Type decoration for photon!"); + } + if (phPtr->isAvailable<unsigned int>("particleOrigin")) { + m_ph_true_origin[i] = phPtr->auxdata<unsigned int>("particleOrigin"); + } else if (phPtr->isAvailable<unsigned int>("classifierParticleOrigin")) { + m_ph_true_origin[i] = phPtr->auxdata<unsigned int>("classifierParticleOrigin"); + } else { + top::check(false, "Could not obtain truth Origin decoration for photon!"); + } + } else { + if (phPtr->isAvailable<int>("FakeType")) { + m_ph_faketype[i] = phPtr->auxdata<int>("FakeType"); + } else { + top::check(false, "Could not obtain FakeType decoration for photon!"); + } + if (m_ph_faketype[i] == 0) { // truthType/Origin only available for true photon (also for electron fake, but + // we are not interested in its truth info) + if (phPtr->isAvailable<unsigned int>("particleType")) { + m_ph_true_type[i] = phPtr->auxdata<unsigned int>("particleType"); + } else if (phPtr->isAvailable<unsigned int>("classifierParticleType")) { + m_ph_true_type[i] = phPtr->auxdata<unsigned int>("classifierParticleType"); + } else { + top::check(false, "Could not obtain truth Type decoration for photon!"); } - else { - ATH_MSG_INFO("insertObjectIntoTruthTree - you need another variable map for more types!"); + if (phPtr->isAvailable<unsigned int>("particleOrigin")) { + m_ph_true_origin[i] = phPtr->auxdata<unsigned int>("particleOrigin"); + } else if (phPtr->isAvailable<unsigned int>("classifierParticleOrigin")) { + m_ph_true_origin[i] = phPtr->auxdata<unsigned int>("classifierParticleOrigin"); + } else { + top::check(false, "Could not obtain truth Origin decoration for photon!"); } + } } - // add the variables to the truthTreeManager - for (std::unordered_map<std::string,int*>::const_iterator i=m_extraTruthVars_int.begin();i!=m_extraTruthVars_int.end();++i) { - m_truthTreeManager->makeOutputVariable(*(*i).second,(*i).first); - } - for (std::unordered_map<std::string,float*>::const_iterator i=m_extraTruthVars_float.begin();i!=m_extraTruthVars_float.end();++i) { - m_truthTreeManager->makeOutputVariable(*(*i).second,(*i).first); - } + ++i; + } } - void EventSaverFlatNtuple::saveObjectIntoTruthTree(const SG::AuxElement& obj) - { - // If the container doesn't have an auxiliary store, bail now: - if (!obj.container()->getConstStore()) - return; - - // Get a convenience pointer to the aux type registry: - SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance(); - // Get the auxiliary IDs of the object: - const SG::auxid_set_t& auxids = - ( obj.container()->getConstStore() ? - obj.container()->getConstStore()->getAuxIDs() : - obj.getConstStore()->getAuxIDs() ); - - // setup new variables - for (SG::auxid_t auxid : auxids) { - // get the type of the variable - const std::type_info* ti = reg.getType( auxid ); - // get the name of the variable - const std::string name = reg.getName( auxid ); - - // Add variable - if (*ti == typeid( int ) ){ - std::unordered_map<std::string,int*>::iterator itr = m_extraTruthVars_int.find( name ); - if (itr != m_extraTruthVars_int.end()) { - *((*itr).second) = obj.auxdataConst<int> (name); - } - } - else if (*ti == typeid( float ) ){ - std::unordered_map<std::string,float*>::iterator itr = m_extraTruthVars_float.find( name ); - if (itr != m_extraTruthVars_float.end()) { - *((*itr).second) = obj.auxdataConst<float> (name); - } - } - else { - ATH_MSG_INFO("saveObjectIntoTruthTree - you need another variable map for more types!"); - } - } + // MET + m_met_met = upgradeEvent.m_met->met(); + m_met_phi = upgradeEvent.m_met->phi(); + + if (m_config->doMCGeneratorWeights()) { + // delegate to helper function. + loadMCGeneratorWeights(); } + } + + void EventSaverFlatNtuple::fillUpgradeEvent() { + // fill the tree + m_upgradeTreeManager->fill(); + }//saveUpgradeEvent + + void EventSaverFlatNtuple::finalize() { + m_outputFile->Write(); + } + + void EventSaverFlatNtuple::loadPdfInfo() { + const xAOD::TruthEventContainer* truthEvent(nullptr); + + top::check(evtStore()->retrieve(truthEvent, m_config->sgKeyTruthEvent()), "Failed to retrieve truth PDF info"); - // get short name for FixedCutBEff_* WPs - std::string EventSaverFlatNtuple::shortBtagWP(std::string const & WP) const { - std::string str = "FixedCutBEff_"; - std::string out = WP; - if (out.find(str) != std::string::npos) { - out.replace(out.find(str),str.length(),""); + if (truthEvent != nullptr) { + unsigned int i(0); + unsigned int truthEventSize = truthEvent->size(); + m_PDFinfo_X1.resize(truthEventSize); + m_PDFinfo_X2.resize(truthEventSize); + m_PDFinfo_PDGID1.resize(truthEventSize); + m_PDFinfo_PDGID2.resize(truthEventSize); + m_PDFinfo_Q.resize(truthEventSize); + m_PDFinfo_XF1.resize(truthEventSize); + m_PDFinfo_XF2.resize(truthEventSize); + + for (const auto* const tePtr : *truthEvent) { + // LMTODO: ASG tools/pdfInfo() can't be used yet, since scale Q is not available + // xAOD::TruthEvent::PdfInfo _pdfInfo=tePtr->pdfInfo(); + // if _pdfInfo.valid() { m_PDFinfo_X1[i] = _pdfInfo.x1; //etc. } + std::string PDFinfoVarName = "X1"; + if (truthEvent->isAvailable<float>(PDFinfoVarName)) m_PDFinfo_X1[i] = (*tePtr).auxdataConst< float >(PDFinfoVarName); + PDFinfoVarName = "X2"; + if (truthEvent->isAvailable<float>(PDFinfoVarName)) m_PDFinfo_X2[i] = (*tePtr).auxdataConst< float >(PDFinfoVarName); + PDFinfoVarName = "PDGID1"; + if (truthEvent->isAvailable<int>(PDFinfoVarName)) m_PDFinfo_PDGID1[i] = (*tePtr).auxdataConst< int >(PDFinfoVarName); + PDFinfoVarName = "PDGID2"; + if (truthEvent->isAvailable<int>(PDFinfoVarName)) m_PDFinfo_PDGID2[i] = (*tePtr).auxdataConst< int >(PDFinfoVarName); + PDFinfoVarName = "XF1"; + if (truthEvent->isAvailable<float>(PDFinfoVarName)) m_PDFinfo_XF1[i] = (*tePtr).auxdataConst< float >(PDFinfoVarName); + PDFinfoVarName = "XF2"; + if (truthEvent->isAvailable<float>(PDFinfoVarName)) m_PDFinfo_XF2[i] = (*tePtr).auxdataConst< float >(PDFinfoVarName); + PDFinfoVarName = "Q"; + if (truthEvent->isAvailable<float>(PDFinfoVarName)) m_PDFinfo_Q[i] = (*tePtr).auxdataConst< float >(PDFinfoVarName); + ++i; } - return out; } + } + + void EventSaverFlatNtuple::loadPdfWeights() { + const xAOD::TruthEventContainer* truthEvent(nullptr); - // remove "FT_EFF_", spaces, and "-" in named systematics - std::string EventSaverFlatNtuple::betterBtagNamedSyst (const std::string name) { - std::string str = "FT_EFF_"; - std::string out = name; - if (out.find(str) != std::string::npos) { - out.replace(out.find(str),str.length(),""); + top::check(evtStore()->retrieve(truthEvent, m_config->sgKeyTruthEvent()), "Failed to retrieve truth PDF info"); + + for (auto tePtr : *truthEvent) { + for (const std::string& pdf_name : m_config->LHAPDFSets()) { + if (tePtr->isAvailable<std::vector<float> >("AnalysisTop_" + pdf_name + "_Weights")) { + m_PDF_eventWeights[ pdf_name ] = tePtr->auxdata<std::vector<float> >("AnalysisTop_" + pdf_name + "_Weights"); + } } - str = " "; - while (out.find(str) != std::string::npos) { - out.replace(out.find(str),str.length(),"_"); + } + } + + void EventSaverFlatNtuple::loadMCGeneratorWeights() { + const xAOD::EventInfo* eventInfo(nullptr); + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo for loading of MCGenWeights!"); + m_mc_generator_weights = eventInfo->mcEventWeights(); + } + + // This bit is new + // It is not optimal and can do with a lot of improvement + // Consider it a first pass + // + // We can save xAOD objects into flat ntuple by looking at their SG::AuxElement data + // + // inspired by: + // https://svnweb.cern.ch/trac/atlasoff/browser/Event/xAOD/xAODCore/tags/xAODCore-00-00-93/Root/PrintHelpers.cxx + + void EventSaverFlatNtuple::registerObjectIntoTruthTree(const SG::AuxElement& obj) { + // If the container doesn't have an auxiliary store, bail now: + if (!obj.container()->getConstStore()) return; + + // Get a convenience pointer to the aux type registry: + SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance(); + + // Get the auxiliary IDs of the object: + const SG::auxid_set_t& auxids = + (obj.container()->getConstStore() ? + obj.container()->getConstStore()->getAuxIDs() : + obj.getConstStore()->getAuxIDs()); + + // find the variables and fill them + for (SG::auxid_t auxid : auxids) { + // get the type of the variable + const std::type_info* ti = reg.getType(auxid); + // get the name of the variable + const std::string name = reg.getName(auxid); + + // Add variable + if (*ti == typeid(int)) { + m_extraTruthVars_int.insert(std::make_pair(name, new int)); + } else if (*ti == typeid(float)) { + m_extraTruthVars_float.insert(std::make_pair(name, new float)); + } else { + ATH_MSG_INFO("insertObjectIntoTruthTree - you need another variable map for more types!"); } - str = "-"; - while (out.find(str) != std::string::npos) { - out.replace(out.find(str),str.length(),"_"); + } + + // add the variables to the truthTreeManager + for (std::unordered_map<std::string, int*>::const_iterator i = m_extraTruthVars_int.begin(); i != m_extraTruthVars_int.end(); ++i) { + m_truthTreeManager->makeOutputVariable(*(*i).second, (*i).first); + } + for (std::unordered_map<std::string, float*>::const_iterator i = m_extraTruthVars_float.begin(); i != m_extraTruthVars_float.end(); ++i) { + m_truthTreeManager->makeOutputVariable(*(*i).second, (*i).first); + } + } + + void EventSaverFlatNtuple::saveObjectIntoTruthTree(const SG::AuxElement& obj) { + // If the container doesn't have an auxiliary store, bail now: + if (!obj.container()->getConstStore()) return; + + // Get a convenience pointer to the aux type registry: + SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance(); + // Get the auxiliary IDs of the object: + const SG::auxid_set_t& auxids = + (obj.container()->getConstStore() ? + obj.container()->getConstStore()->getAuxIDs() : + obj.getConstStore()->getAuxIDs()); + + // setup new variables + for (SG::auxid_t auxid : auxids) { + // get the type of the variable + const std::type_info* ti = reg.getType(auxid); + // get the name of the variable + const std::string name = reg.getName(auxid); + + // Add variable + if (*ti == typeid(int)) { + std::unordered_map<std::string, int*>::iterator itr = m_extraTruthVars_int.find(name); + if (itr != m_extraTruthVars_int.end()) { + *((*itr).second) = obj.auxdataConst<int> (name); + } + } else if (*ti == typeid(float)) { + std::unordered_map<std::string, float*>::iterator itr = m_extraTruthVars_float.find(name); + if (itr != m_extraTruthVars_float.end()) { + *((*itr).second) = obj.auxdataConst<float> (name); + } + } else { + ATH_MSG_INFO("saveObjectIntoTruthTree - you need another variable map for more types!"); } - return out; + } + } + + // get short name for FixedCutBEff_* WPs + std::string EventSaverFlatNtuple::shortBtagWP(std::string const& WP) const { + std::string str = "FixedCutBEff_"; + std::string out = WP; + if (out.find(str) != std::string::npos) { + out.replace(out.find(str), str.length(), ""); + } + return out; + } + + // remove "FT_EFF_", spaces, and "-" in named systematics + std::string EventSaverFlatNtuple::betterBtagNamedSyst(const std::string name) { + std::string str = "FT_EFF_"; + std::string out = name; + if (out.find(str) != std::string::npos) { + out.replace(out.find(str), str.length(), ""); + } + str = " "; + while (out.find(str) != std::string::npos) { + out.replace(out.find(str), str.length(), "_"); + } + str = "-"; + while (out.find(str) != std::string::npos) { + out.replace(out.find(str), str.length(), "_"); + } + return out; + } + + //new prompt lepton classification below based on + // https://twiki.cern.ch/twiki/pub/AtlasProtected/IsolationFakeForum/MakeTruthClassification.hxx + //these represent the latest IFF recommendations + std::pair<bool, bool> EventSaverFlatNtuple::isPromptElectron(int type, int origin, int egMotherType, int egMotherOrigin, int egMotherPdgId, int RecoCharge) { + // 43 is "diboson" origin, but is needed due to buggy origin flags in Sherpa ttbar + bool isprompt = (type == 2 || + (type == 4 && origin == 5 && fabs(egMotherPdgId) == 11) || + // bkg electrons from ElMagDecay with origin top, W or Z, higgs, diBoson + (type == 4 && origin == 7 && egMotherType == 2 && (egMotherOrigin == 10 || egMotherOrigin == 12 || egMotherOrigin == 13 || egMotherOrigin == 14 || egMotherOrigin == 43) && fabs(egMotherPdgId) == 11) || + // unknown electrons from multi-boson (sherpa 222, di-boson) + (type == 1 && egMotherType == 2 && egMotherOrigin == 47 && fabs(egMotherPdgId) == 11)); + + bool isChargeFl = false; + + if (egMotherPdgId * RecoCharge > 0) isChargeFl = true; + if (isprompt) return std::make_pair(true, isChargeFl); //charge flipped electrons are also considered prompt + + // bkg photons from photon conv from FSR (must check!!) + if (type == 4 && origin == 5 && egMotherOrigin == 40) return std::make_pair(true, false); + + // non-iso photons from FSR for the moment but we must check!! (must check!!) + if (type == 15 && origin == 40) return std::make_pair(true, false); + + // mainly in Sherpa Zee, but some also in Zmumu + if (type == 4 && origin == 7 && egMotherType == 15 && egMotherOrigin == 40) return std::make_pair(true, false); + + return std::make_pair(false, false); + } + + bool EventSaverFlatNtuple::isPromptMuon(int type, int origin) { + // 43 is "diboson" origin, but is needed due to buggy origin flags in Sherpa ttbar + bool prompt = (type == 6 && + (origin == 10 || origin == 12 || origin == 13 || origin == 14 || origin == 15 || origin == 22 || origin == 43)); + + return prompt; + } + + int EventSaverFlatNtuple::filterBranches(const top::TreeManager* treeManager, const std::string& variable) { + std::vector<std::string> filteredBranches; + if(treeManager->name() == "truth") filteredBranches= m_config->filterPartonLevelBranches(); + else if(treeManager->name() == "particleLevel") filteredBranches= m_config->filterParticleLevelBranches(); + else if(treeManager->name() == "nominal_Loose") filteredBranches= m_config->filterNominalLooseBranches(); + else filteredBranches= m_config->filterBranches(); + + // lambda to test a wildcard on the variable + auto matches_wildcard = [&variable] (const std::string& wildcard) { + std::smatch match; + std::regex_search(variable, match, std::regex(wildcard)); + if (!match.empty()) return true; + + return false; + }; + + for (std::string filter : filteredBranches) { + // replace "*" with ".*" + filter = regex_replace(filter, std::regex("\\*"), ".*"); + // check for a match + if (matches_wildcard(("^" + filter).c_str())) return 0; } + return -1; + } } // namespace diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAOD.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAOD.cxx index 34fb1578fa3d..767cc1d7ed39 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAOD.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAOD.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopAnalysis/EventSaverxAOD.h" @@ -17,40 +17,38 @@ #include "TFile.h" namespace top { - -EventSaverxAOD::EventSaverxAOD() : - asg::AsgTool( "top::EventSaverxAOD" ), - m_prefix("CorrectedSelected"), - m_config(nullptr), - m_outputFile(nullptr) { -} - -EventSaverxAOD::~EventSaverxAOD() -{ -} - -void EventSaverxAOD::initialize(std::shared_ptr<top::TopConfig> config, TFile* file, const std::vector<std::string>& extraBranches) { + EventSaverxAOD::EventSaverxAOD() : + asg::AsgTool("top::EventSaverxAOD"), + m_prefix("CorrectedSelected"), + m_config(nullptr), + m_outputFile(nullptr) { + } + + EventSaverxAOD::~EventSaverxAOD() { + } + + void EventSaverxAOD::initialize(std::shared_ptr<top::TopConfig> config, TFile* file, + const std::vector<std::string>& extraBranches) { m_config = config; m_outputFile = file; top::check(evtStore()->event()->writeTo(m_outputFile), "EventSaverxAOD trying to call writeTo on output file"); //EventInfo std::string eventInfoList = "runNumber.eventNumber.eventTypeBitmask.averageInteractionsPerCrossing"; - if (config->isMC()) - eventInfoList += ".mcChannelNumber.mcEventWeights.PileupWeight"; + if (config->isMC()) eventInfoList += ".mcChannelNumber.mcEventWeights.PileupWeight"; //Add extra branches - e.g. if it passed the ee / mumu / emu selection per event for (const auto& branchName : extraBranches) - eventInfoList += "." + branchName; + eventInfoList += "." + branchName; - //std::cout << "EventLoaderCorrectSelect::branchesToSave - EventInfo " << eventInfoList << std::endl; evtStore()->event()->setAuxItemList("EventInfoAux.", eventInfoList); //Electrons evtStore()->event()->setAuxItemList(m_prefix + m_config->sgKeyElectrons() + "Aux.", "pt.eta.phi.m.charge"); //Muons - evtStore()->event()->setAuxItemList(m_prefix + m_config->sgKeyMuons() + "Aux.", "pt.eta.phi.m.charge.muonType.combinedTrackParticleLink"); + evtStore()->event()->setAuxItemList( + m_prefix + m_config->sgKeyMuons() + "Aux.", "pt.eta.phi.m.charge.muonType.combinedTrackParticleLink"); //Once mu has a built-in charge we can get rid of this //Muon charge is a property of the associated track - e.g. d0.z0.phi.theta.qOverP @@ -66,137 +64,153 @@ void EventSaverxAOD::initialize(std::shared_ptr<top::TopConfig> config, TFile* f evtStore()->event()->setAuxItemList(btagName + "Aux.", "MV1_discriminant"); //MET seems to be pretty small already -} + } -void EventSaverxAOD::saveEvent(const top::Event& event) { + void EventSaverxAOD::saveEvent(const top::Event& event) { //only save the nominal variation for now - speak to Attila about TEvent.fill not taking a tree name - if (event.m_hashValue != m_config->nominalHashValue()) - return; - + if (event.m_hashValue != m_config->nominalHashValue()) return; + // record the event? - if (m_config->saveOnlySelectedEvents() && !event.m_saveEvent) - return; - - // Systematic Event + if (m_config->saveOnlySelectedEvents() && !event.m_saveEvent) return; + + // Systematic Event const xAOD::SystematicEventContainer* allSystematics(nullptr); - top::check(evtStore()->retrieve(allSystematics,m_config->sgKeyTopSystematicEvents()) , "Failed to retrieve xAOD::SystematicEventContainer" ); - - xAOD::SystematicEventContainer* allSystematics_output = new xAOD::SystematicEventContainer{}; - SG::IAuxStore* allSystematics_aux = evtStore()->event()->recordAux( m_config->sgKeyTopSystematicEvents() + "Aux." ); - allSystematics_output->setStore( allSystematics_aux ); + top::check(evtStore()->retrieve(allSystematics, + m_config->sgKeyTopSystematicEvents()), + "Failed to retrieve xAOD::SystematicEventContainer"); + + xAOD::SystematicEventContainer* allSystematics_output = new xAOD::SystematicEventContainer {}; + SG::IAuxStore* allSystematics_aux = evtStore()->event()->recordAux(m_config->sgKeyTopSystematicEvents() + "Aux."); + allSystematics_output->setStore(allSystematics_aux); for (auto currentSystematic : *allSystematics) { - xAOD::SystematicEvent* out = new xAOD::SystematicEvent{}; - out->makePrivateStore( *currentSystematic ); - allSystematics_output->push_back( out ); + xAOD::SystematicEvent* out = new xAOD::SystematicEvent {}; + out->makePrivateStore(*currentSystematic); + allSystematics_output->push_back(out); } - top::check(evtStore()->event()->record(allSystematics_output,m_config->sgKeyTopSystematicEvents()),"Failed to record xAOD::SystematicEventContainer" ); - - - // Top Parton History + top::check(evtStore()->event()->record(allSystematics_output, + m_config->sgKeyTopSystematicEvents()), + "Failed to record xAOD::SystematicEventContainer"); + + + // Top Parton History if (m_config->doTopPartonHistory()) { if (evtStore()->contains<xAOD::PartonHistoryContainer>(m_config->sgKeyTopPartonHistory())) { const xAOD::PartonHistoryContainer* partonHistory(nullptr); - top::check(evtStore()->retrieve(partonHistory, m_config->sgKeyTopPartonHistory()),"Failed to retrieve Top Parton History"); - - xAOD::PartonHistoryContainer* partonHistory_output = new xAOD::PartonHistoryContainer{}; - SG::IAuxStore* partonHistory_aux = evtStore()->event()->recordAux( m_config->sgKeyTopPartonHistory() + "Aux." ); - partonHistory_output->setStore( partonHistory_aux ); + top::check(evtStore()->retrieve(partonHistory, + m_config->sgKeyTopPartonHistory()), "Failed to retrieve Top Parton History"); + + xAOD::PartonHistoryContainer* partonHistory_output = new xAOD::PartonHistoryContainer {}; + SG::IAuxStore* partonHistory_aux = evtStore()->event()->recordAux(m_config->sgKeyTopPartonHistory() + "Aux."); + partonHistory_output->setStore(partonHistory_aux); for (auto x : *partonHistory) { - xAOD::PartonHistory* out = new xAOD::PartonHistory{}; - out->makePrivateStore( *x ); - partonHistory_output->push_back( out ); + xAOD::PartonHistory* out = new xAOD::PartonHistory {}; + out->makePrivateStore(*x); + partonHistory_output->push_back(out); } - top::check(evtStore()->event()->record(partonHistory_output,m_config->sgKeyTopPartonHistory()),"Failed to record Parton History" ); + top::check(evtStore()->event()->record(partonHistory_output, + m_config->sgKeyTopPartonHistory()), "Failed to record Parton History"); } } - - + + //Event Info top::check(evtStore()->event()->copy("EventInfo"), "copying event info failed"); //Electrons if (m_config->useElectrons()) { - xAOD::ElectronContainer* electrons_output = new xAOD::ElectronContainer(); - SG::IAuxStore* electrons_aux = evtStore()->event()->recordAux(m_prefix + m_config->sgKeyElectrons() + "Aux."); - electrons_output->setStore(electrons_aux); - - for (const auto* const elPtr : event.m_electrons) { - xAOD::Electron* outputElPtr = new xAOD::Electron(); - outputElPtr->makePrivateStore(*elPtr); - electrons_output->push_back(outputElPtr); - } + xAOD::ElectronContainer* electrons_output = new xAOD::ElectronContainer(); + SG::IAuxStore* electrons_aux = evtStore()->event()->recordAux(m_prefix + m_config->sgKeyElectrons() + "Aux."); + electrons_output->setStore(electrons_aux); + + for (const auto* const elPtr : event.m_electrons) { + xAOD::Electron* outputElPtr = new xAOD::Electron(); + outputElPtr->makePrivateStore(*elPtr); + electrons_output->push_back(outputElPtr); + } - top::check(evtStore()->event()->record(electrons_output, m_prefix + m_config->sgKeyElectrons()), "xAOD::TEvent record " + m_prefix + m_config->sgKeyElectrons() + " failed"); + top::check(evtStore()->event()->record(electrons_output, + m_prefix + m_config->sgKeyElectrons()), + "xAOD::TEvent record " + m_prefix + m_config->sgKeyElectrons() + " failed"); } //Muons if (m_config->useMuons()) { - xAOD::MuonContainer* muons_output = new xAOD::MuonContainer(); - SG::IAuxStore* muons_aux = evtStore()->event()->recordAux(m_prefix + m_config->sgKeyMuons() + "Aux."); - muons_output->setStore(muons_aux); - - for (const auto* const muPtr : event.m_muons) { - xAOD::Muon* outputMuPtr = new xAOD::Muon(); - outputMuPtr->makePrivateStore(*muPtr); - muons_output->push_back(outputMuPtr); - } - - top::check(evtStore()->event()->record(muons_output, m_prefix + m_config->sgKeyMuons()), "xAOD::TEvent record " + m_prefix + m_config->sgKeyMuons() + " failed"); + xAOD::MuonContainer* muons_output = new xAOD::MuonContainer(); + SG::IAuxStore* muons_aux = evtStore()->event()->recordAux(m_prefix + m_config->sgKeyMuons() + "Aux."); + muons_output->setStore(muons_aux); + + for (const auto* const muPtr : event.m_muons) { + xAOD::Muon* outputMuPtr = new xAOD::Muon(); + outputMuPtr->makePrivateStore(*muPtr); + muons_output->push_back(outputMuPtr); + } - //for now... - //Muon charge is a property of the associated track - //Copy tracks (for muon charge) - check(evtStore()->event()->copy("InDetTrackParticles"), "xAOD::TEvent copy InDetTrackParticles failed"); - check(evtStore()->event()->copy("ExtrapolatedMuonTrackParticles"), "xAOD::TEvent copy InDetTrackParticles ExtrapolatedMuonTrackParticles"); - check(evtStore()->event()->copy("CombinedMuonTrackParticles"), "xAOD::TEvent copy InDetTrackParticles CombinedMuonTrackParticles"); + top::check(evtStore()->event()->record(muons_output, + m_prefix + m_config->sgKeyMuons()), + "xAOD::TEvent record " + m_prefix + m_config->sgKeyMuons() + " failed"); + + //for now... + //Muon charge is a property of the associated track + //Copy tracks (for muon charge) + check(evtStore()->event()->copy("InDetTrackParticles"), "xAOD::TEvent copy InDetTrackParticles failed"); + check(evtStore()->event()->copy( + "ExtrapolatedMuonTrackParticles"), + "xAOD::TEvent copy InDetTrackParticles ExtrapolatedMuonTrackParticles"); + check(evtStore()->event()->copy( + "CombinedMuonTrackParticles"), "xAOD::TEvent copy InDetTrackParticles CombinedMuonTrackParticles"); } //Jets if (m_config->useJets()) { - xAOD::JetContainer* jets_output = new xAOD::JetContainer(); - SG::IAuxStore* jets_aux = evtStore()->event()->recordAux(m_prefix + m_config->sgKeyJets() + "Aux."); - jets_output->setStore(jets_aux); - - for (const auto* const jetPtr : event.m_jets) { - xAOD::Jet* outputJetPtr = new xAOD::Jet(); - outputJetPtr->makePrivateStore(*jetPtr); - jets_output->push_back(outputJetPtr); - } + xAOD::JetContainer* jets_output = new xAOD::JetContainer(); + SG::IAuxStore* jets_aux = evtStore()->event()->recordAux(m_prefix + m_config->sgKeyJets() + "Aux."); + jets_output->setStore(jets_aux); + + for (const auto* const jetPtr : event.m_jets) { + xAOD::Jet* outputJetPtr = new xAOD::Jet(); + outputJetPtr->makePrivateStore(*jetPtr); + jets_output->push_back(outputJetPtr); + } - top::check(evtStore()->event()->record(jets_output, m_prefix + m_config->sgKeyJets()), "xAOD::TEvent record " + m_prefix + m_config->sgKeyJets() + " failed"); + top::check(evtStore()->event()->record(jets_output, + m_prefix + m_config->sgKeyJets()), + "xAOD::TEvent record " + m_prefix + m_config->sgKeyJets() + " failed"); - //b-tagging variables need the BTagging_JetNameWithoutJetsOnTheEnd container - //remove Jets from the end of the container name and add BTagging_ - const std::string btagName = "BTagging_" + m_config->sgKeyJets().substr(0, m_config->sgKeyJets().size() - 4); - check(evtStore()->event()->copy(btagName), "xAOD::TEvent copy " + btagName + " failed"); + //b-tagging variables need the BTagging_JetNameWithoutJetsOnTheEnd container + //remove Jets from the end of the container name and add BTagging_ + const std::string btagName = "BTagging_" + m_config->sgKeyJets().substr(0, m_config->sgKeyJets().size() - 4); + check(evtStore()->event()->copy(btagName), "xAOD::TEvent copy " + btagName + " failed"); } //Large Jets if (m_config->useLargeRJets()) { - xAOD::JetContainer* largeJets_output = new xAOD::JetContainer(); - SG::IAuxStore* largeJets_aux = evtStore()->event()->recordAux(m_prefix + m_config->sgKeyLargeRJets() + "Aux."); - largeJets_output->setStore(largeJets_aux); - - for (const auto* const jetPtr : event.m_largeJets) { - xAOD::Jet* outputJetPtr = new xAOD::Jet(); - outputJetPtr->makePrivateStore(*jetPtr); - largeJets_output->push_back(outputJetPtr); - } + xAOD::JetContainer* largeJets_output = new xAOD::JetContainer(); + SG::IAuxStore* largeJets_aux = evtStore()->event()->recordAux(m_prefix + m_config->sgKeyLargeRJets() + "Aux."); + largeJets_output->setStore(largeJets_aux); + + for (const auto* const jetPtr : event.m_largeJets) { + xAOD::Jet* outputJetPtr = new xAOD::Jet(); + outputJetPtr->makePrivateStore(*jetPtr); + largeJets_output->push_back(outputJetPtr); + } - check(evtStore()->event()->record(largeJets_output, m_prefix + m_config->sgKeyLargeRJets()), "xAOD::TEvent record " + m_prefix + m_config->sgKeyLargeRJets() + " failed"); + check(evtStore()->event()->record(largeJets_output, + m_prefix + m_config->sgKeyLargeRJets()), + "xAOD::TEvent record " + m_prefix + m_config->sgKeyLargeRJets() + " failed"); } //MET - top::check(evtStore()->event()->copy(m_config->sgKeyMissingEt()), "xAOD::TEvent copy " + m_config->sgKeyMissingEt() + " failed"); + top::check(evtStore()->event()->copy(m_config->sgKeyMissingEt()), + "xAOD::TEvent copy " + m_config->sgKeyMissingEt() + " failed"); //do it! top::check(evtStore()->event()->fill(), "xAOD::TEvent fill failed"); -} + } -void EventSaverxAOD::finalize() { + void EventSaverxAOD::finalize() { m_outputFile->Write(); - top::check(evtStore()->event()->finishWritingTo(m_outputFile), "EventSaverxAOD::finalise trying to call finishWritingTo"); -} - + top::check(evtStore()->event()->finishWritingTo( + m_outputFile), "EventSaverxAOD::finalise trying to call finishWritingTo"); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAODNext.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAODNext.cxx index 7845c85afc79..47716a65b955 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAODNext.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAODNext.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ #include "TopAnalysis/EventSaverxAODNext.h" @@ -27,52 +27,50 @@ #include "TFile.h" namespace top { - - EventSaverxAODNext::EventSaverxAODNext() : - asg::AsgMetadataTool( "top::EventSaverxAODNext" ), - m_config(nullptr), + EventSaverxAODNext::EventSaverxAODNext() : + asg::AsgMetadataTool("top::EventSaverxAODNext"), + m_config(nullptr), m_outputFile(nullptr), - m_saveAllObjects(false) - { + m_saveAllObjects(false) { } - - EventSaverxAODNext::~EventSaverxAODNext() - { + + EventSaverxAODNext::~EventSaverxAODNext() { } - void EventSaverxAODNext::initialize(std::shared_ptr<top::TopConfig> config, TFile* file, const std::vector<std::string>& extraBranches) { + void EventSaverxAODNext::initialize(std::shared_ptr<top::TopConfig> config, TFile* file, + const std::vector<std::string>& extraBranches) { m_config = config; m_outputFile = file; top::check(evtStore()->event()->writeTo(m_outputFile), "EventSaverxAODNext trying to call writeTo on output file"); - // Persist the top::TopConfig settings - we'll need this to make sense of the output when reading it back - top::check( outputMetaStore()->record( m_config->createPersistentSettings() , "TopPersistentSettings" ) , "Failed to save TopPersistentSettings" ); + // Persist the top::TopConfig settings - we'll need this to make sense of the output when reading it back + top::check(outputMetaStore()->record( + m_config->createPersistentSettings(), "TopPersistentSettings"), + "Failed to save TopPersistentSettings"); auto* const settings = top::ConfigurationSettings::get(); - + //EventInfo std::string eventInfoList = settings->value("EventVariableSaveList"); - if (config->isMC()) - eventInfoList += ".mcChannelNumber.mcEventWeights"; + if (config->isMC()) eventInfoList += ".mcChannelNumber.mcEventWeights"; //Add extra branches - e.g. if it passed the ee / mumu / emu selection per event for (const auto& branchName : extraBranches) - eventInfoList += "." + branchName; + eventInfoList += "." + branchName; - //std::cout << "EventLoaderCorrectSelect::branchesToSave - EventInfo " << eventInfoList << std::endl; evtStore()->event()->setAuxItemList("EventInfoAux.", eventInfoList); - + // Photons if (m_config->usePhotons()) { std::string photonVariableSaveList = settings->value("PhotonVariableSaveList"); if (config->isMC()) { photonVariableSaveList += ".truthType.truthOrigin"; } - + for (auto currentSystematic : *m_config->systSgKeyMapPhotons()) { std::string sgKey = currentSystematic.second; - evtStore()->event()->setAuxItemList(sgKey + "Aux." , photonVariableSaveList ); + evtStore()->event()->setAuxItemList(sgKey + "Aux.", photonVariableSaveList); } - } // Photons + } // Photons // Electrons if (m_config->useElectrons()) { @@ -80,13 +78,13 @@ namespace top { if (config->isMC()) { electronVariableSaveList += ".truthType.truthOrigin"; } - + for (auto currentSystematic : *m_config->systSgKeyMapElectrons()) { std::string sgKey = currentSystematic.second; - evtStore()->event()->setAuxItemList(sgKey + "Aux." , electronVariableSaveList ); + evtStore()->event()->setAuxItemList(sgKey + "Aux.", electronVariableSaveList); } } // Electrons - + // Muons if (m_config->useMuons()) { std::string muonVariableSaveList = settings->value("MuonVariableSaveList"); @@ -95,71 +93,71 @@ namespace top { // if (config->isMC()) { // muonVariableSaveList += ".truthType.truthOrigin"; // } - + for (auto currentSystematic : *m_config->systSgKeyMapMuons()) { std::string sgKey = currentSystematic.second; - evtStore()->event()->setAuxItemList(sgKey + "Aux." , muonVariableSaveList ); + evtStore()->event()->setAuxItemList(sgKey + "Aux.", muonVariableSaveList); } - } // Muons - + } // Muons + // Taus if (m_config->useTaus()) { std::string tauVariableSaveList = settings->value("TauVariableSaveList"); - + for (auto currentSystematic : *m_config->systSgKeyMapTaus()) { std::string sgKey = currentSystematic.second; - evtStore()->event()->setAuxItemList(sgKey + "Aux." , tauVariableSaveList ); + evtStore()->event()->setAuxItemList(sgKey + "Aux.", tauVariableSaveList); } - } // Taus - - + } // Taus + + // Jets if (m_config->useJets()) { std::string jetVariableSaveList = settings->value("JetVariableSaveList"); - + for (auto currentSystematic : *m_config->systSgKeyMapJets(false)) { std::string sgKey = currentSystematic.second; - evtStore()->event()->setAuxItemList(sgKey + "Aux." , jetVariableSaveList ); - } + evtStore()->event()->setAuxItemList(sgKey + "Aux.", jetVariableSaveList); + } } - + if (m_config->useLargeRJets()) { std::string jetVariableSaveList = settings->value("JetVariableSaveList"); - + for (auto currentSystematic : *m_config->systSgKeyMapLargeRJets()) { std::string sgKey = currentSystematic.second; - evtStore()->event()->setAuxItemList(sgKey + "Aux." , jetVariableSaveList ); - } - } - + evtStore()->event()->setAuxItemList(sgKey + "Aux.", jetVariableSaveList); + } + } + if (m_config->useTrackJets()) { std::string jetVariableSaveList = settings->value("JetVariableSaveList"); - + for (auto currentSystematic : *m_config->systSgKeyMapTrackJets()) { std::string sgKey = currentSystematic.second; - evtStore()->event()->setAuxItemList(sgKey + "Aux." , jetVariableSaveList ); - } - } - + evtStore()->event()->setAuxItemList(sgKey + "Aux.", jetVariableSaveList); + } + } + if (m_config->useJets() || m_config->useLargeRJets() || m_config->useTrackJets()) { // B-tagging std::string bTagVariableSaveList = settings->value("BTagVariableSaveList"); - evtStore()->event()->setAuxItemList("BTagging_AntiKt4EMTopoAux.",bTagVariableSaveList); - } // B-tagging - - + evtStore()->event()->setAuxItemList("BTagging_AntiKt4EMTopoAux.", bTagVariableSaveList); + } // B-tagging } - void EventSaverxAODNext::saveEventToxAOD() - { - // Systematic Event + void EventSaverxAODNext::saveEventToxAOD() { + // Systematic Event const xAOD::SystematicEventContainer* allSystematics(nullptr); - top::check(evtStore()->retrieve(allSystematics,m_config->sgKeyTopSystematicEvents()) , "Failed to retrieve xAOD::SystematicEventContainer" ); - + + top::check(evtStore()->retrieve(allSystematics, + m_config->sgKeyTopSystematicEvents()), + "Failed to retrieve xAOD::SystematicEventContainer"); + // Save all reco event objects? // If no systematic in the event passes the event selection // We don't fill the collections - this saves a lot of disk space - bool saveEvent(false),saveEventObjects(false); + bool saveEvent(false), saveEventObjects(false); if (!m_config->saveOnlySelectedEvents()) { saveEvent = true; } @@ -172,143 +170,148 @@ namespace top { } } } // Save reco event? - - if (saveEvent) { + if (saveEvent) { //Event Info - top::check(evtStore()->event()->copy("EventInfo"), "copying event info failed"); - - // BTagging - can consider thinning this at some point. + top::check(evtStore()->event()->copy("EventInfo"), "copying event info failed"); + + // BTagging - can consider thinning this at some point. // Tricky computation as all jet collections need updated ElementLinks - top::check(evtStore()->event()->copy("BTagging_AntiKt4EMTopo") , "copying btagging failed" ); + top::check(evtStore()->event()->copy("BTagging_AntiKt4EMTopo"), "copying btagging failed"); top::check(evtStore()->event()->copy("egammaClusters"), "copying egamma clusters failed"); - - // Object Thinning maps - std::shared_ptr<ThinningMap_t> photonThinningMap = savePhotons(saveEventObjects); + + // Object Thinning maps + std::shared_ptr<ThinningMap_t> photonThinningMap = savePhotons(saveEventObjects); std::shared_ptr<ThinningMap_t> electronThinningMap = saveElectrons(saveEventObjects); - std::shared_ptr<ThinningMap_t> muonThinningMap = saveMuons(saveEventObjects); + std::shared_ptr<ThinningMap_t> muonThinningMap = saveMuons(saveEventObjects); std::shared_ptr<ThinningMap_t> tauThinningMap = saveTaus(saveEventObjects); - std::shared_ptr<ThinningMap_t> jetThinningMap = saveJets(saveEventObjects); - std::shared_ptr<ThinningMap_t> largeRJetThinningMap = saveLargeRJets(saveEventObjects); + std::shared_ptr<ThinningMap_t> jetThinningMap = saveJets(saveEventObjects); + std::shared_ptr<ThinningMap_t> largeRJetThinningMap = saveLargeRJets(saveEventObjects); std::shared_ptr<ThinningMap_t> trackJetThinningMap = saveTrackJets(saveEventObjects); - + // Save SystematicEventContainer - xAOD::SystematicEventContainer* allSystematics_output = new xAOD::SystematicEventContainer{}; - SG::IAuxStore* allSystematics_output_aux = evtStore()->event()->recordAux( m_config->sgKeyTopSystematicEvents() + "Aux." ); - allSystematics_output->setStore( allSystematics_output_aux ); + xAOD::SystematicEventContainer* allSystematics_output = new xAOD::SystematicEventContainer {}; + SG::IAuxStore* allSystematics_output_aux = evtStore()->event()->recordAux( + m_config->sgKeyTopSystematicEvents() + "Aux."); + allSystematics_output->setStore(allSystematics_output_aux); if (saveEventObjects) { for (auto systematicPtr : *allSystematics) { - xAOD::SystematicEvent* out = new xAOD::SystematicEvent{}; - out->makePrivateStore( *systematicPtr ); - out->setGoodPhotons ( thinObjectSelection( systematicPtr->hashValue() , systematicPtr->goodPhotons() , photonThinningMap ) ); - out->setGoodElectrons ( thinObjectSelection( systematicPtr->hashValue() , systematicPtr->goodElectrons() , electronThinningMap ) ); - out->setGoodMuons ( thinObjectSelection( systematicPtr->hashValue() , systematicPtr->goodMuons() , muonThinningMap ) ); - out->setGoodTaus ( thinObjectSelection( systematicPtr->hashValue() , systematicPtr->goodTaus() , tauThinningMap ) ); - out->setGoodJets ( thinObjectSelection( systematicPtr->hashValue() , systematicPtr->goodJets() , jetThinningMap ) ); - out->setGoodLargeRJets( thinObjectSelection( systematicPtr->hashValue() , systematicPtr->goodLargeRJets() , largeRJetThinningMap ) ); - out->setGoodTrackJets ( thinObjectSelection( systematicPtr->hashValue() , systematicPtr->goodTrackJets() , trackJetThinningMap ) ); - allSystematics_output->push_back( out ); - - // Missing ET + if (!(systematicPtr->hashValue() == m_config->nominalHashValue() || m_config->doTightSysts() || + m_config->doLooseSysts())) continue; + xAOD::SystematicEvent* out = new xAOD::SystematicEvent {}; + out->makePrivateStore(*systematicPtr); + out->setGoodPhotons(thinObjectSelection(systematicPtr->hashValue(), systematicPtr->goodPhotons(), + photonThinningMap)); + out->setGoodElectrons(thinObjectSelection(systematicPtr->hashValue(), systematicPtr->goodElectrons(), + electronThinningMap)); + out->setGoodMuons(thinObjectSelection(systematicPtr->hashValue(), systematicPtr->goodMuons(), + muonThinningMap)); + out->setGoodTaus(thinObjectSelection(systematicPtr->hashValue(), systematicPtr->goodTaus(), tauThinningMap)); + out->setGoodJets(thinObjectSelection(systematicPtr->hashValue(), systematicPtr->goodJets(), jetThinningMap)); + out->setGoodLargeRJets(thinObjectSelection(systematicPtr->hashValue(), systematicPtr->goodLargeRJets(), + largeRJetThinningMap)); + out->setGoodTrackJets(thinObjectSelection(systematicPtr->hashValue(), systematicPtr->goodTrackJets(), + trackJetThinningMap)); + allSystematics_output->push_back(out); + + // Missing ET xAOD::MissingETContainer* met(nullptr); - top::check( evtStore()->retrieve(met,m_config->sgKeyMissingEt( systematicPtr->hashValue() ) ) , "Failed to retrieve MET" ); - - xAOD::MissingETContainer* output_met = new xAOD::MissingETContainer{}; - SG::IAuxStore* output_met_aux = evtStore()->event()->recordAux( m_config->sgKeyMissingEt( systematicPtr->hashValue() ) + "Aux." ); - output_met->setStore( output_met_aux ); + top::check(evtStore()->retrieve(met, m_config->sgKeyMissingEt( + systematicPtr->hashValue())), "Failed to retrieve MET"); + + xAOD::MissingETContainer* output_met = new xAOD::MissingETContainer {}; + SG::IAuxStore* output_met_aux = + evtStore()->event()->recordAux(m_config->sgKeyMissingEt(systematicPtr->hashValue()) + "Aux."); + output_met->setStore(output_met_aux); for (auto x : *met) { - xAOD::MissingET* out = new xAOD::MissingET{}; - out->makePrivateStore( *x ); - output_met->push_back( out ); + xAOD::MissingET* out = new xAOD::MissingET {}; + out->makePrivateStore(*x); + output_met->push_back(out); } - top::check( evtStore()->event()->record(output_met,m_config->sgKeyMissingEt( systematicPtr->hashValue() )) , "Failed to save MET" ); - - + top::check(evtStore()->event()->record(output_met, m_config->sgKeyMissingEt( + systematicPtr->hashValue())), "Failed to save MET"); } } - top::check(evtStore()->event()->record(allSystematics_output,m_config->sgKeyTopSystematicEvents()),"Failed to record xAOD::SystematicEventContainer" ); - + top::check(evtStore()->event()->record(allSystematics_output, + m_config->sgKeyTopSystematicEvents()), + "Failed to record xAOD::SystematicEventContainer"); + // Write to disk top::check(evtStore()->event()->fill(), "xAOD::TEvent fill failed"); } } - - - std::vector<unsigned int> EventSaverxAODNext::thinObjectSelection(const std::size_t hashValue , - const std::vector<unsigned int>& objectList , - const std::shared_ptr<ThinningMap_t> thinningMap) const - { + std::vector<unsigned int> EventSaverxAODNext::thinObjectSelection(const std::size_t hashValue, + const std::vector<unsigned int>& objectList, + const std::shared_ptr<ThinningMap_t> thinningMap) + const { // reduced output std::vector<unsigned int> out; - + // Find the correct systematic in the thinningMap - ThinningMap_Itr Itr = thinningMap->find( hashValue ); + ThinningMap_Itr Itr = thinningMap->find(hashValue); // If the systematic is not in the map, then we use the nominal hashValue // This happens, for example, when we look at a jet systematic and are looping over electrons if (Itr == thinningMap->end()) { - Itr = thinningMap->find( m_config->nominalHashValue() ); + Itr = thinningMap->find(m_config->nominalHashValue()); } - + // double check that we have a valid systematic if (Itr != thinningMap->end()) { - // Get the relevant thinningMap for this specific systematic - std::map<unsigned int,unsigned int> currentSystematicThinningMap = (*Itr).second; - + std::map<unsigned int, unsigned int> currentSystematicThinningMap = (*Itr).second; + // Loop over the original good object list, this contains information about objects we are not going to save // Use the thinningMap to build a new good object list based on the objects we are saving for (auto i : objectList) { - std::map<unsigned int,unsigned int>::const_iterator Itr2 = currentSystematicThinningMap.find( i ); + std::map<unsigned int, unsigned int>::const_iterator Itr2 = currentSystematicThinningMap.find(i); if (Itr2 != currentSystematicThinningMap.end()) { - out.push_back( (*Itr2).second ); + out.push_back((*Itr2).second); } - } + } } - + return out; } /** - * All the saveObject functions work the same way - * - we should probably turn this into a template method at some point - * - * We only save objects that pass the pre overlap removal selection - * - This throws away a lot of objects and saves a lot of disk space - * - * We need to consider every calibration systematic variation - * - Each calibration systematic contains a vector of goodIndices used to form top::Event's - * - We need to re-map these vectors if we throw away objects - * - For example, lets consider a dummy jet systematic: - * - calibrated JetContainer has objects [0,1,2,3,4,5,6,7,8] - * - The pre OR selection cuts keep objects [3,4,7] - * - We only want to save objects [3,4,7], objects [0,1,2,5,6,8] are a waste of disk space - * - The saved objects in the output mini-xAOD become [0,1,2] - * - We need to map [ 3->0 , 4->1 , 7->2 ] - * - This needs to be done for each xAOD::SystematicEvent - * - */ - - std::shared_ptr<std::map<std::size_t,std::map<unsigned int,unsigned int>>> EventSaverxAODNext::savePhotons(const bool saveEventObjects) - { - std::shared_ptr<ThinningMap_t> thinningMap( new ThinningMap_t ); + * All the saveObject functions work the same way + * - we should probably turn this into a template method at some point + * + * We only save objects that pass the pre overlap removal selection + * - This throws away a lot of objects and saves a lot of disk space + * + * We need to consider every calibration systematic variation + * - Each calibration systematic contains a vector of goodIndices used to form top::Event's + * - We need to re-map these vectors if we throw away objects + * - For example, lets consider a dummy jet systematic: + * - calibrated JetContainer has objects [0,1,2,3,4,5,6,7,8] + * - The pre OR selection cuts keep objects [3,4,7] + * - We only want to save objects [3,4,7], objects [0,1,2,5,6,8] are a waste of disk space + * - The saved objects in the output mini-xAOD become [0,1,2] + * - We need to map [ 3->0 , 4->1 , 7->2 ] + * - This needs to be done for each xAOD::SystematicEvent + * + */ + + std::shared_ptr<std::map<std::size_t, std::map<unsigned int, unsigned int> > > EventSaverxAODNext::savePhotons( + const bool saveEventObjects) { + std::shared_ptr<ThinningMap_t> thinningMap(new ThinningMap_t); if (m_config->usePhotons()) { - for (auto currentSystematic : *m_config->systSgKeyMapPhotons()) { - std::map<unsigned int,unsigned int> currentSystematicThinningMap; + std::map<unsigned int, unsigned int> currentSystematicThinningMap; std::string sgKey = currentSystematic.second; const xAOD::PhotonContainer* xaod(nullptr); - top::check(evtStore()->retrieve(xaod,sgKey),"Failed to retrieve photons"); - - xAOD::PhotonContainer* output = new xAOD::PhotonContainer{}; - SG::IAuxStore* output_aux = evtStore()->event()->recordAux( sgKey + "Aux." ); - output->setStore( output_aux ); - - if( saveEventObjects ) { - unsigned int index(0),indexReduced(0); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve photons"); + + xAOD::PhotonContainer* output = new xAOD::PhotonContainer {}; + SG::IAuxStore* output_aux = evtStore()->event()->recordAux(sgKey + "Aux."); + output->setStore(output_aux); + + if (saveEventObjects) { + unsigned int index(0), indexReduced(0); for (auto x : *xaod) { - bool save(m_saveAllObjects); if (x->isAvailable<char>("passPreORSelection")) { if (x->auxdataConst<char>("passPreORSelection") == 1) { @@ -320,44 +323,42 @@ namespace top { save = true; } } - + if (save) { - currentSystematicThinningMap.insert( std::make_pair( index , indexReduced ) ); - xAOD::Photon* out = new xAOD::Photon{}; - out->makePrivateStore( *x ); - output->push_back( out ); + currentSystematicThinningMap.insert(std::make_pair(index, indexReduced)); + xAOD::Photon* out = new xAOD::Photon {}; + out->makePrivateStore(*x); + output->push_back(out); ++indexReduced; } ++index; } // Loop over container - } // saveEventObjects - top::check(evtStore()->event()->record(output,sgKey),"Failed to record xAOD::PhotonContainer"); - thinningMap->insert( std::make_pair(currentSystematic.first, currentSystematicThinningMap) ); + } // saveEventObjects + top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::PhotonContainer"); + thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); } // Loop over all systematics; } // use object type - - return thinningMap; + + return thinningMap; } - std::shared_ptr<std::map<std::size_t,std::map<unsigned int,unsigned int>>> EventSaverxAODNext::saveElectrons(const bool saveEventObjects) - { - std::shared_ptr<ThinningMap_t> thinningMap( new ThinningMap_t ); + std::shared_ptr<std::map<std::size_t, std::map<unsigned int, unsigned int> > > EventSaverxAODNext::saveElectrons( + const bool saveEventObjects) { + std::shared_ptr<ThinningMap_t> thinningMap(new ThinningMap_t); if (m_config->useElectrons()) { - for (auto currentSystematic : *m_config->systSgKeyMapElectrons()) { - std::map<unsigned int,unsigned int> currentSystematicThinningMap; + std::map<unsigned int, unsigned int> currentSystematicThinningMap; std::string sgKey = currentSystematic.second; const xAOD::ElectronContainer* xaod(nullptr); - top::check(evtStore()->retrieve(xaod,sgKey),"Failed to retrieve electrons"); - - xAOD::ElectronContainer* output = new xAOD::ElectronContainer{}; - SG::IAuxStore* output_aux = evtStore()->event()->recordAux( sgKey + "Aux." ); - output->setStore( output_aux ); - - if( saveEventObjects ) { - unsigned int index(0),indexReduced(0); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve electrons"); + + xAOD::ElectronContainer* output = new xAOD::ElectronContainer {}; + SG::IAuxStore* output_aux = evtStore()->event()->recordAux(sgKey + "Aux."); + output->setStore(output_aux); + + if (saveEventObjects) { + unsigned int index(0), indexReduced(0); for (auto x : *xaod) { - bool save(m_saveAllObjects); if (x->isAvailable<char>("passPreORSelection")) { if (x->auxdataConst<char>("passPreORSelection") == 1) { @@ -369,50 +370,47 @@ namespace top { save = true; } } - + if (save) { - currentSystematicThinningMap.insert( std::make_pair( index , indexReduced ) ); - xAOD::Electron* out = new xAOD::Electron{}; - out->makePrivateStore( *x ); - output->push_back( out ); + currentSystematicThinningMap.insert(std::make_pair(index, indexReduced)); + xAOD::Electron* out = new xAOD::Electron {}; + out->makePrivateStore(*x); + output->push_back(out); ++indexReduced; } ++index; } // Loop over container - // Reset calo cluster links - for (std::map<unsigned int,unsigned int>::const_iterator i=currentSystematicThinningMap.begin();i!=currentSystematicThinningMap.end();++i) { - output->at((*i).second)->setCaloClusterLinks( xaod->at((*i).first)->caloClusterLinks() ); - } - } // saveEventObjects - top::check(evtStore()->event()->record(output,sgKey),"Failed to record xAOD::ElectronContainer"); - thinningMap->insert( std::make_pair(currentSystematic.first, currentSystematicThinningMap) ); - } // Loop over all systematics + // Reset calo cluster links + for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); + i != currentSystematicThinningMap.end(); ++i) { + output->at((*i).second)->setCaloClusterLinks(xaod->at((*i).first)->caloClusterLinks()); + } + } // saveEventObjects + top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::ElectronContainer"); + thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); + } // Loop over all systematics } // use object type - - return thinningMap; - } - + return thinningMap; + } - std::shared_ptr<std::map<std::size_t,std::map<unsigned int,unsigned int>>> EventSaverxAODNext::saveMuons(const bool saveEventObjects) - { - std::shared_ptr<ThinningMap_t> thinningMap( new ThinningMap_t ); + std::shared_ptr<std::map<std::size_t, std::map<unsigned int, unsigned int> > > EventSaverxAODNext::saveMuons( + const bool saveEventObjects) { + std::shared_ptr<ThinningMap_t> thinningMap(new ThinningMap_t); if (m_config->useMuons()) { - for (auto currentSystematic : *m_config->systSgKeyMapMuons()) { - std::map<unsigned int,unsigned int> currentSystematicThinningMap; + std::map<unsigned int, unsigned int> currentSystematicThinningMap; std::string sgKey = currentSystematic.second; const xAOD::MuonContainer* xaod(nullptr); - top::check(evtStore()->retrieve(xaod,sgKey),"Failed to retrieve muons"); - - xAOD::MuonContainer* output = new xAOD::MuonContainer{}; - SG::IAuxStore* output_aux = evtStore()->event()->recordAux( sgKey + "Aux." ); - output->setStore( output_aux ); - - if( saveEventObjects ) { - unsigned int index(0),indexReduced(0); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve muons"); + + xAOD::MuonContainer* output = new xAOD::MuonContainer {}; + SG::IAuxStore* output_aux = evtStore()->event()->recordAux(sgKey + "Aux."); + output->setStore(output_aux); + + if (saveEventObjects) { + unsigned int index(0), indexReduced(0); for (auto x : *xaod) { - bool save(m_saveAllObjects); if (x->isAvailable<char>("passPreORSelection")) { if (x->auxdataConst<char>("passPreORSelection") == 1) { @@ -424,44 +422,42 @@ namespace top { save = true; } } - + if (save) { - currentSystematicThinningMap.insert( std::make_pair( index , indexReduced ) ); - xAOD::Muon* out = new xAOD::Muon{}; - out->makePrivateStore( *x ); - output->push_back( out ); + currentSystematicThinningMap.insert(std::make_pair(index, indexReduced)); + xAOD::Muon* out = new xAOD::Muon {}; + out->makePrivateStore(*x); + output->push_back(out); ++indexReduced; } ++index; } // Loop over container - } // saveEventObjects - top::check(evtStore()->event()->record(output,sgKey),"Failed to record xAOD::MuonContainer"); - thinningMap->insert( std::make_pair(currentSystematic.first, currentSystematicThinningMap) ); - } // Loop over all systematics + } // saveEventObjects + top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::MuonContainer"); + thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); + } // Loop over all systematics } // use object type - - return thinningMap; + + return thinningMap; } - std::shared_ptr<std::map<std::size_t,std::map<unsigned int,unsigned int>>> EventSaverxAODNext::saveTaus(const bool saveEventObjects) - { - std::shared_ptr<ThinningMap_t> thinningMap( new ThinningMap_t ); + std::shared_ptr<std::map<std::size_t, std::map<unsigned int, unsigned int> > > EventSaverxAODNext::saveTaus( + const bool saveEventObjects) { + std::shared_ptr<ThinningMap_t> thinningMap(new ThinningMap_t); if (m_config->useTaus()) { - for (auto currentSystematic : *m_config->systSgKeyMapTaus()) { - std::map<unsigned int,unsigned int> currentSystematicThinningMap; + std::map<unsigned int, unsigned int> currentSystematicThinningMap; std::string sgKey = currentSystematic.second; const xAOD::TauJetContainer* xaod(nullptr); - top::check(evtStore()->retrieve(xaod,sgKey),"Failed to retrieve taus"); - - xAOD::TauJetContainer* output = new xAOD::TauJetContainer{}; - SG::IAuxStore* output_aux = evtStore()->event()->recordAux( sgKey + "Aux." ); - output->setStore( output_aux ); - - if( saveEventObjects ) { - unsigned int index(0),indexReduced(0); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve taus"); + + xAOD::TauJetContainer* output = new xAOD::TauJetContainer {}; + SG::IAuxStore* output_aux = evtStore()->event()->recordAux(sgKey + "Aux."); + output->setStore(output_aux); + + if (saveEventObjects) { + unsigned int index(0), indexReduced(0); for (auto x : *xaod) { - bool save(m_saveAllObjects); if (x->isAvailable<char>("passPreORSelection")) { if (x->auxdataConst<char>("passPreORSelection") == 1) { @@ -473,44 +469,42 @@ namespace top { save = true; } } - + if (save) { - currentSystematicThinningMap.insert( std::make_pair( index , indexReduced ) ); - xAOD::TauJet* out = new xAOD::TauJet{}; - out->makePrivateStore( *x ); - output->push_back( out ); + currentSystematicThinningMap.insert(std::make_pair(index, indexReduced)); + xAOD::TauJet* out = new xAOD::TauJet {}; + out->makePrivateStore(*x); + output->push_back(out); ++indexReduced; } ++index; } // Loop over container } // saveEventObjects - top::check(evtStore()->event()->record(output,sgKey),"Failed to record xAOD::TauJetContainer"); - thinningMap->insert( std::make_pair(currentSystematic.first, currentSystematicThinningMap) ); - } // Loop over all systematics + top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::TauJetContainer"); + thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); + } // Loop over all systematics } // use object type - - return thinningMap; + + return thinningMap; } - std::shared_ptr<std::map<std::size_t,std::map<unsigned int,unsigned int>>> EventSaverxAODNext::saveJets(const bool saveEventObjects) - { - std::shared_ptr<ThinningMap_t> thinningMap( new ThinningMap_t ); + std::shared_ptr<std::map<std::size_t, std::map<unsigned int, unsigned int> > > EventSaverxAODNext::saveJets( + const bool saveEventObjects) { + std::shared_ptr<ThinningMap_t> thinningMap(new ThinningMap_t); if (m_config->useJets()) { - for (auto currentSystematic : *m_config->systSgKeyMapJets(false)) { - std::map<unsigned int,unsigned int> currentSystematicThinningMap; + std::map<unsigned int, unsigned int> currentSystematicThinningMap; std::string sgKey = currentSystematic.second; const xAOD::JetContainer* xaod(nullptr); - top::check(evtStore()->retrieve(xaod,sgKey),"Failed to retrieve electrons"); - - xAOD::JetContainer* output = new xAOD::JetContainer{}; - SG::IAuxStore* output_aux = evtStore()->event()->recordAux( sgKey + "Aux." ); - output->setStore( output_aux ); - - if( saveEventObjects ) { - unsigned int index(0),indexReduced(0); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve electrons"); + + xAOD::JetContainer* output = new xAOD::JetContainer {}; + SG::IAuxStore* output_aux = evtStore()->event()->recordAux(sgKey + "Aux."); + output->setStore(output_aux); + + if (saveEventObjects) { + unsigned int index(0), indexReduced(0); for (auto x : *xaod) { - bool save(m_saveAllObjects); if (x->isAvailable<char>("passPreORSelection")) { if (x->auxdataConst<char>("passPreORSelection") == 1) { @@ -522,50 +516,48 @@ namespace top { save = true; } } - + if (save) { - currentSystematicThinningMap.insert( std::make_pair( index , indexReduced ) ); - xAOD::Jet* out = new xAOD::Jet{}; - out->makePrivateStore( *x ); - output->push_back( out ); + currentSystematicThinningMap.insert(std::make_pair(index, indexReduced)); + xAOD::Jet* out = new xAOD::Jet {}; + out->makePrivateStore(*x); + output->push_back(out); ++indexReduced; } ++index; } // Loop over container - + // Reset b-tagging links - for (std::map<unsigned int,unsigned int>::const_iterator i=currentSystematicThinningMap.begin();i!=currentSystematicThinningMap.end();++i) { - output->at((*i).second)->setBTaggingLink ( xaod->at((*i).first)->btaggingLink() ); + for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); + i != currentSystematicThinningMap.end(); ++i) { + output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); } - - } // saveEventObjects - top::check(evtStore()->event()->record(output,sgKey),"Failed to record xAOD::JetContainer"); - thinningMap->insert( std::make_pair(currentSystematic.first, currentSystematicThinningMap) ); - } // Loop over all systematics + } // saveEventObjects + top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::JetContainer"); + thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); + } // Loop over all systematics } // use object type - - return thinningMap; + + return thinningMap; } - std::shared_ptr<std::map<std::size_t,std::map<unsigned int,unsigned int>>> EventSaverxAODNext::saveLargeRJets(const bool saveEventObjects) - { - std::shared_ptr<ThinningMap_t> thinningMap( new ThinningMap_t ); + std::shared_ptr<std::map<std::size_t, std::map<unsigned int, unsigned int> > > EventSaverxAODNext::saveLargeRJets( + const bool saveEventObjects) { + std::shared_ptr<ThinningMap_t> thinningMap(new ThinningMap_t); if (m_config->useLargeRJets()) { - for (auto currentSystematic : *m_config->systSgKeyMapLargeRJets()) { - std::map<unsigned int,unsigned int> currentSystematicThinningMap; + std::map<unsigned int, unsigned int> currentSystematicThinningMap; std::string sgKey = currentSystematic.second; const xAOD::JetContainer* xaod(nullptr); - top::check(evtStore()->retrieve(xaod,sgKey),"Failed to retrieve electrons"); - - xAOD::JetContainer* output = new xAOD::JetContainer{}; - SG::IAuxStore* output_aux = evtStore()->event()->recordAux( sgKey + "Aux." ); - output->setStore( output_aux ); - - if( saveEventObjects ) { - unsigned int index(0),indexReduced(0); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve electrons"); + + xAOD::JetContainer* output = new xAOD::JetContainer {}; + SG::IAuxStore* output_aux = evtStore()->event()->recordAux(sgKey + "Aux."); + output->setStore(output_aux); + + if (saveEventObjects) { + unsigned int index(0), indexReduced(0); for (auto x : *xaod) { - bool save(m_saveAllObjects); if (x->isAvailable<char>("passPreORSelection")) { if (x->auxdataConst<char>("passPreORSelection") == 1) { @@ -577,50 +569,48 @@ namespace top { save = true; } } - + if (save) { - currentSystematicThinningMap.insert( std::make_pair( index , indexReduced ) ); - xAOD::Jet* out = new xAOD::Jet{}; - out->makePrivateStore( *x ); - output->push_back( out ); + currentSystematicThinningMap.insert(std::make_pair(index, indexReduced)); + xAOD::Jet* out = new xAOD::Jet {}; + out->makePrivateStore(*x); + output->push_back(out); ++indexReduced; } ++index; } // Loop over container - + // Reset b-tagging links - for (std::map<unsigned int,unsigned int>::const_iterator i=currentSystematicThinningMap.begin();i!=currentSystematicThinningMap.end();++i) { - output->at((*i).second)->setBTaggingLink ( xaod->at((*i).first)->btaggingLink() ); + for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); + i != currentSystematicThinningMap.end(); ++i) { + output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); } - } // saveEventObjects - top::check(evtStore()->event()->record(output,sgKey),"Failed to record xAOD::JetContainer"); - thinningMap->insert( std::make_pair(currentSystematic.first, currentSystematicThinningMap) ); - } // Loop over all systematics + top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::JetContainer"); + thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); + } // Loop over all systematics } // use object type - - return thinningMap; - } - - std::shared_ptr<std::map<std::size_t,std::map<unsigned int,unsigned int>>> EventSaverxAODNext::saveTrackJets(const bool saveEventObjects) - { - std::shared_ptr<ThinningMap_t> thinningMap( new ThinningMap_t ); + + return thinningMap; + } + + std::shared_ptr<std::map<std::size_t, std::map<unsigned int, unsigned int> > > EventSaverxAODNext::saveTrackJets( + const bool saveEventObjects) { + std::shared_ptr<ThinningMap_t> thinningMap(new ThinningMap_t); if (m_config->useTrackJets()) { - for (auto currentSystematic : *m_config->systSgKeyMapTrackJets()) { - std::map<unsigned int,unsigned int> currentSystematicThinningMap; + std::map<unsigned int, unsigned int> currentSystematicThinningMap; std::string sgKey = currentSystematic.second; const xAOD::JetContainer* xaod(nullptr); - top::check(evtStore()->retrieve(xaod,sgKey),"Failed to retrieve electrons"); - - xAOD::JetContainer* output = new xAOD::JetContainer{}; - SG::IAuxStore* output_aux = evtStore()->event()->recordAux( sgKey + "Aux." ); - output->setStore( output_aux ); - - if( saveEventObjects ) { - unsigned int index(0),indexReduced(0); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve electrons"); + + xAOD::JetContainer* output = new xAOD::JetContainer {}; + SG::IAuxStore* output_aux = evtStore()->event()->recordAux(sgKey + "Aux."); + output->setStore(output_aux); + + if (saveEventObjects) { + unsigned int index(0), indexReduced(0); for (auto x : *xaod) { - bool save(m_saveAllObjects); if (x->isAvailable<char>("passPreORSelection")) { if (x->auxdataConst<char>("passPreORSelection") == 1) { @@ -632,34 +622,34 @@ namespace top { save = true; } } - + if (save) { - currentSystematicThinningMap.insert( std::make_pair( index , indexReduced ) ); - xAOD::Jet* out = new xAOD::Jet{}; - out->makePrivateStore( *x ); - output->push_back( out ); + currentSystematicThinningMap.insert(std::make_pair(index, indexReduced)); + xAOD::Jet* out = new xAOD::Jet {}; + out->makePrivateStore(*x); + output->push_back(out); ++indexReduced; } ++index; } // Loop over container - + // Reset b-tagging links - for (std::map<unsigned int,unsigned int>::const_iterator i=currentSystematicThinningMap.begin();i!=currentSystematicThinningMap.end();++i) { - output->at((*i).second)->setBTaggingLink ( xaod->at((*i).first)->btaggingLink() ); + for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); + i != currentSystematicThinningMap.end(); ++i) { + output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); } - } // saveEventObjects - top::check(evtStore()->event()->record(output,sgKey),"Failed to record xAOD::JetContainer"); - thinningMap->insert( std::make_pair(currentSystematic.first, currentSystematicThinningMap) ); - } // Loop over all systematics + top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::JetContainer"); + thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); + } // Loop over all systematics } // use object type - - return thinningMap; - } - void EventSaverxAODNext::finalize() { - m_outputFile->Write(); - top::check(evtStore()->event()->finishWritingTo(m_outputFile), "EventSaverxAODNext::finalise trying to call finishWritingTo"); + return thinningMap; } + void EventSaverxAODNext::finalize() { + m_outputFile->Write(); + top::check(evtStore()->event()->finishWritingTo( + m_outputFile), "EventSaverxAODNext::finalise trying to call finishWritingTo"); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSelection.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSelection.cxx index 90f4fbf74687..2206953a410a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSelection.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSelection.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopAnalysis/EventSelection.h" #include "TopAnalysis/Tools.h" @@ -25,408 +25,494 @@ #include "TopParticleLevel/ParticleLevelEvent.h" #include "TopEventSelectionTools/FakesMMConfigs.h" +#include "TopEventSelectionTools/NJetBtagSelector.h" -namespace top { - -EventSelection::EventSelection(const std::string& name, const std::vector<std::string>& cutNames, TFile* outputFile, const std::vector<std::unique_ptr<top::ToolLoaderBase>>& toolLoaders,std::shared_ptr<top::TopConfig> config, EL::Worker* wk) : - m_cutflow(nullptr), - m_cutflow_Loose(nullptr), - m_cutflowMCWeights(nullptr), - m_cutflowMCWeights_Loose(nullptr), - m_cutflowPUWeights(nullptr), - m_cutflowPUWeights_Loose(nullptr), - m_cutflowZVtxWeights(nullptr), - m_cutflowZVtxWeights_Loose(nullptr), - m_cutflowMCPUWeights(nullptr), - m_cutflowMCPUWeights_Loose(nullptr), - m_cutflowMCPUZVtxWeights(nullptr), - m_cutflowMCPUZVtxWeights_Loose(nullptr), - m_cutflowScaleFactors(nullptr), - m_cutflowScaleFactors_Loose(nullptr), - m_cutflowBScaleFactors(nullptr), - m_cutflowBScaleFactors_Loose(nullptr), - m_cutflowParticleLevel(nullptr), - m_cutflowUpgradeLevel(nullptr), - m_name(name), - m_isMC(false), - m_sfRetriever(nullptr), - m_nominalHashValue(0), - m_containsInitial(false), - m_containsGRL(false), - m_containsGoodCalo(false), - m_containsPrimaryVertex(false), - m_positionInitial(0), - m_positionGRL(0), - m_positionGoodCalo(0), - m_positionPrimaryVertex(0), - m_toBeSaved(false) -{ +#include "TopAnalysis/MsgCategory.h" +using namespace TopAnalysis; +namespace top { + EventSelection::EventSelection(const std::string& name, const std::vector<std::string>& cutNames, TFile* outputFile, + const std::vector<std::unique_ptr<top::ToolLoaderBase> >& toolLoaders, + std::shared_ptr<top::TopConfig> config, EL::Worker* wk) : + m_cutflow(nullptr), + m_cutflow_Loose(nullptr), + m_cutflowMCWeights(nullptr), + m_cutflowMCWeights_Loose(nullptr), + m_cutflowPUWeights(nullptr), + m_cutflowPUWeights_Loose(nullptr), + m_cutflowZVtxWeights(nullptr), + m_cutflowZVtxWeights_Loose(nullptr), + m_cutflowMCPUWeights(nullptr), + m_cutflowMCPUWeights_Loose(nullptr), + m_cutflowMCPUZVtxWeights(nullptr), + m_cutflowMCPUZVtxWeights_Loose(nullptr), + m_cutflowScaleFactors(nullptr), + m_cutflowScaleFactors_Loose(nullptr), + m_cutflowBScaleFactors(nullptr), + m_cutflowBScaleFactors_Loose(nullptr), + m_cutflowParticleLevel(nullptr), + m_cutflowParticleLevelMCWeights(nullptr), + m_cutflowUpgradeLevel(nullptr), + m_name(name), + m_isMC(false), + m_sfRetriever(nullptr), + m_nominalHashValue(0), + m_containsInitial(false), + m_containsGRL(false), + m_containsGoodCalo(false), + m_containsPrimaryVertex(false), + m_positionInitial(0), + m_positionGRL(0), + m_positionGoodCalo(0), + m_positionPrimaryVertex(0), + m_toBeSaved(false) { // We use the nominal hash value so we don't do // string comparisions during the event loop CP::SystematicSet nominal; m_nominalHashValue = nominal.hash(); - + // need that later for the sf in the cutflow, not especially elegant but works for now m_config = config; - m_isMC = config->isMC(); + m_isMC = config->isMC(); - if(m_isMC) - m_sfRetriever = std::unique_ptr<top::ScaleFactorRetriever> ( new top::ScaleFactorRetriever( config) ); + if (m_isMC) { + this->initialiseTopScaleFactorRetriever(m_config); + } TDirectory* plotDir = outputFile->mkdir(m_name.c_str()); plotDir->cd(); - if (!config->doLooseTreeOnly()) { + if (config->doTightEvents()) { m_cutflow = new TH1D("cutflow", (name + " cutflow").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowMCWeights = new TH1D("cutflow_mc", (name + " cutflow MC weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowPUWeights = new TH1D("cutflow_pu", (name + " cutflow PU weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowZVtxWeights = new TH1D("cutflow_zvtx", (name + " cutflow ZVtx weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowMCPUWeights = new TH1D("cutflow_mc_pu", (name + " cutflow MC*PU weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowMCPUZVtxWeights = new TH1D("cutflow_mc_pu_zvtx", (name + " cutflow MC*PU*ZVtx weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowScaleFactors = new TH1D("cutflow_scale_factors", (name + " cutflow ScaleFactors").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowBScaleFactors = new TH1D("cutflow_btag_scale_factors", (name + " cutflow b-tag ScaleFactors").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowMCWeights = new TH1D("cutflow_mc", (name + " cutflow MC weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowPUWeights = new TH1D("cutflow_pu", (name + " cutflow PU weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowZVtxWeights = new TH1D("cutflow_zvtx", (name + " cutflow ZVtx weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowMCPUWeights = new TH1D("cutflow_mc_pu", (name + " cutflow MC*PU weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowMCPUZVtxWeights = new TH1D("cutflow_mc_pu_zvtx", + (name + " cutflow MC*PU*ZVtx weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowScaleFactors = new TH1D("cutflow_scale_factors", (name + " cutflow ScaleFactors").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowBScaleFactors = new TH1D("cutflow_btag_scale_factors", + (name + " cutflow b-tag ScaleFactors").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); } if (config->doLooseEvents()) { - m_cutflow_Loose = new TH1D("cutflow_Loose", (name + " cutflow_Loose").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowMCWeights_Loose = new TH1D("cutflow_mc_Loose", (name + " cutflow_Loose MC weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowPUWeights_Loose = new TH1D("cutflow_pu_Loose", (name + " cutflow_Loose PU weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowZVtxWeights_Loose = new TH1D("cutflow_zvtx_Loose", (name + " cutflow_Loose ZVtx weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowMCPUWeights_Loose = new TH1D("cutflow_mc_pu_Loose", (name + " cutflow_Loose MC*PU weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowMCPUZVtxWeights_Loose = new TH1D("cutflow_mc_pu_zvtx_Loose", (name + " cutflow_Loose MC*PU*ZVtx weights").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowScaleFactors_Loose = new TH1D("cutflow_scale_factors_Loose", (name + " cutflow_Loose ScaleFactors").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); - m_cutflowBScaleFactors_Loose = new TH1D("cutflow_btag_scale_factors_Loose", (name + " cutflow_Loose b-tag ScaleFactors").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflow_Loose = new TH1D("cutflow_Loose", (name + " cutflow_Loose").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowMCWeights_Loose = new TH1D("cutflow_mc_Loose", + (name + " cutflow_Loose MC weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowPUWeights_Loose = new TH1D("cutflow_pu_Loose", + (name + " cutflow_Loose PU weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowZVtxWeights_Loose = new TH1D("cutflow_zvtx_Loose", + (name + " cutflow_Loose ZVtx weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowMCPUWeights_Loose = new TH1D("cutflow_mc_pu_Loose", + (name + " cutflow_Loose MC*PU weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowMCPUZVtxWeights_Loose = new TH1D("cutflow_mc_pu_zvtx_Loose", + (name + " cutflow_Loose MC*PU*ZVtx weights").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowScaleFactors_Loose = new TH1D("cutflow_scale_factors_Loose", + (name + " cutflow_Loose ScaleFactors").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowBScaleFactors_Loose = + new TH1D("cutflow_btag_scale_factors_Loose", (name + " cutflow_Loose b-tag ScaleFactors").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); } - if ( config->doTopParticleLevel() ){ - m_cutflowParticleLevel = new TH1D("cutflow_particle_level", (name + " cutflow_particle_level").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); + if (config->doTopParticleLevel()) { + m_cutflowParticleLevel = new TH1D("cutflow_particle_level", + (name + " cutflow_particle_level").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); + m_cutflowParticleLevelMCWeights = new TH1D("cutflow_particle_level_mc", + (name + " cutflow_particle_level_mc").c_str(), + cutNames.size(), -0.5, cutNames.size() - 0.5); } - if ( config->HLLHC() ){ - m_cutflowUpgradeLevel = new TH1D("cutflow_upgrade_level", (name + " cutflow_upgrade_level").c_str(), cutNames.size(), -0.5, cutNames.size() - 0.5); + if (config->HLLHC()) { + m_cutflowUpgradeLevel = new TH1D("cutflow_upgrade_level", + (name + " cutflow_upgrade_level").c_str(), cutNames.size(), -0.5, + cutNames.size() - 0.5); } unsigned int i(0); for (const auto& currentCutName : cutNames) { + //look through all the libraries and load any tools + top::EventSelectorBase* tool = nullptr; + for (auto& libraryPtr : toolLoaders) { + tool = libraryPtr->initTool(m_name, currentCutName, outputFile, config, wk); + if (tool) break; + } - //look through all the libraries and load any tools - top::EventSelectorBase* tool = nullptr; - for (auto& libraryPtr : toolLoaders) { - tool = libraryPtr->initTool(m_name, currentCutName, outputFile, config, wk); - if (tool) - break; - } + if (tool != nullptr) { + m_allCuts.emplace_back(std::move(tool)); + } else { + throw std::runtime_error("Could not find " + currentCutName); + } - if (tool != nullptr) { - m_allCuts.emplace_back(std::move(tool)); - } else { - std::cout << "Could not find " << currentCutName << std::endl; - exit(1); - } - - // Initlal and GRL - if (currentCutName == "INITIAL") { - m_containsInitial = true; - m_positionInitial = i; - } - - if (currentCutName == "GRL") { - m_containsGRL = true; - m_positionGRL = i; - } - - if (currentCutName == "GOODCALO") { - m_containsGoodCalo = true; - m_positionGoodCalo = i; - } - - if (currentCutName == "PRIVTX") { - m_containsPrimaryVertex = true; - m_positionPrimaryVertex = i; - } - - //some cutflow histograms - if (!config->doLooseTreeOnly()) { - m_cutflow->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowMCWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowPUWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowZVtxWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowMCPUWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowMCPUZVtxWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowScaleFactors->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowBScaleFactors->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - } - if (config->doLooseEvents()) { - m_cutflow_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowMCWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowPUWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowZVtxWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowMCPUWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowMCPUZVtxWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowScaleFactors_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - m_cutflowBScaleFactors_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - } + // Initlal and GRL + if (currentCutName == "INITIAL") { + m_containsInitial = true; + m_positionInitial = i; + } - if ( m_cutflowParticleLevel ){ - m_cutflowParticleLevel->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - } + if (currentCutName == "GRL") { + m_containsGRL = true; + m_positionGRL = i; + } - if ( m_cutflowUpgradeLevel ){ - m_cutflowUpgradeLevel->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); - } - - if (currentCutName == "SAVE") { - m_toBeSaved = true; - } + if (currentCutName == "GOODCALO") { + m_containsGoodCalo = true; + m_positionGoodCalo = i; + } + + if (currentCutName == "PRIVTX") { + m_containsPrimaryVertex = true; + m_positionPrimaryVertex = i; + } + + //some cutflow histograms + if (config->doTightEvents()) { + m_cutflow->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowMCWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowPUWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowZVtxWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowMCPUWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowMCPUZVtxWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowScaleFactors->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowBScaleFactors->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + } + if (config->doLooseEvents()) { + m_cutflow_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowMCWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowPUWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowZVtxWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowMCPUWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowMCPUZVtxWeights_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowScaleFactors_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + m_cutflowBScaleFactors_Loose->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + } + + if (m_cutflowParticleLevel) { + m_cutflowParticleLevel->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + } + + if (m_cutflowParticleLevelMCWeights) { + m_cutflowParticleLevelMCWeights->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + } + + if (m_cutflowUpgradeLevel) { + m_cutflowUpgradeLevel->GetXaxis()->SetBinLabel(i + 1, m_allCuts[i]->name().c_str()); + } + + if (currentCutName == "SAVE") { + m_toBeSaved = true; + } - ++i; + ++i; } //be nice to the user and tell them what they enabled //at the very start of the run. It allows them to quit the program //if they notice a problem. printCuts(); -} - -EventSelection::EventSelection(EventSelection&& other) : - m_allCuts(std::move(other.m_allCuts)), - m_cutflow(std::move(other.m_cutflow)), - m_cutflow_Loose(std::move(other.m_cutflow_Loose)), - m_cutflowMCWeights(std::move(other.m_cutflowMCWeights)), - m_cutflowMCWeights_Loose(std::move(other.m_cutflowMCWeights_Loose)), - m_cutflowPUWeights(std::move(other.m_cutflowPUWeights)), - m_cutflowPUWeights_Loose(std::move(other.m_cutflowPUWeights_Loose)), - m_cutflowZVtxWeights(std::move(other.m_cutflowZVtxWeights)), - m_cutflowZVtxWeights_Loose(std::move(other.m_cutflowZVtxWeights_Loose)), - m_cutflowMCPUWeights(std::move(other.m_cutflowMCPUWeights)), - m_cutflowMCPUWeights_Loose(std::move(other.m_cutflowMCPUWeights_Loose)), - m_cutflowMCPUZVtxWeights(std::move(other.m_cutflowMCPUZVtxWeights)), - m_cutflowMCPUZVtxWeights_Loose(std::move(other.m_cutflowMCPUZVtxWeights_Loose)), - m_cutflowScaleFactors(std::move(other.m_cutflowScaleFactors)), - m_cutflowScaleFactors_Loose(std::move(other.m_cutflowScaleFactors_Loose)), - m_cutflowBScaleFactors(std::move(other.m_cutflowBScaleFactors)), - m_cutflowBScaleFactors_Loose(std::move(other.m_cutflowBScaleFactors_Loose)), - m_cutflowParticleLevel(std::move(other.m_cutflowParticleLevel)), - m_cutflowUpgradeLevel(std::move(other.m_cutflowUpgradeLevel)), - m_name(std::move(other.m_name)), - m_isMC(std::move(other.m_isMC)), - m_config(std::move(other.m_config)), - m_sfRetriever(nullptr), - m_nominalHashValue(std::move(other.m_nominalHashValue)), - m_containsInitial(std::move(other.m_containsInitial)), - m_containsGRL(std::move(other.m_containsGRL)), - m_containsGoodCalo(std::move(other.m_containsGoodCalo)), - m_containsPrimaryVertex(std::move(other.m_containsPrimaryVertex)), - m_positionInitial(std::move(other.m_positionInitial)), - m_positionGRL(std::move(other.m_positionGRL)), - m_positionGoodCalo(std::move(other.m_positionGoodCalo)), - m_positionPrimaryVertex(std::move(other.m_positionPrimaryVertex)), - m_toBeSaved(std::move(other.m_toBeSaved)) -{ - - // need this to calculate the lepton SF for the cutflow - if(m_isMC) - m_sfRetriever = std::unique_ptr<top::ScaleFactorRetriever> ( new top::ScaleFactorRetriever( m_config ) ); - -} + } -void EventSelection::countInitial(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) const -{ - if (m_containsInitial) { - if (!m_config->doLooseTreeOnly()) { - m_cutflow->Fill(m_positionInitial); - m_cutflowMCWeights->Fill(m_positionInitial,mcEventWeight); - m_cutflowPUWeights->Fill(m_positionInitial,pileupWeight); - m_cutflowZVtxWeights->Fill(m_positionInitial,zvtxWeight); - m_cutflowMCPUWeights->Fill(m_positionInitial,mcEventWeight*pileupWeight); - m_cutflowMCPUZVtxWeights->Fill(m_positionInitial,mcEventWeight*pileupWeight*zvtxWeight); - } - if (m_config->doLooseEvents()) { - m_cutflow_Loose->Fill(m_positionInitial); - m_cutflowMCWeights_Loose->Fill(m_positionInitial,mcEventWeight); - m_cutflowPUWeights_Loose->Fill(m_positionInitial,pileupWeight); - m_cutflowZVtxWeights_Loose->Fill(m_positionInitial,zvtxWeight); - m_cutflowMCPUWeights_Loose->Fill(m_positionInitial,mcEventWeight*pileupWeight); - m_cutflowMCPUZVtxWeights_Loose->Fill(m_positionInitial,mcEventWeight*pileupWeight*zvtxWeight); + EventSelection::EventSelection(EventSelection&& other) : + m_allCuts(std::move(other.m_allCuts)), + m_cutflow(std::move(other.m_cutflow)), + m_cutflow_Loose(std::move(other.m_cutflow_Loose)), + m_cutflowMCWeights(std::move(other.m_cutflowMCWeights)), + m_cutflowMCWeights_Loose(std::move(other.m_cutflowMCWeights_Loose)), + m_cutflowPUWeights(std::move(other.m_cutflowPUWeights)), + m_cutflowPUWeights_Loose(std::move(other.m_cutflowPUWeights_Loose)), + m_cutflowZVtxWeights(std::move(other.m_cutflowZVtxWeights)), + m_cutflowZVtxWeights_Loose(std::move(other.m_cutflowZVtxWeights_Loose)), + m_cutflowMCPUWeights(std::move(other.m_cutflowMCPUWeights)), + m_cutflowMCPUWeights_Loose(std::move(other.m_cutflowMCPUWeights_Loose)), + m_cutflowMCPUZVtxWeights(std::move(other.m_cutflowMCPUZVtxWeights)), + m_cutflowMCPUZVtxWeights_Loose(std::move(other.m_cutflowMCPUZVtxWeights_Loose)), + m_cutflowScaleFactors(std::move(other.m_cutflowScaleFactors)), + m_cutflowScaleFactors_Loose(std::move(other.m_cutflowScaleFactors_Loose)), + m_cutflowBScaleFactors(std::move(other.m_cutflowBScaleFactors)), + m_cutflowBScaleFactors_Loose(std::move(other.m_cutflowBScaleFactors_Loose)), + m_cutflowParticleLevel(std::move(other.m_cutflowParticleLevel)), + m_cutflowParticleLevelMCWeights(std::move(other.m_cutflowParticleLevelMCWeights)), + m_cutflowUpgradeLevel(std::move(other.m_cutflowUpgradeLevel)), + m_name(std::move(other.m_name)), + m_isMC(std::move(other.m_isMC)), + m_config(std::move(other.m_config)), + m_sfRetriever(nullptr), + m_nominalHashValue(std::move(other.m_nominalHashValue)), + m_containsInitial(std::move(other.m_containsInitial)), + m_containsGRL(std::move(other.m_containsGRL)), + m_containsGoodCalo(std::move(other.m_containsGoodCalo)), + m_containsPrimaryVertex(std::move(other.m_containsPrimaryVertex)), + m_positionInitial(std::move(other.m_positionInitial)), + m_positionGRL(std::move(other.m_positionGRL)), + m_positionGoodCalo(std::move(other.m_positionGoodCalo)), + m_positionPrimaryVertex(std::move(other.m_positionPrimaryVertex)), + m_toBeSaved(std::move(other.m_toBeSaved)) { + // need this to calculate the lepton SF for the cutflow + if (m_isMC) { + this->initialiseTopScaleFactorRetriever(m_config); } } -} -void EventSelection::countGRL(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) const -{ - if (m_containsGRL) { - if (!m_config->doLooseTreeOnly()) { - m_cutflow->Fill(m_positionGRL); - m_cutflowMCWeights->Fill(m_positionGRL,mcEventWeight); - m_cutflowPUWeights->Fill(m_positionGRL,pileupWeight); - m_cutflowZVtxWeights->Fill(m_positionGRL,zvtxWeight); - m_cutflowMCPUWeights->Fill(m_positionGRL,mcEventWeight*pileupWeight); - m_cutflowMCPUZVtxWeights->Fill(m_positionGRL,mcEventWeight*pileupWeight*zvtxWeight); - } - if (m_config->doLooseEvents()) { - m_cutflow_Loose->Fill(m_positionGRL); - m_cutflowMCWeights_Loose->Fill(m_positionGRL,mcEventWeight); - m_cutflowPUWeights_Loose->Fill(m_positionGRL,pileupWeight); - m_cutflowZVtxWeights_Loose->Fill(m_positionGRL,zvtxWeight); - m_cutflowMCPUWeights_Loose->Fill(m_positionGRL,mcEventWeight*pileupWeight); - m_cutflowMCPUZVtxWeights_Loose->Fill(m_positionGRL,mcEventWeight*pileupWeight*zvtxWeight); + void EventSelection::initialiseTopScaleFactorRetriever(std::shared_ptr<TopConfig> config) { + // Define this once, and then use it when needed + if (asg::ToolStore::contains<ScaleFactorRetriever>("top::ScaleFactorRetriever")) { + m_sfRetriever = asg::ToolStore::get<ScaleFactorRetriever>("top::ScaleFactorRetriever"); + } else { + top::ScaleFactorRetriever* topSFR = new top::ScaleFactorRetriever("top::ScaleFactorRetriever"); + top::check(asg::setProperty(topSFR, "config", config), "Failed to set config"); + top::check(topSFR->initialize(), "Failed to initalialise"); + m_sfRetriever = topSFR; } } -} -void EventSelection::countGoodCalo(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) const -{ - if (m_containsGoodCalo) { - if (!m_config->doLooseTreeOnly()) { - m_cutflow->Fill(m_positionGoodCalo); - m_cutflowMCWeights->Fill(m_positionGoodCalo,mcEventWeight); - m_cutflowPUWeights->Fill(m_positionGoodCalo,pileupWeight); - m_cutflowZVtxWeights->Fill(m_positionGoodCalo,zvtxWeight); - m_cutflowMCPUWeights->Fill(m_positionGoodCalo,mcEventWeight*pileupWeight); - m_cutflowMCPUZVtxWeights->Fill(m_positionGoodCalo,mcEventWeight*pileupWeight*zvtxWeight); + void EventSelection::countInitial(const float mcEventWeight, const float pileupWeight, const float zvtxWeight) const { + if (m_containsInitial) { + if (m_config->doTightEvents()) { + m_cutflow->Fill(m_positionInitial); + m_cutflowMCWeights->Fill(m_positionInitial, mcEventWeight); + m_cutflowPUWeights->Fill(m_positionInitial, pileupWeight); + m_cutflowZVtxWeights->Fill(m_positionInitial, zvtxWeight); + m_cutflowMCPUWeights->Fill(m_positionInitial, mcEventWeight * pileupWeight); + m_cutflowMCPUZVtxWeights->Fill(m_positionInitial, mcEventWeight * pileupWeight * zvtxWeight); + } + if (m_config->doLooseEvents()) { + m_cutflow_Loose->Fill(m_positionInitial); + m_cutflowMCWeights_Loose->Fill(m_positionInitial, mcEventWeight); + m_cutflowPUWeights_Loose->Fill(m_positionInitial, pileupWeight); + m_cutflowZVtxWeights_Loose->Fill(m_positionInitial, zvtxWeight); + m_cutflowMCPUWeights_Loose->Fill(m_positionInitial, mcEventWeight * pileupWeight); + m_cutflowMCPUZVtxWeights_Loose->Fill(m_positionInitial, mcEventWeight * pileupWeight * zvtxWeight); + } } - if (m_config->doLooseEvents()) { - m_cutflow_Loose->Fill(m_positionGoodCalo); - m_cutflowMCWeights_Loose->Fill(m_positionGoodCalo,mcEventWeight); - m_cutflowPUWeights_Loose->Fill(m_positionGoodCalo,pileupWeight); - m_cutflowZVtxWeights_Loose->Fill(m_positionGoodCalo,zvtxWeight); - m_cutflowMCPUWeights_Loose->Fill(m_positionGoodCalo,mcEventWeight*pileupWeight); - m_cutflowMCPUZVtxWeights_Loose->Fill(m_positionGoodCalo,mcEventWeight*pileupWeight*zvtxWeight); + } + + void EventSelection::countGRL(const float mcEventWeight, const float pileupWeight, const float zvtxWeight) const { + if (m_containsGRL) { + if (m_config->doTightEvents()) { + m_cutflow->Fill(m_positionGRL); + m_cutflowMCWeights->Fill(m_positionGRL, mcEventWeight); + m_cutflowPUWeights->Fill(m_positionGRL, pileupWeight); + m_cutflowZVtxWeights->Fill(m_positionGRL, zvtxWeight); + m_cutflowMCPUWeights->Fill(m_positionGRL, mcEventWeight * pileupWeight); + m_cutflowMCPUZVtxWeights->Fill(m_positionGRL, mcEventWeight * pileupWeight * zvtxWeight); + } + if (m_config->doLooseEvents()) { + m_cutflow_Loose->Fill(m_positionGRL); + m_cutflowMCWeights_Loose->Fill(m_positionGRL, mcEventWeight); + m_cutflowPUWeights_Loose->Fill(m_positionGRL, pileupWeight); + m_cutflowZVtxWeights_Loose->Fill(m_positionGRL, zvtxWeight); + m_cutflowMCPUWeights_Loose->Fill(m_positionGRL, mcEventWeight * pileupWeight); + m_cutflowMCPUZVtxWeights_Loose->Fill(m_positionGRL, mcEventWeight * pileupWeight * zvtxWeight); + } } } -} -void EventSelection::countPrimaryVertex(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) const -{ - if (m_containsPrimaryVertex) { - if (!m_config->doLooseTreeOnly()) { - m_cutflow->Fill(m_positionPrimaryVertex); - m_cutflowMCWeights->Fill(m_positionPrimaryVertex,mcEventWeight); - m_cutflowPUWeights->Fill(m_positionPrimaryVertex,pileupWeight); - m_cutflowZVtxWeights->Fill(m_positionPrimaryVertex,zvtxWeight); - m_cutflowMCPUWeights->Fill(m_positionPrimaryVertex,mcEventWeight*pileupWeight); - m_cutflowMCPUZVtxWeights->Fill(m_positionPrimaryVertex,mcEventWeight*pileupWeight*zvtxWeight); + void EventSelection::countGoodCalo(const float mcEventWeight, const float pileupWeight, + const float zvtxWeight) const { + if (m_containsGoodCalo) { + if (m_config->doTightEvents()) { + m_cutflow->Fill(m_positionGoodCalo); + m_cutflowMCWeights->Fill(m_positionGoodCalo, mcEventWeight); + m_cutflowPUWeights->Fill(m_positionGoodCalo, pileupWeight); + m_cutflowZVtxWeights->Fill(m_positionGoodCalo, zvtxWeight); + m_cutflowMCPUWeights->Fill(m_positionGoodCalo, mcEventWeight * pileupWeight); + m_cutflowMCPUZVtxWeights->Fill(m_positionGoodCalo, mcEventWeight * pileupWeight * zvtxWeight); + } + if (m_config->doLooseEvents()) { + m_cutflow_Loose->Fill(m_positionGoodCalo); + m_cutflowMCWeights_Loose->Fill(m_positionGoodCalo, mcEventWeight); + m_cutflowPUWeights_Loose->Fill(m_positionGoodCalo, pileupWeight); + m_cutflowZVtxWeights_Loose->Fill(m_positionGoodCalo, zvtxWeight); + m_cutflowMCPUWeights_Loose->Fill(m_positionGoodCalo, mcEventWeight * pileupWeight); + m_cutflowMCPUZVtxWeights_Loose->Fill(m_positionGoodCalo, mcEventWeight * pileupWeight * zvtxWeight); + } } - if (m_config->doLooseEvents()) { - m_cutflow_Loose->Fill(m_positionPrimaryVertex); - m_cutflowMCWeights_Loose->Fill(m_positionPrimaryVertex,mcEventWeight); - m_cutflowPUWeights_Loose->Fill(m_positionPrimaryVertex,pileupWeight); - m_cutflowZVtxWeights_Loose->Fill(m_positionPrimaryVertex,zvtxWeight); - m_cutflowMCPUWeights_Loose->Fill(m_positionPrimaryVertex,mcEventWeight*pileupWeight); - m_cutflowMCPUZVtxWeights_Loose->Fill(m_positionPrimaryVertex,mcEventWeight*pileupWeight*zvtxWeight); + } + + void EventSelection::countPrimaryVertex(const float mcEventWeight, const float pileupWeight, + const float zvtxWeight) const { + if (m_containsPrimaryVertex) { + if (m_config->doTightEvents()) { + m_cutflow->Fill(m_positionPrimaryVertex); + m_cutflowMCWeights->Fill(m_positionPrimaryVertex, mcEventWeight); + m_cutflowPUWeights->Fill(m_positionPrimaryVertex, pileupWeight); + m_cutflowZVtxWeights->Fill(m_positionPrimaryVertex, zvtxWeight); + m_cutflowMCPUWeights->Fill(m_positionPrimaryVertex, mcEventWeight * pileupWeight); + m_cutflowMCPUZVtxWeights->Fill(m_positionPrimaryVertex, mcEventWeight * pileupWeight * zvtxWeight); + } + if (m_config->doLooseEvents()) { + m_cutflow_Loose->Fill(m_positionPrimaryVertex); + m_cutflowMCWeights_Loose->Fill(m_positionPrimaryVertex, mcEventWeight); + m_cutflowPUWeights_Loose->Fill(m_positionPrimaryVertex, pileupWeight); + m_cutflowZVtxWeights_Loose->Fill(m_positionPrimaryVertex, zvtxWeight); + m_cutflowMCPUWeights_Loose->Fill(m_positionPrimaryVertex, mcEventWeight * pileupWeight); + m_cutflowMCPUZVtxWeights_Loose->Fill(m_positionPrimaryVertex, mcEventWeight * pileupWeight * zvtxWeight); + } } } -} -bool EventSelection::apply(const top::Event& event) const { + bool EventSelection::apply(const top::Event& event) const { unsigned int i(0); bool passEvent(false); - for (const auto& currentCut : m_allCuts) { - const bool passed = currentCut->apply(event); - //std::cout << (*it)->name() << " " << passed << std::endl; + std::string btag_string = ""; + std::string nBtagCutName = "JET_N_BTAG"; + std::string nBtagCutName_tjet = "TJET_N_BTAG"; + + // Find if this cutflow uses JET_N_BTAG or TJET_N_BTAG to identify appropriate b-tagging WP SF (if available) + // Implicitly assumes you only apply one n-btag condition (and is only for cutflow use) + auto foundBtagSelection = std::find_if(m_allCuts.begin(), m_allCuts.end(), + [&nBtagCutName](const auto& thisCut) { + return(thisCut->name() == nBtagCutName); + }); + auto foundBtagSelection_tjet = std::find_if(m_allCuts.begin(), m_allCuts.end(), + [&nBtagCutName_tjet](const auto& thisCut) { + return(thisCut->name() == nBtagCutName_tjet); + }); + if (foundBtagSelection_tjet != m_allCuts.end()) { + NJetBtagSelector* nJetBtagSelection = dynamic_cast<NJetBtagSelector*>((*foundBtagSelection_tjet).get()); + btag_string = nJetBtagSelection->getFullCutName(); + } else if (foundBtagSelection != m_allCuts.end()) { + NJetBtagSelector* nJetBtagSelection = dynamic_cast<NJetBtagSelector*>((*foundBtagSelection).get()); + btag_string = nJetBtagSelection->getFullCutName(); + } - if (!passed) - break; + for (const auto& currentCut : m_allCuts) { + const bool passed = currentCut->apply(event); - double mcweight = 1.; - double puweight = 1.; - double zvtxweight = 1.; - double leptonSF = 1.; - double btagSF = 1.; + if (!passed) break; - if (m_isMC) { -// mcweight = event.m_info->mcEventWeight(); - mcweight = event.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix + double mcweight = 1.; + double puweight = 1.; + double zvtxweight = 1.; + double leptonSF = 1.; + double btagSF = 1.; - if (top::ScaleFactorRetriever::hasPileupSF(event)) - puweight = top::ScaleFactorRetriever::pileupSF(event); + if (m_isMC) { + mcweight = event.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); - leptonSF = m_sfRetriever -> leptonSF(event, top::topSFSyst::nominal); + if (top::ScaleFactorRetriever::hasPileupSF(event)) puweight = top::ScaleFactorRetriever::pileupSF(event); - for (auto& tag : ( m_config->useTrackJets() ? m_config->bTagWP_available_trkJet() : m_config->bTagWP_available())){ - btagSF = m_sfRetriever -> btagSF(event, top::topSFSyst::nominal, tag, m_config->useTrackJets()); - } + leptonSF = m_sfRetriever->leptonSF(event, top::topSFSyst::nominal); + // Need to be careful with b-tagging. Can now load multiple taggers/calibrated or not. + // Can only retrieve SF for cutflow if its calibrated + if ((m_config->useTrackJets() && + std::find(m_config->bTagWP_calibrated_trkJet().begin(), m_config->bTagWP_calibrated_trkJet().end(), + btag_string) != m_config->bTagWP_calibrated_trkJet().end()) || + (!m_config->useTrackJets() && + std::find(m_config->bTagWP_calibrated().begin(), m_config->bTagWP_calibrated().end(), + btag_string) != m_config->bTagWP_calibrated().end())) { + btagSF = m_sfRetriever->btagSF(event, top::topSFSyst::nominal, btag_string, m_config->useTrackJets()); } + } - //add cutflow information for the nominal (not systematic) selection - //For data we have (sometimes) the same event with loose and tight - //The cutflow is just the "analysis" -> tight to avoid double counting - if (event.m_hashValue == m_nominalHashValue) { - bool countThisCut(true); - if ( m_containsInitial && i == m_positionInitial) {countThisCut = false;} - if ( m_containsGRL && i == m_positionGRL) {countThisCut = false;} - if ( m_containsGoodCalo && i == m_positionGoodCalo) {countThisCut = false;} - if ( m_containsPrimaryVertex && i == m_positionPrimaryVertex) {countThisCut = false;} - if (countThisCut) { - if (!m_config->doLooseTreeOnly() && !event.m_isLoose) { - m_cutflow->Fill(i); - m_cutflowMCWeights->Fill(i, mcweight); - m_cutflowPUWeights->Fill(i, puweight); - m_cutflowZVtxWeights->Fill(i, zvtxweight); - m_cutflowMCPUWeights->Fill(i, mcweight * puweight); - m_cutflowMCPUZVtxWeights->Fill(i, mcweight * puweight * zvtxweight); - m_cutflowScaleFactors->Fill(i, leptonSF); - m_cutflowBScaleFactors->Fill(i, btagSF); - } - if (m_config->doLooseEvents() && event.m_isLoose) { - m_cutflow_Loose->Fill(i); - m_cutflowMCWeights_Loose->Fill(i, mcweight); - m_cutflowPUWeights_Loose->Fill(i, puweight); - m_cutflowZVtxWeights_Loose->Fill(i, zvtxweight); - m_cutflowMCPUWeights_Loose->Fill(i, mcweight * puweight); - m_cutflowMCPUZVtxWeights_Loose->Fill(i, mcweight * puweight * zvtxweight); - m_cutflowScaleFactors_Loose->Fill(i, leptonSF); - m_cutflowBScaleFactors_Loose->Fill(i, btagSF); - } + //add cutflow information for the nominal (not systematic) selection + //For data we have (sometimes) the same event with loose and tight + //The cutflow is just the "analysis" -> tight to avoid double counting + if (event.m_hashValue == m_nominalHashValue) { + bool countThisCut(true); + if (m_containsInitial && i == m_positionInitial) { + countThisCut = false; + } + if (m_containsGRL && i == m_positionGRL) { + countThisCut = false; + } + if (m_containsGoodCalo && i == m_positionGoodCalo) { + countThisCut = false; + } + if (m_containsPrimaryVertex && i == m_positionPrimaryVertex) { + countThisCut = false; + } + if (countThisCut) { + if (m_config->doTightEvents() && !event.m_isLoose) { + m_cutflow->Fill(i); + m_cutflowMCWeights->Fill(i, mcweight); + m_cutflowPUWeights->Fill(i, puweight); + m_cutflowZVtxWeights->Fill(i, zvtxweight); + m_cutflowMCPUWeights->Fill(i, mcweight * puweight); + m_cutflowMCPUZVtxWeights->Fill(i, mcweight * puweight * zvtxweight); + m_cutflowScaleFactors->Fill(i, leptonSF); + m_cutflowBScaleFactors->Fill(i, btagSF); + } + if (m_config->doLooseEvents() && event.m_isLoose) { + m_cutflow_Loose->Fill(i); + m_cutflowMCWeights_Loose->Fill(i, mcweight); + m_cutflowPUWeights_Loose->Fill(i, puweight); + m_cutflowZVtxWeights_Loose->Fill(i, zvtxweight); + m_cutflowMCPUWeights_Loose->Fill(i, mcweight * puweight); + m_cutflowMCPUZVtxWeights_Loose->Fill(i, mcweight * puweight * zvtxweight); + m_cutflowScaleFactors_Loose->Fill(i, leptonSF); + m_cutflowBScaleFactors_Loose->Fill(i, btagSF); } } + } - passEvent |= (currentCut->name() == "SAVE"); - ++i; + passEvent |= (currentCut->name() == "SAVE"); + ++i; } // If "SAVE" wasn't found but event passes all cuts, event passes the selection passEvent |= (i == m_allCuts.size()); return passEvent; -} + } -bool EventSelection::applyParticleLevel(const top::ParticleLevelEvent& plEvent) const { + bool EventSelection::applyParticleLevel(const top::ParticleLevelEvent& plEvent) const { // In principle, this function should never be called for non-active // particle level. However, for code safetly, include a null pointer // check. Return false here because "do-not-do-particle-level" is equivalent // to "do-no-save-particle-level". - if ( not m_cutflowParticleLevel ){ return false; } + if (not m_cutflowParticleLevel) { + return false; + } + if (not m_cutflowParticleLevelMCWeights) { + return false; + } unsigned int i(0); bool passEvent(false); for (const auto& currentCut : m_allCuts) { - const bool passed = currentCut->applyParticleLevel( plEvent ); - //std::cout << (*it)->name() << " " << passed << std::endl; + const bool passed = currentCut->applyParticleLevel(plEvent); - if (!passed) - break; + if (!passed) break; - m_cutflowParticleLevel->Fill(i); + m_cutflowParticleLevel->Fill(i); - passEvent |= (currentCut->name() == "SAVE"); - ++i; + double mcweight = plEvent.m_info->mcEventWeight(0); + m_cutflowParticleLevelMCWeights->Fill(i, mcweight); + + passEvent |= (currentCut->name() == "SAVE"); + ++i; } // If "SAVE" wasn't found but event passes all cuts, event passes the selection passEvent |= (i == m_allCuts.size()); return passEvent; -} + } -bool EventSelection::applyUpgradeLevel(const top::ParticleLevelEvent& upgradeEvent) const { + bool EventSelection::applyUpgradeLevel(const top::ParticleLevelEvent& upgradeEvent) const { // In principle, this function should never be called for non-active // upgrade level. However, for code safetly, include a null pointer // check. Return false here because "do-not-do-particle-level" is equivalent // to "do-no-save-particle-level". - if ( not m_cutflowUpgradeLevel ){ return false; } + if (not m_cutflowUpgradeLevel) { + return false; + } unsigned int i(0); bool passEvent(false); @@ -434,11 +520,9 @@ bool EventSelection::applyUpgradeLevel(const top::ParticleLevelEvent& upgradeEve for (const auto& currentCut : m_allCuts) { // we use applyParticleLevel, because in the end upgrade events are smeared // truth level, so we can just re-use this function - const bool passed = currentCut->applyParticleLevel( upgradeEvent ); - //std::cout << (*it)->name() << " " << passed << std::endl; + const bool passed = currentCut->applyParticleLevel(upgradeEvent); - if (!passed) - break; + if (!passed) break; m_cutflowUpgradeLevel->Fill(i); @@ -450,149 +534,163 @@ bool EventSelection::applyUpgradeLevel(const top::ParticleLevelEvent& upgradeEve passEvent |= (i == m_allCuts.size()); return passEvent; -} + } -void EventSelection::finalise() const { + void EventSelection::finalise() const { //2dp, neater output for numbers - std::cout << std::right; - if (m_isMC) - std::cout << std::fixed << std::setprecision(2); - - if (!m_config->doLooseTreeOnly()) { - //channel name - std::cout << " - " << m_name << " cutflow:\n"; - - //some headings - std::cout << std::setw(7) << "" << - std::setw(30) << "cut" << - std::setw(15) << "events"; - - if (m_isMC) - std::cout << std::setw(15) << "mc weights" << - std::setw(15) << "mc*pu weights" << - std::setw(15) << "lepton SF" << - std::setw(15) << "b-tag SF" ; - - if( m_cutflowParticleLevel ) { - std::cout << std::setw(15) << "particle level"; - } - - if( m_cutflowUpgradeLevel ) { - std::cout << std::setw(15) << "upgrade level"; - } + std::ostream& msgInfo = msg(MSG::Level::INFO); + msgInfo << std::right; + if (m_isMC) msgInfo << std::fixed << std::setprecision(2); + + if (m_config->doTightEvents()) { + //channel name + msgInfo << " - " << m_name << " cutflow:\n"; + + //some headings + msgInfo << std::setw(7) << "" << + std::setw(30) << "cut" << + std::setw(15) << "events"; + + if (m_isMC) + msgInfo << std::setw(15) << "mc weights" << + std::setw(15) << "mc*pu weights" << + std::setw(15) << "lepton SF" << + std::setw(15) << "b-tag SF"; + + if (m_cutflowParticleLevel) { + msgInfo << std::setw(15) << "particle level"; + } + + if (m_cutflowParticleLevelMCWeights) { + msgInfo << std::setw(15) << "particle level mc"; + } - std::cout << "\n"; + if (m_cutflowUpgradeLevel) { + msgInfo << std::setw(15) << "upgrade level"; + } + + msgInfo << "\n"; - //cutflow table content - for (int i = 1; i <= m_cutflow->GetNbinsX(); ++i) { - std::cout << " " << std::setw(3) << i - << std::setw(30) << m_cutflow->GetXaxis()->GetBinLabel(i) - << std::setw(15) << m_cutflow->GetBinContent(i); + //cutflow table content + for (int i = 1; i <= m_cutflow->GetNbinsX(); ++i) { + msgInfo << " " << std::setw(3) << i + << std::setw(30) << m_cutflow->GetXaxis()->GetBinLabel(i) + << std::setw(15) << m_cutflow->GetBinContent(i); if (m_isMC) - std::cout << std::setw(15) << m_cutflowMCWeights->GetBinContent(i) - << std::setw(15) << m_cutflowMCPUWeights->GetBinContent(i) - << std::setw(15) << m_cutflowScaleFactors->GetBinContent(i) - << std::setw(15) << m_cutflowBScaleFactors->GetBinContent(i); - - if ( m_cutflowParticleLevel ){ - std::cout << std::setw(15) << m_cutflowParticleLevel->GetBinContent(i); - } - - if ( m_cutflowUpgradeLevel ){ - std::cout << std::setw(15) << m_cutflowUpgradeLevel->GetBinContent(i); + msgInfo << std::setw(15) << m_cutflowMCWeights->GetBinContent(i) + << std::setw(15) << m_cutflowMCPUWeights->GetBinContent(i) + << std::setw(15) << m_cutflowScaleFactors->GetBinContent(i) + << std::setw(15) << m_cutflowBScaleFactors->GetBinContent(i); + + if (m_cutflowParticleLevel) { + msgInfo << std::setw(15) << m_cutflowParticleLevel->GetBinContent(i); + } + + if (m_cutflowParticleLevelMCWeights) { + msgInfo << std::setw(15) << m_cutflowParticleLevelMCWeights->GetBinContent(i); + } + + if (m_cutflowUpgradeLevel) { + msgInfo << std::setw(15) << m_cutflowUpgradeLevel->GetBinContent(i); } - std::cout << "\n"; + msgInfo << "\n"; + } } - } - if (m_config->doLooseEvents()) { - //channel name - std::cout << " - " << m_name << " cutflow (Loose):\n"; + if (m_config->doLooseEvents()) { + //channel name + msgInfo << " - " << m_name << " cutflow (Loose):\n"; - //some headings - std::cout << std::setw(7) << "" << - std::setw(30) << "cut" << - std::setw(15) << "events"; + //some headings + msgInfo << std::setw(7) << "" << + std::setw(30) << "cut" << + std::setw(15) << "events"; - if (m_isMC) - std::cout << std::setw(15) << "mc weights" << + if (m_isMC) + msgInfo << std::setw(15) << "mc weights" << std::setw(15) << "mc*pu weights" << std::setw(15) << "lepton SF" << - std::setw(15) << "b-tag SF" ; + std::setw(15) << "b-tag SF"; - if( m_cutflowParticleLevel ) { - std::cout << std::setw(15) << "particle level"; - } + if (m_cutflowParticleLevel) { + msgInfo << std::setw(15) << "particle level"; + } - if( m_cutflowUpgradeLevel ) { - std::cout << std::setw(15) << "upgrade level"; - } + if (m_cutflowParticleLevelMCWeights) { + msgInfo << std::setw(15) << "particle level mc"; + } + if (m_cutflowUpgradeLevel) { + msgInfo << std::setw(15) << "upgrade level"; + } - std::cout << "\n"; - //cutflow table content - for (int i = 1; i <= m_cutflow_Loose->GetNbinsX(); ++i) { - std::cout << " " << std::setw(3) << i - << std::setw(30) << m_cutflow_Loose->GetXaxis()->GetBinLabel(i) - << std::setw(15) << m_cutflow_Loose->GetBinContent(i); + msgInfo << "\n"; + + //cutflow table content + for (int i = 1; i <= m_cutflow_Loose->GetNbinsX(); ++i) { + msgInfo << " " << std::setw(3) << i + << std::setw(30) << m_cutflow_Loose->GetXaxis()->GetBinLabel(i) + << std::setw(15) << m_cutflow_Loose->GetBinContent(i); if (m_isMC) - std::cout << std::setw(15) << m_cutflowMCWeights_Loose->GetBinContent(i) - << std::setw(15) << m_cutflowMCPUWeights_Loose->GetBinContent(i) - << std::setw(15) << m_cutflowScaleFactors_Loose->GetBinContent(i) - << std::setw(15) << m_cutflowBScaleFactors_Loose->GetBinContent(i); + msgInfo << std::setw(15) << m_cutflowMCWeights_Loose->GetBinContent(i) + << std::setw(15) << m_cutflowMCPUWeights_Loose->GetBinContent(i) + << std::setw(15) << m_cutflowScaleFactors_Loose->GetBinContent(i) + << std::setw(15) << m_cutflowBScaleFactors_Loose->GetBinContent(i); + + if (m_cutflowParticleLevel) { + msgInfo << std::setw(15) << m_cutflowParticleLevel->GetBinContent(i); + } - if ( m_cutflowParticleLevel ){ - std::cout << std::setw(15) << m_cutflowParticleLevel->GetBinContent(i); + if (m_cutflowParticleLevelMCWeights) { + msgInfo << std::setw(15) << m_cutflowParticleLevelMCWeights->GetBinContent(i); } - if ( m_cutflowUpgradeLevel ){ - std::cout << std::setw(15) << m_cutflowUpgradeLevel->GetBinContent(i); + if (m_cutflowUpgradeLevel) { + msgInfo << std::setw(15) << m_cutflowUpgradeLevel->GetBinContent(i); } - std::cout << "\n"; + msgInfo << "\n"; + } } + msgInfo << "\n"; } - std::cout << "\n"; -} -const std::string EventSelection::name() const { + const std::string EventSelection::name() const { return m_name; -} + } -std::vector<std::string> EventSelection::GetFakesMMConfigs() const { + std::vector<std::string> EventSelection::GetFakesMMConfigs() const { std::vector<std::string> configs; for (const auto& currentCutName : m_allCuts) { - if (currentCutName->name()!="FAKESMMCONFIGS") continue; + if (currentCutName->name() != "FAKESMMCONFIGS") continue; else { - FakesMMConfigs* conf = dynamic_cast<FakesMMConfigs*>(currentCutName.get()); - for (std::string s : conf->configurations()) - configs.push_back(s); + FakesMMConfigs* conf = dynamic_cast<FakesMMConfigs*>(currentCutName.get()); + for (std::string s : conf->configurations()) + configs.push_back(s); } } return configs; -} + } -void EventSelection::printCuts() { - std::cout << " - " << m_name << ":\n"; - if (!m_config->doLooseTreeOnly()) { + void EventSelection::printCuts() { + std::ostream& msgInfo = msg(MSG::Level::INFO); + msgInfo << "\n - " << m_name << ":\n"; + if (m_config->doTightEvents()) { for (int i = 1; i <= m_cutflow->GetNbinsX(); ++i) { - std::cout << " " << std::setw(3) << i - << std::setw(30) << m_cutflow->GetXaxis()->GetBinLabel(i) - << "\n"; + msgInfo << " " << std::setw(3) << i + << std::setw(30) << m_cutflow->GetXaxis()->GetBinLabel(i) + << "\n"; } - } - else if (m_config->doLooseEvents()) { + } else if (m_config->doLooseEvents()) { for (int i = 1; i <= m_cutflow_Loose->GetNbinsX(); ++i) { - std::cout << " " << std::setw(3) << i - << std::setw(30) << m_cutflow_Loose->GetXaxis()->GetBinLabel(i) - << "\n"; + msgInfo << " " << std::setw(3) << i + << std::setw(30) << m_cutflow_Loose->GetXaxis()->GetBinLabel(i) + << "\n"; } } - - std::cout << "\n"; -} - + msgInfo << std::endl; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSelectionManager.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSelectionManager.cxx index f7168b5489d5..c86529a2033d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSelectionManager.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSelectionManager.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopAnalysis/EventSelectionManager.h" @@ -23,145 +23,151 @@ #include "TopParticleLevel/ParticleLevelEvent.h" -namespace top { +#include "TopAnalysis/MsgCategory.h" +// use ATH_MSG macros defined in the namespace TopAnalysis +using namespace TopAnalysis; -EventSelectionManager::EventSelectionManager(const std::vector<SelectionConfigurationData>& selectionConfigData, TFile* outputFile, const std::string& toolLoaderNames, std::shared_ptr<top::TopConfig> config, EL::Worker* wk) { +namespace top { + EventSelectionManager::EventSelectionManager(const std::vector<SelectionConfigurationData>& selectionConfigData, + TFile* outputFile, const std::string& toolLoaderNames, + std::shared_ptr<top::TopConfig> config, EL::Worker* wk) { std::vector<std::string> tokens; std::stringstream ss(toolLoaderNames); std::string item; char delim = ' '; while (std::getline(ss, item, delim)) - tokens.push_back(item); + tokens.push_back(item); - std::vector<std::unique_ptr<top::ToolLoaderBase>> toolLoaders; + std::vector<std::unique_ptr<top::ToolLoaderBase> > toolLoaders; for (const auto& toolLoaderName : tokens) { - //remove the lib and add namespace and Loader to the class name - std::string className = "top::" + toolLoaderName.substr(3) + "Loader"; - - std::cout << "Attempting to load Tools from this class: " << className << "\n"; - TClass* c = ::TClass::GetClass(className.c_str()); - - //okay, so that failed - //maybe the user didn't put it in the top namespace - try again without top::? - if (c == nullptr) { - className = toolLoaderName.substr(3) + "Loader"; - std::cout << "Attempting to load Tools from this class: " << className << "\n"; - c = ::TClass::GetClass(className.c_str()); - } - - //okay, so that worked! - if (c != nullptr) { - std::cout << " Success part 1 of 2" << "\n"; - top::ToolLoaderBase* bc = static_cast<top::ToolLoaderBase*> (c->New()); - - if (bc) { - std::cout << " Success part 2 of 2" << "\n"; - toolLoaders.push_back(std::unique_ptr<top::ToolLoaderBase>(bc)); - } else - std::cout << " Failure converting to ToolLoaderBase\n"; - } else - std::cout << " Class " << className << " in library " << toolLoaderName << " not found - this is only a problem if you wrote one in your library\n"; + //remove the lib and add namespace and Loader to the class name + std::string className = "top::" + toolLoaderName.substr(3) + "Loader"; + + ATH_MSG_INFO("Attempting to load Tools from this class: " << className); + TClass* c = ::TClass::GetClass(className.c_str()); + + //okay, so that failed + //maybe the user didn't put it in the top namespace - try again without top::? + if (c == nullptr) { + className = toolLoaderName.substr(3) + "Loader"; + ATH_MSG_INFO("Attempting to load Tools from this class: " << className); + c = ::TClass::GetClass(className.c_str()); + } + + //okay, so that worked! + if (c != nullptr) { + ATH_MSG_INFO(" Success part 1 of 2"); + top::ToolLoaderBase* bc = static_cast<top::ToolLoaderBase*> (c->New()); + + if (bc) { + ATH_MSG_INFO(" Success part 2 of 2"); + toolLoaders.push_back(std::unique_ptr<top::ToolLoaderBase>(bc)); + } else ATH_MSG_ERROR(" Failure converting to ToolLoaderBase"); + } else ATH_MSG_WARNING(" Class " << className << " in library " << toolLoaderName << + " not found - this is only a problem if you wrote one in your library"); } - std::cout << "\nTelling you how I'm configured, before I do anything:\n"; + ATH_MSG_INFO("Telling you how I'm configured, before I do anything:"); for (const auto& currentConfig : selectionConfigData) - m_selections.emplace_back(currentConfig.m_name, currentConfig.m_cutnames, outputFile, toolLoaders,config,wk); -} + m_selections.emplace_back(currentConfig.m_name, currentConfig.m_cutnames, outputFile, toolLoaders, config, wk); + } -EventSelectionManager::EventSelectionManager(EventSelectionManager&& other) : + EventSelectionManager::EventSelectionManager(EventSelectionManager&& other) : m_selections(std::move(other.m_selections)) { -} - -void EventSelectionManager::countInitial(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) -{ - for (const auto& currentSelection : m_selections) - currentSelection.countInitial(mcEventWeight,pileupWeight,zvtxWeight); -} + } -void EventSelectionManager::countGRL(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) -{ - for (const auto& currentSelection : m_selections) - currentSelection.countGRL(mcEventWeight,pileupWeight,zvtxWeight); -} + void EventSelectionManager::countInitial(const float mcEventWeight, const float pileupWeight, + const float zvtxWeight) { + for (const auto& currentSelection : m_selections) + currentSelection.countInitial(mcEventWeight, pileupWeight, zvtxWeight); + } -void EventSelectionManager::countGoodCalo(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) -{ - for (const auto& currentSelection : m_selections) - currentSelection.countGoodCalo(mcEventWeight,pileupWeight,zvtxWeight); -} + void EventSelectionManager::countGRL(const float mcEventWeight, const float pileupWeight, const float zvtxWeight) { + for (const auto& currentSelection : m_selections) + currentSelection.countGRL(mcEventWeight, pileupWeight, zvtxWeight); + } -void EventSelectionManager::countPrimaryVertex(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) -{ - for (const auto& currentSelection : m_selections) - currentSelection.countPrimaryVertex(mcEventWeight,pileupWeight,zvtxWeight); -} + void EventSelectionManager::countGoodCalo(const float mcEventWeight, const float pileupWeight, + const float zvtxWeight) { + for (const auto& currentSelection : m_selections) + currentSelection.countGoodCalo(mcEventWeight, pileupWeight, zvtxWeight); + } -bool EventSelectionManager::apply(top::Event& event,const xAOD::SystematicEvent& currentSystematic) { + void EventSelectionManager::countPrimaryVertex(const float mcEventWeight, const float pileupWeight, + const float zvtxWeight) { + for (const auto& currentSelection : m_selections) + currentSelection.countPrimaryVertex(mcEventWeight, pileupWeight, zvtxWeight); + } + + bool EventSelectionManager::apply(top::Event& event, const xAOD::SystematicEvent& currentSystematic) { bool save(false); + for (const auto& currentSelection : m_selections) { - const bool passedThisSelection = currentSelection.apply(event); + const bool passedThisSelection = currentSelection.apply(event); - //save result as new branch (int) - event.m_info->auxdecor<int>(currentSelection.name()) = passedThisSelection; - //save result as decoration - currentSystematic.auxdecor<int>(currentSelection.name()) = passedThisSelection ? 1 : 0; + //save result as new branch (int) + event.m_info->auxdecor<int>(currentSelection.name()) = passedThisSelection; + //save result as decoration + currentSystematic.auxdecor<int>(currentSelection.name()) = passedThisSelection ? 1 : 0; - //Did any of the selections with SAVE specified pass for this event (if so we might want to keep the event) - save |= (passedThisSelection && currentSelection.ToBeSaved()); + //Did any of the selections with SAVE specified pass for this event (if so we might want to keep the event) + save |= (passedThisSelection && currentSelection.ToBeSaved()); } return save; -} + } -bool EventSelectionManager::applyParticleLevel(const top::ParticleLevelEvent& plEvent) { + bool EventSelectionManager::applyParticleLevel(const top::ParticleLevelEvent& plEvent) { bool save(false); + for (const auto& currentSelection : m_selections) { - const bool passedThisSelection = currentSelection.applyParticleLevel( plEvent ); + const bool passedThisSelection = currentSelection.applyParticleLevel(plEvent); - //save result as new branch (int) - plEvent.m_selectionDecisions[ currentSelection.name() ] = passedThisSelection; + //save result as new branch (int) + plEvent.m_selectionDecisions[ currentSelection.name() ] = passedThisSelection; - //Did any of the selections with SAVE specified pass for this event (if so we might want to keep the event) - save |= (passedThisSelection && currentSelection.ToBeSaved()); + //Did any of the selections with SAVE specified pass for this event (if so we might want to keep the event) + save |= (passedThisSelection && currentSelection.ToBeSaved()); } return save; -} + } -bool EventSelectionManager::applyUpgradeLevel(const top::ParticleLevelEvent& upgradeEvent) { + bool EventSelectionManager::applyUpgradeLevel(const top::ParticleLevelEvent& upgradeEvent) { bool save(false); + for (const auto& currentSelection : m_selections) { - const bool passedThisSelection = currentSelection.applyUpgradeLevel( upgradeEvent ); + const bool passedThisSelection = currentSelection.applyUpgradeLevel(upgradeEvent); - //save result as new branch (int) - upgradeEvent.m_selectionDecisions[ currentSelection.name() ] = passedThisSelection; + //save result as new branch (int) + upgradeEvent.m_selectionDecisions[ currentSelection.name() ] = passedThisSelection; - //Did any of the selections with SAVE specified pass for this event (if so we might want to keep the event) - save |= (passedThisSelection && currentSelection.ToBeSaved()); + //Did any of the selections with SAVE specified pass for this event (if so we might want to keep the event) + save |= (passedThisSelection && currentSelection.ToBeSaved()); } return save; -} + } -void EventSelectionManager::finalise() { - std::cout << "Final yields:\n"; + void EventSelectionManager::finalise() { + ATH_MSG_INFO("Final yields:"); for (const auto& currentSelection : m_selections) - currentSelection.finalise(); -} + currentSelection.finalise(); + } -void EventSelectionManager::addExtraBranches(std::vector<std::string>& extraBranchList) { + void EventSelectionManager::addExtraBranches(std::vector<std::string>& extraBranchList) { for (const auto& currentSelection : m_selections) - extraBranchList.push_back(currentSelection.name()); -} + extraBranchList.push_back(currentSelection.name()); + } -std::vector<std::string> EventSelectionManager::GetFakesMMConfigs(std::string selection) const { - for (const auto& currentSelection : m_selections) - if (currentSelection.name() == selection) return currentSelection.GetFakesMMConfigs(); - std::cout << "WARNING: Attempt to retrieve the FakesMMConfigs for non-existing selection " << selection << std::endl; - std::cout << " This is nonense - returning empty list" << std::endl; - std::vector<std::string> empty; - return empty; -} + std::vector<std::string> EventSelectionManager::GetFakesMMConfigs(std::string selection) const { + for (const auto& currentSelection : m_selections) + if (currentSelection.name() == selection) return currentSelection.GetFakesMMConfigs(); + ATH_MSG_WARNING("Attempt to retrieve the FakesMMConfigs for non-existing selection " << selection + << "\n This is nonense - returning empty list"); + std::vector<std::string> empty; + return empty; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/LinkDef.h index 656be7428b15..3533b95ab492 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/LinkDef.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/LinkDef.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #include "TopAnalysis/ObjectLoaderStandardCuts.h" diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/MsgCategory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/MsgCategory.cxx new file mode 100644 index 000000000000..a81b4d6b4d42 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/MsgCategory.cxx @@ -0,0 +1,6 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#include "TopAnalysis/MsgCategory.h" + +ANA_MSG_SOURCE(TopAnalysis, "TopAnalysis") diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/ObjectLoaderStandardCuts.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/ObjectLoaderStandardCuts.cxx index a8797c37c349..facd9d757320 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/ObjectLoaderStandardCuts.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/ObjectLoaderStandardCuts.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopAnalysis/ObjectLoaderStandardCuts.h" #include "TopEvent/EventTools.h" @@ -9,81 +9,102 @@ #include "TopObjectSelectionTools/TopObjectSelection.h" #include "TopObjectSelectionTools/ElectronLikelihoodMC15.h" #include "TopObjectSelectionTools/ElectronCutBasedMC15.h" +//#include "TopObjectSelectionTools/FwdElectronMC15.h" #include "TopObjectSelectionTools/IsolationTools.h" #include "TopObjectSelectionTools/MuonMC15.h" +#include "TopObjectSelectionTools/SoftMuonMC15.h" #include "TopObjectSelectionTools/AntiMuonMC15.h" #include "TopObjectSelectionTools/TauMC15.h" #include "TopObjectSelectionTools/JetMC15.h" #include "TopObjectSelectionTools/TrackJetMC15.h" -#include "TopObjectSelectionTools/PhotonMC15.h" +#include "TopObjectSelectionTools/JetGhostTrackSelection.h" +#include "TopObjectSelectionTools/TrackSelection.h" #include "TopObjectSelectionTools/OverlapRemovalASG.h" +// R21 specific +#include "TopObjectSelectionTools/PhotonMC16.h" -namespace top { +#include "TopAnalysis/MsgCategory.h" +// use ATH_MSG macros defined in the namespace TopAnalysis +using namespace TopAnalysis; - top::TopObjectSelection* ObjectLoaderStandardCuts::init(std::shared_ptr<top::TopConfig> topConfig) - { +namespace top { + top::TopObjectSelection* ObjectLoaderStandardCuts::init(std::shared_ptr<top::TopConfig> topConfig) { top::TopObjectSelection* objectSelection = new top::TopObjectSelection(topConfig->objectSelectionName()); - top::check(objectSelection->setProperty( "config" , topConfig ) , "Failed to setProperty for top::TopObjectSelection" ); - top::check(objectSelection->initialize() , "Failed to initialize top::TopObjectSelection" ); + top::check(objectSelection->setProperty("config", topConfig), "Failed to setProperty for top::TopObjectSelection"); + top::check(objectSelection->initialize(), "Failed to initialize top::TopObjectSelection"); // Debug messages? // objectSelection->msg().setLevel(MSG::DEBUG); ///-- Photons --// - if(topConfig->usePhotons()) { - objectSelection->photonSelection(new top::PhotonMC15(topConfig->photonPtcut(), - topConfig->photonEtacut(), - topConfig->photonIdentification(), - topConfig->photonIdentificationLoose(), - new top::StandardIsolation( - topConfig->photonIsolation(), - topConfig->photonIsolationLoose() )) ); + if (topConfig->usePhotons()) { + ATH_MSG_INFO("top::ObjectLoaderStandardCuts::init - Using new photon object for Release 21 - PhotonMC16"); + objectSelection->photonSelection(new top::PhotonMC16(topConfig->photonPtcut(), + topConfig->photonEtacut(), + topConfig->photonIdentification(), + topConfig->photonIdentificationLoose(), + new top::StandardIsolation(topConfig->photonIsolation(), + topConfig->photonIsolationLoose()), + topConfig->recomputeCPvars())); } ///-- Electrons --/// if (topConfig->useElectrons()) { - if (topConfig->electronID().find("LH") == std::string::npos && topConfig->electronIDLoose().find("LH") == std::string::npos) { - //both the tight and loose user settings do not contain LH -> cut based + if (topConfig->electronID().find("LH") == std::string::npos && + topConfig->electronIDLoose().find("LH") == std::string::npos) { + //both the tight and loose user settings do not contain LH -> cut based objectSelection->electronSelection(new top::ElectronCutBasedMC15(topConfig->electronPtcut(), topConfig->electronVetoLArCrack(), topConfig->electronID(), topConfig->electronIDLoose(), new top::StandardIsolation( - topConfig->electronIsolation() , - topConfig->electronIsolationLoose() )) ); - - } else if (topConfig->electronID().find("LH") != std::string::npos && topConfig->electronIDLoose().find("LH") != std::string::npos) { - //user wants likelihood electrons - objectSelection->electronSelection(new top::ElectronLikelihoodMC15(topConfig->isPrimaryxAOD(), - topConfig->electronPtcut(), - topConfig->electronVetoLArCrack(), - topConfig->electronID(), - topConfig->electronIDLoose(), - new top::StandardIsolation( - topConfig->electronIsolation() , - topConfig->electronIsolationLoose() ), - topConfig->applyTTVACut() - ) ); - + topConfig->electronIsolation(), + topConfig->electronIsolationLoose()))); + } else if (topConfig->electronID().find("LH") != std::string::npos && + topConfig->electronIDLoose().find("LH") != std::string::npos) { + //user wants likelihood electrons + objectSelection->electronSelection(new top::ElectronLikelihoodMC15(topConfig->isPrimaryxAOD(), + topConfig->electronPtcut(), + topConfig->electronVetoLArCrack(), + topConfig->electronID(), + topConfig->electronIDLoose(), + new top::StandardIsolation( + topConfig->electronIsolation(), + topConfig->electronIsolationLoose()), + topConfig->applyTTVACut(), + topConfig->useElectronChargeIDSelection() + )); } else { - std::cout << "\nHo hum\n"; - std::cout << "Not sure it makes sense to use a mix of LH and cut-based electrons for the tight/loose definitions\n"; - std::cout << "Tight electron definition is " << topConfig->electronID() << "\n"; - std::cout << "Loose electron definition is " << topConfig->electronIDLoose() << "\n"; - std::cout << "If it does make sense, feel free to fix this\n"; - exit(1); + ATH_MSG_ERROR("Not sure it makes sense to use a mix of LH and cut-based electrons for the tight/loose definitions\n" + << "Tight electron definition is " << topConfig->electronID() << "\n" + << "Loose electron definition is " << topConfig->electronIDLoose() << "\n" + << "If it does make sense, feel free to fix this"); + throw std::runtime_error("Mixing LH and cut-based electron definitions for tight/loose"); } } + ///-- Fwd Electrons --/// + //if (topConfig->useFwdElectrons()) { + // objectSelection->fwdElectronSelection(new top::FwdElectronMC15(topConfig->fwdElectronPtcut(), + // topConfig->fwdElectronMinEtacut(), + // topConfig->fwdElectronMaxEtacut(), topConfig)); + //} ///-- Muons --/// if (topConfig->useMuons()) { + if (topConfig->useAntiMuons()) objectSelection->muonSelection(new top::AntiMuonMC15(topConfig->muonPtcut(), + new top::StandardIsolation( + topConfig->muonIsolation(), + topConfig-> + muonIsolationLoose()))); + else objectSelection->muonSelection(new top::MuonMC15(topConfig->muonPtcut(), + new top::StandardIsolation(topConfig->muonIsolation(), + topConfig->muonIsolationLoose()), + topConfig->applyTTVACut())); + } - - if (topConfig->useAntiMuons()) - objectSelection -> muonSelection(new top::AntiMuonMC15(topConfig->muonPtcut(), new top::StandardIsolation(topConfig->muonIsolation(), topConfig->muonIsolationLoose()) )); - else - objectSelection -> muonSelection(new top::MuonMC15(topConfig->muonPtcut(), new top::StandardIsolation(topConfig->muonIsolation(), topConfig->muonIsolationLoose()), topConfig->applyTTVACut()) ); - + ///-- Soft Muons --/// + if (topConfig->useSoftMuons()) { + objectSelection->softmuonSelection(new top::SoftMuonMC15(topConfig->softmuonPtcut())); } @@ -94,24 +115,39 @@ namespace top { ///-- Jets --/// if (topConfig->useJets()) { - objectSelection -> jetSelection(new top::JetMC15(topConfig->jetPtcut(), topConfig->jetEtacut(), topConfig->fwdJetAndMET())); + objectSelection->jetSelection(new top::JetMC15(topConfig->jetPtcut(), topConfig->jetEtacut())); } ///-- Large R Jets --/// if (topConfig->useLargeRJets()) {// not doing JVT cut for large-R jets - objectSelection -> largeJetSelection(new top::JetMC15(topConfig->largeRJetPtcut(), topConfig->largeRJetEtacut(), false)); + objectSelection->largeJetSelection(new top::JetMC15(topConfig->largeRJetPtcut(), topConfig->largeRJetEtacut(), + false)); } ///-- Track Jets --/// if (topConfig->useTrackJets()) { - objectSelection -> trackJetSelection(new top::TrackJetMC15(topConfig->trackJetPtcut(), topConfig->trackJetEtacut())); + objectSelection->trackJetSelection(new top::TrackJetMC15(topConfig->trackJetPtcut(), + topConfig->trackJetEtacut())); + } + + ///-- Ghost Track Jets --/// + if (topConfig->useJetGhostTrack()) { + objectSelection->jetGhostTrackSelection(new top::JetGhostTrackSelection(topConfig->ghostTrackspT(), + 2.5,topConfig->ghostTracksVertexAssociation(),topConfig->jetPtGhostTracks(), 2.5)); + } + + ///-- Tracks --/// + if (topConfig->useTracks()) { + objectSelection->trackSelection(new top::TrackSelection(topConfig->trackPtcut(), topConfig->trackEtacut())); } ///-- Overlap removal --/// /// single parameter: boolean to do OR with large-R jets - objectSelection->overlapRemovalPostSelection(new top::OverlapRemovalASG( (topConfig->doLargeJetOverlapRemoval() && topConfig->useLargeRJets())) ); + if (!topConfig->isTruthDxAOD()) { + objectSelection->overlapRemovalPostSelection(new top::OverlapRemovalASG((topConfig->doLargeJetOverlapRemoval() && + topConfig->useLargeRJets()))); + } return objectSelection; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/Tools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/Tools.cxx index 6c1de11684c0..d8942ca71a37 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/Tools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/Tools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopAnalysis/Tools.h" @@ -26,147 +26,237 @@ #include "TROOT.h" #include "xAODRootAccess/Init.h" +//#include "xAODRootAccess/LoadDictionaries.h" #include "PATInterfaces/SystematicCode.h" #include "PATInterfaces/CorrectionCode.h" +#include "AsgTools/AsgMetadataTool.h" +#include "xAODTruth/TruthMetaData.h" +#include "xAODTruth/TruthMetaDataContainer.h" + #ifndef ROOTCORE #include "AthAnalysisBaseComps/AthAnalysisHelper.h" #endif -namespace top { +#include "TopAnalysis/MsgCategory.h" +using namespace TopAnalysis; -void xAODInit(bool failOnUnchecked) { +namespace top { + void xAODInit(bool failOnUnchecked) { if (!xAOD::Init()) { - std::cout << "Failed xAOD::Init - no idea what to do, exiting\n"; - exit(1); + throw std::runtime_error("Failed xAOD::Init - no idea what to do, exiting"); } + //if (xAOD::LoadDictionaries().isFailure()) { + // ATH_MSG_WARNING("Failiure in xAOD::LoadDictionaries(). The job will " + // "likely not run correctly."); + //} //fail on unchecked error codes if (failOnUnchecked) { - xAOD::TReturnCode::enableFailure(); - CP::SystematicCode::enableFailure(); - CP::CorrectionCode::enableFailure(); - //StatusCode::enableFailure(); + xAOD::TReturnCode::enableFailure(); + CP::SystematicCode::enableFailure(); + CP::CorrectionCode::enableFailure(); + //StatusCode::enableFailure(); } -} + } -bool isFilePrimaryxAOD(TFile* inputFile) { + bool isFilePrimaryxAOD(TFile* inputFile) { TTree* metaData = dynamic_cast<TTree*> (inputFile->Get("MetaData")); if (metaData) { - metaData->LoadTree(0); - - TObjArray* ar = metaData->GetListOfBranches(); - for (int i = 0; i < ar->GetEntries(); ++i) { - TBranch* b = (TBranch*) ar->At(i); - std::string name = std::string(b->GetName()); - // std::cout << name << std::endl; - if (name == "StreamAOD") - return true; - } + metaData->LoadTree(0); + + TObjArray* ar = metaData->GetListOfBranches(); + for (int i = 0; i < ar->GetEntries(); ++i) { + TBranch* b = (TBranch*) ar->At(i); + std::string name = std::string(b->GetName()); + if (name == "StreamAOD") return true; + } } else { - std::cout << "isFilePrimaryxAOD says MetaData tree missing from input file.\n Weird" << std::endl; - exit(1); + throw std::runtime_error("Tools::isFilePrimaryxAOD: MetaData tree missing from input file."); } return false; -} + } -bool isFileSimulation(TFile* inputFile, const std::string& eventInfoName) { + bool isFileSimulation(TFile* inputFile, const std::string& eventInfoName) { xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); top::check(xaodEvent.readFrom(inputFile), "Tools::isFileSimulation Failed to read file in"); xaodEvent.getEntry(0); const xAOD::EventInfo* eventInfo(0); - top::check(xaodEvent.retrieve(eventInfo, eventInfoName) , "Tools::isFileSimulation Failed to get " + eventInfoName); - return eventInfo->eventType(xAOD::EventInfo::IS_SIMULATION); -} + top::check(xaodEvent.retrieve(eventInfo, eventInfoName), "Tools::isFileSimulation Failed to get " + eventInfoName); -bool isTruthDxAOD(TFile* inputFile) { - TTree* metaData = dynamic_cast<TTree*> (inputFile->Get("MetaData")); - - if (metaData) { - metaData->LoadTree(0); - - TObjArray* ar = metaData->GetListOfBranches(); - for (int i = 0; i < ar->GetEntries(); ++i) { - TBranch* b = (TBranch*) ar->At(i); - std::string name = std::string(b->GetName()); - // std::cout << name << std::endl; - if (name.find("DAOD_TRUTH") != std::string::npos) - return true; - } - } else { - throw std::runtime_error("isTruthDxAOD says MetaData tree" - " missing from input file.\n Weird"); + return eventInfo->eventType(xAOD::EventInfo::IS_SIMULATION); } - - return false; -} + size_t MCweightsSize(TFile* inputFile, const std::string& eventInfoName) { + xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); + top::check(xaodEvent.readFrom(inputFile), "Tools::MCweightsSize Failed to read file in"); -unsigned int getDSID(TFile* inputFile, const std::string& eventInfoName){ + xaodEvent.getEntry(0); + const xAOD::EventInfo* eventInfo(0); + top::check(xaodEvent.retrieve(eventInfo, eventInfoName), "Tools::isFileSimulation Failed to get " + eventInfoName); - xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); - top::check(xaodEvent.readFrom(inputFile), "Tools::isFileSimulation Failed to read file in"); - - xaodEvent.getEntry(0); - const xAOD::EventInfo* eventInfo(0); - top::check(xaodEvent.retrieve(eventInfo, eventInfoName) , "Tools::isFileSimulation Failed to get " + eventInfoName); - - return eventInfo-> mcChannelNumber(); + return eventInfo->mcEventWeights().size(); + } -} + bool isTruthDxAOD(TFile* inputFile) { + TTree* metaData = dynamic_cast<TTree*> (inputFile->Get("MetaData")); + if (metaData) { + metaData->LoadTree(0); + + TObjArray* ar = metaData->GetListOfBranches(); + for (int i = 0; i < ar->GetEntries(); ++i) { + TBranch* b = (TBranch*) ar->At(i); + std::string name = std::string(b->GetName()); + if (name.find("DAOD_TRUTH") != std::string::npos) return true; + } + } else { + throw std::runtime_error("isTruthDxAOD says MetaData tree" + " missing from input file.\n Weird"); + } -bool isFileFastSim(TFile* /*inputFile*/) { + return false; + } - - return false; - -} + unsigned int getDSID(TFile* inputFile, const std::string& eventInfoName) { + xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); + top::check(xaodEvent.readFrom(inputFile), "Tools::isFileSimulation Failed to read file in"); + xaodEvent.getEntry(0); + const xAOD::EventInfo* eventInfo(0); + top::check(xaodEvent.retrieve(eventInfo, eventInfoName), "Tools::isFileSimulation Failed to get " + eventInfoName); -std::string getDerivationStream(TFile* inputFile){ + return eventInfo->mcChannelNumber(); + } - TTree* metaData = dynamic_cast<TTree*> (inputFile->Get("MetaData")); + bool isFileFastSim(TFile* /*inputFile*/) { + return false; + } - if (metaData) { - metaData->LoadTree(0); + std::string getDerivationStream(TFile* inputFile) { + TTree* metaData = dynamic_cast<TTree*> (inputFile->Get("MetaData")); - TObjArray* ar = metaData->GetListOfBranches(); - for (int i = 0; i < ar->GetEntries(); ++i) { - TBranch* b = (TBranch*) ar->At(i); - std::string name = std::string(b->GetName()); - // Find a variable name with Stream, then split off from DAOD - // If we only need TOPQX, we just find "_", add 1 and substring from there instead - if (name.find("Stream") != std::string::npos){ - auto cursor = name.find("_"); - std::string stream = name.substr(cursor+1); - return stream; - } + if (metaData) { + metaData->LoadTree(0); + + TObjArray* ar = metaData->GetListOfBranches(); + for (int i = 0; i < ar->GetEntries(); ++i) { + TBranch* b = (TBranch*) ar->At(i); + std::string name = std::string(b->GetName()); + // Find a variable name with Stream, then split off from DAOD + // If we only need TOPQX, we just find "_", add 1 and substring from there instead + if (name.find("Stream") != std::string::npos) { + auto cursor = name.find("_"); + std::string stream = name.substr(cursor + 1); + return stream; + } + } + } else { + throw std::runtime_error("getDerivationStream says MetaData tree" + " missing from input file.\n Weird"); } - } - else { - throw std::runtime_error("getDerivationStream says MetaData tree" - " missing from input file.\n Weird"); + + // If we don't already return, something unexpected has happened and we need to fix it! + throw std::runtime_error("Cannot determine the derivation stream. Please report."); } - // If we don't already return, something unexpected has happened and we need to fix it! - throw std::runtime_error("Cannot determine the derivation stream. Please report."); + void parseCutBookkeepers(const xAOD::CutBookkeeperContainer *cutBookKeepers, + std::vector<std::string> &names, std::vector<float>& sumW, const bool isHLLHC) { + std::vector<int> maxCycle; + for (const xAOD::CutBookkeeper *cbk : *cutBookKeepers) { + // skip RDO and ESD numbers, which are nonsense; and + // skip the derivation number, which is the one after skimming + // we want the primary xAOD numbers + if ((cbk->inputStream() != "StreamAOD") && !(isHLLHC && cbk->inputStream() == "StreamDAOD_TRUTH1")) + continue; + // only accept "AllExecutedEvents" bookkeeper (0th MC weight) + // or "AllExecutedEvents_NonNominalMCWeight_XYZ" where XYZ is the MC weight index + if (!((cbk->name() == "AllExecutedEvents") + || (cbk->name().find("AllExecutedEvents_NonNominalMCWeight_") != std::string::npos))) + continue; + const std::string name = cbk->name(); + auto pos_name = std::find(names.begin(), names.end(), name); + // is it a previously unencountered bookkeeper? If yes append its name to the vector of names + // if not no need, but we must check the corresponding entry for the sum of weights exist + if (pos_name == names.end()) { + names.push_back(name); + maxCycle.push_back(cbk->cycle()); + sumW.push_back(cbk->sumOfEventWeights()); + } else if (cbk->cycle() > maxCycle.at(pos_name - names.begin())) { + maxCycle.at(pos_name - names.begin()) = cbk->cycle(); + sumW.at(pos_name - names.begin()) = cbk->sumOfEventWeights(); + } else { + continue; + } + } + } -} - + ULong64_t getRawEventsBookkeeper(const xAOD::CutBookkeeperContainer *cutBookKeepers, const bool isHLLHC) { + int maxCycle = -1; + ULong64_t rawEntries = 0; + // search for "AllExecutedEvents" bookkeeper -- this one should always exist + for (const xAOD::CutBookkeeper *cbk : *cutBookKeepers) { + if ((cbk->inputStream() != "StreamAOD") && !(isHLLHC && cbk->inputStream() == "StreamDAOD_TRUTH1")) + continue; + if (cbk->name() != "AllExecutedEvents") + continue; + if (cbk->cycle() > maxCycle) { + rawEntries = cbk->nAcceptedEvents(); + maxCycle = cbk->cycle(); + } + } + return rawEntries; + } -xAOD::TEvent::EAuxMode guessAccessMode(const std::string& filename, const std::string& electronCollectionName) { + void renameCutBookkeepers(std::vector<std::string>& bookkeeper_names, + const std::vector<std::string>& pmg_weight_names) { + + // prefix in the bookkeeper names to remove + static const std::string name_prefix = "AllExecutedEvents_NonNominalMCWeight_"; + + // check if we have more than one MC generator weight, in that case we have to do the renaming + if (pmg_weight_names.size() > 1) { + if (bookkeeper_names.size() != pmg_weight_names.size()) { + // The number of AllExecutedEvents_ bookkeepers does not match the number of weights retrieved by PMGTool + // we cannot match the bookkeepers to weights by indices in this case + throw std::runtime_error("ERROR: The number of CutBookkeepers does not match the number of MC generator weights in metadata! Cannot match nominal MC weight to nominal sum of weights!"); + } + + // rename the bookkeepers based on the weight names from PMGTool + // this names are then also written into the sumWeights TTree in output files + for (std::string &name : bookkeeper_names) { + if (name == "AllExecutedEvents") { + name = pmg_weight_names.at(0); + } else { + // erase "AllExecutedEvents_NonNominalMCWeight_" prefix + int index = std::stoi(name.erase(0, name_prefix.size())); + name = pmg_weight_names.at(index); + } + } + } else { + // expect only one MC weight in this sample, hence only one AllExecutedEvents* bookeeeper + if (bookkeeper_names.size() == 1) { + bookkeeper_names[0] = "nominal"; + } else { + ATH_MSG_INFO("WARNING: PMGTruthWeightTool reports no extra MC generator weight variations, " + << "but this sample does not have exactly one AllExecutedEvents* bookkeeper!\n" + << "Expect trouble, because this means we can't guarantee that proper CutBookkeeper " + << "is used for the sum of weights!"); + } + } + } + xAOD::TEvent::EAuxMode guessAccessMode(const std::string& filename, const std::string& electronCollectionName) { //there must be a better way than this std::unique_ptr<TFile> inputFile(TFile::Open(filename.c_str())); xAOD::TEvent xaodEvent(xAOD::TEvent::kBranchAccess); - top::check( xaodEvent.readFrom(inputFile.get()) , "Failed to guessAccessMode" ); + top::check(xaodEvent.readFrom(inputFile.get()), "Failed to guessAccessMode"); //if we're unlucky and none of the events have electrons we can't //tell which mode we need -> use ClassAccess @@ -174,128 +264,116 @@ xAOD::TEvent::EAuxMode guessAccessMode(const std::string& filename, const std::s xAOD::TEvent::EAuxMode mode = xAOD::TEvent::kBranchAccess; if (electronCollectionName != "None") { - //look at the first n events - unsigned int entries = xaodEvent.getEntries(); - - for (unsigned int i = 0; i < entries; ++i) { - xaodEvent.getEntry(i); - - const xAOD::ElectronContainer* electrons(0); - top::check( xaodEvent.retrieve(electrons, electronCollectionName) , "Failed to guessAccessMode" ); - - try { - //loading the electron pt only works for class access for the first - //round of xAODs made for DC14 8 TeV - //class access doesn't let us make out mini-xAOD super small though - - //branch access is available for the xAOD->xAOD reprocessing, - //derivations and 13 TeV DC14 MC samples - if (!electrons->empty()) { - fallback = false; - electrons->at(0)->pt(); - break; - } - } catch(...) { - mode = xAOD::TEvent::kClassAccess; - break; - } + //look at the first n events + unsigned int entries = xaodEvent.getEntries(); + + for (unsigned int i = 0; i < entries; ++i) { + xaodEvent.getEntry(i); + + const xAOD::ElectronContainer* electrons(0); + top::check(xaodEvent.retrieve(electrons, electronCollectionName), "Failed to guessAccessMode"); + + try { + //loading the electron pt only works for class access for the first + //round of xAODs made for DC14 8 TeV + //class access doesn't let us make out mini-xAOD super small though + + //branch access is available for the xAOD->xAOD reprocessing, + //derivations and 13 TeV DC14 MC samples + if (!electrons->empty()) { + fallback = false; + electrons->at(0)->pt(); + break; + } + } catch (...) { + mode = xAOD::TEvent::kClassAccess; + break; } + } } if (fallback) { - std::cout << "Falling back to kClassAccess" << std::endl; - mode = xAOD::TEvent::kClassAccess; + ATH_MSG_WARNING("Falling back to kClassAccess"); + mode = xAOD::TEvent::kClassAccess; } //useful message if (mode == xAOD::TEvent::kClassAccess) - std::cout << "guessAccessMode: Using kClassAccess\n"; + ATH_MSG_INFO("guessAccessMode: Using kClassAccess"); else if (mode == xAOD::TEvent::kBranchAccess) - std::cout << "guessAccessMode: Using kBranchAccess\n"; + ATH_MSG_INFO("guessAccessMode: Using kBranchAccess"); return mode; -} + } -std::vector<std::string> loadCuts(const std::string& filename) { + std::vector<std::string> loadCuts(const std::string& filename) { std::vector<std::string> v; std::fstream in(filename.c_str()); if (!in.is_open()) { - std::cout << "Problem opening " << filename << "\n"; - exit(1); + throw std::runtime_error("Problem opening " + filename); } std::string str; while (std::getline(in, str)) { - std::string newstring(str); + std::string newstring(str); - if (str.find("#") != std::string::npos) - newstring = str.substr(0, str.find("#")); + if (str.find("#") != std::string::npos) newstring = str.substr(0, str.find("#")); - //leading and trailing white space removal - while (std::isspace(*newstring.begin())) - newstring.erase(newstring.begin()); + //leading and trailing white space removal + while (std::isspace(*newstring.begin())) + newstring.erase(newstring.begin()); - while (std::isspace(*newstring.rbegin())) - newstring.erase(newstring.length() - 1); + while (std::isspace(*newstring.rbegin())) + newstring.erase(newstring.length() - 1); - //make sure it contains something - if (newstring.size() > 0) - v.push_back(newstring); + //make sure it contains something + if (newstring.size() > 0) v.push_back(newstring); } return v; -} + } -unsigned int checkFiles(const std::vector<std::string>& filenames) { - std::cout << "Input filenames:\n"; - unsigned int i = 0; - unsigned int totalYield = 0; + size_t checkFiles(const std::vector<std::string>& filenames) { + ATH_MSG_INFO("Input filenames:\n"); + size_t i = 0; + size_t totalYield = 0; for (const auto& filename : filenames) { - std::unique_ptr<TFile> f(TFile::Open(filename.c_str())); - std::cout << " " << i + 1 << "/" << filenames.size() << " File: " << filename; + std::unique_ptr<TFile> f(TFile::Open(filename.c_str())); + ATH_MSG_INFO(i + 1 << "/" << filenames.size() << " File: " << filename); - if (!f.get()) { - std::cout << "\nDid not manage to open " << filename << std::endl; - std::cout << "Can't continue" << std::endl; - exit(1); - } + if (!f.get()) { + throw std::runtime_error("Did not manage to open " + filename); + } - const TTree* const t = dynamic_cast<TTree* > (f->Get("CollectionTree")); + const TTree* const t = dynamic_cast<TTree* > (f->Get("CollectionTree")); - //some files made by the derivation framework have no events passing the - //cuts -> which means no collection tree. - //the old behaviour was to end execution on this problem - //not any more! - int entries = 0; - std::string note; - if (t) - entries = t->GetEntries(); - else - note = " (No CollectionTree)"; + //some files made by the derivation framework have no events passing the + //cuts -> which means no collection tree. + //the old behaviour was to end execution on this problem + //not any more! + int entries = 0; + std::string note; + if (t) entries = t->GetEntries(); + else note = " (No CollectionTree)"; - std::cout << " Entries: " << entries << note << "\n"; - totalYield += entries; + ATH_MSG_INFO("Entries: " << entries << note); + totalYield += entries; - ++i; + ++i; } - std::cout << "\n"; - return totalYield; -} + } -std::vector<std::string> fileList(const std::string& filename) { + std::vector<std::string> fileList(const std::string& filename) { std::ifstream ifs(filename.c_str()); if (!ifs) { - std::cout << "File does not exist " << filename << std::endl; - std::cout << "This should contain a list - comma separated list of" << std::endl; - std::cout << "input files" << std::endl; - std::cout << "Can't continue" << std::endl; - exit(1); + throw std::runtime_error("File does not exist " + filename + + "\nThis should contain a list - comma separated list of input files."); } //loop over the lines in the file @@ -306,8 +384,8 @@ std::vector<std::string> fileList(const std::string& filename) { //these will be included automagically. std::string line; while (!ifs.eof()) { - std::getline(ifs, line); - wholefile << line << ','; + std::getline(ifs, line); + wholefile << line << ','; } //somewhere to save the filenames @@ -316,78 +394,172 @@ std::vector<std::string> fileList(const std::string& filename) { //now zoom through the whole file string and split at the comma std::string to; while (std::getline(wholefile, to, ',')) { - if (to.size() > 0) - fileList.push_back(to); + if (to.size() > 0) fileList.push_back(to); } if (fileList.size() == 0) { - std::cout << "Could not get a list of input files from " << filename << std::endl; - std::cout << "Can't continue" << std::endl; - exit(1); + throw std::runtime_error("Could not get a list of input files from " + filename); } return fileList; -} + } -void loadLibraries(const std::string& libraryNames) { + void loadLibraries(const std::string& libraryNames) { std::vector<std::string> tokens; std::stringstream ss(libraryNames); std::string item; char delim = ' '; while (std::getline(ss, item, delim)) - tokens.push_back(item); + tokens.push_back(item); - std::vector<std::unique_ptr<top::ToolLoaderBase>> toolLoaders; + std::vector<std::unique_ptr<top::ToolLoaderBase> > toolLoaders; for (const auto& toolLoaderName : tokens) { - std::cout << "Attempting to load library: " << toolLoaderName << ".so\n"; - gSystem->Load((toolLoaderName + ".so").c_str()); + ATH_MSG_INFO("Attempting to load library: " << toolLoaderName << ".so"); + gSystem->Load((toolLoaderName + ".so").c_str()); } -} + } -top::TopObjectSelection* loadObjectSelection(std::shared_ptr<top::TopConfig> config) { - std::cout << "Attempting to load ObjectSelection: " << config->objectSelectionName() << std::endl; - TClass* c = ::TClass::GetClass( config->objectSelectionName().c_str() ); + top::TopObjectSelection* loadObjectSelection(std::shared_ptr<top::TopConfig> config) { + ATH_MSG_INFO("Attempting to load ObjectSelection: " << config->objectSelectionName()); + TClass* c = ::TClass::GetClass(config->objectSelectionName().c_str()); if (c == nullptr) { - std::cout << "Didn't manage to load " << config->objectSelectionName() << std::endl; - exit(1); + throw std::runtime_error("Didn't manage to load " + config->objectSelectionName()); } top::ObjectLoaderBase* bc = static_cast<top::ObjectLoaderBase*> (c->New()); if (bc == nullptr) { - std::cout << "Didn't manage to cast it to top::ObjectLoaderBase " << std::endl; - exit(1); + throw std::runtime_error("Didn't manage to cast it to top::ObjectLoaderBase"); } top::TopObjectSelection* objectSelection = bc->init(config); if (objectSelection == nullptr) { - std::cout << "Didn't manage to make a top::ObjectSelection class" << std::endl; - exit(1); + throw std::runtime_error("Didn't manage to make a top::ObjectSelection class"); } return objectSelection; -} + } -top::EventSaverBase* loadEventSaver(std::shared_ptr<top::TopConfig> config) { - std::cout << "Attempting to load OutputFormat: " << config->outputFormat() << std::endl; - TClass* c = ::TClass::GetClass( config->outputFormat().c_str() ); + top::EventSaverBase* loadEventSaver(std::shared_ptr<top::TopConfig> config) { + ATH_MSG_INFO("Attempting to load OutputFormat: " << config->outputFormat()); + TClass* c = ::TClass::GetClass(config->outputFormat().c_str()); if (c == nullptr) { - std::cout << "Didn't manage to load " << config->outputFormat() << std::endl; - exit(1); + throw std::runtime_error("Didn't manage to load " + config->outputFormat()); } top::EventSaverBase* bc = static_cast<top::EventSaverBase*> (c->New()); if (bc == nullptr) { - std::cout << "Didn't manage to cast it to top::EventSaverBase " << std::endl; - exit(1); + throw std::runtime_error("Didn't manage to cast it to top::EventSaverBase "); } return bc; -} + } + bool readMetaData(TFile* inputFile, std::shared_ptr<top::TopConfig> config) { + // Load the file into a TEvent + xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); + top::check(xaodEvent.readFrom(inputFile), "Cannot load inputFile"); + xaodEvent.getEntry(0); + + bool gotDSID=false; + unsigned int mcChannelNumber = ((unsigned int) -1); + + std::string productionRelease="?", amiTag="?", AODFixVersion="?", AODCalibVersion="?", dataType="?", geometryVersion="?", conditionsTag="?", + beamType="?", simFlavour="?"; + float beamEnergy = 0, mcProcID = -1; + + // Magical metadata tool to access FileMetaData object + asg::AsgMetadataTool ATMetaData("OurNewMetaDataObject"); + bool readFMD=false; + + // Check it exists, and if it does we will work with it + if (ATMetaData.inputMetaStore()->contains<xAOD::FileMetaData>("FileMetaData")) { + + ATH_MSG_INFO("Trying to read FileMetaData"); + + // Create pointer for FileMetaData which we will load + const xAOD::FileMetaData* FMD = 0; + top::check(ATMetaData.inputMetaStore()->retrieve(FMD, + "FileMetaData"), + "Failed to retrieve metadata from AsgMetadataTool"); + // Let's get all the info we can... + // https://gitlab.cern.ch/atlas/athena/blob/21.2/Event/xAOD/xAODMetaData/xAODMetaData/versions/FileMetaData_v1.h#L47 + /// Release that was used to make the file [string] + FMD->value(xAOD::FileMetaData::productionRelease, productionRelease); + /// AMI tag used to process the file the last time [string] + FMD->value(xAOD::FileMetaData::amiTag, amiTag); + /// Version of AODFix that was used on the file last [string] + FMD->value(xAOD::FileMetaData::AODFixVersion, AODFixVersion); + /// Version of AODCalib that was used on the file last [string] + FMD->value(xAOD::FileMetaData::AODCalibVersion, AODCalibVersion); + /// Data type that's in the file [string] + FMD->value(xAOD::FileMetaData::dataType, dataType); + /// Geometry version [string] + FMD->value(xAOD::FileMetaData::geometryVersion, geometryVersion); + /// Conditions version used for simulation/reconstruction [string] + FMD->value(xAOD::FileMetaData::conditionsTag, conditionsTag); + /// Beam energy [float] + FMD->value(xAOD::FileMetaData::beamEnergy, beamEnergy); + /// Beam type [string] + FMD->value(xAOD::FileMetaData::beamType, beamType); + /// Same as mc_channel_number [float] + gotDSID = FMD->value(xAOD::FileMetaData::mcProcID, mcProcID); + mcChannelNumber = mcProcID; + /// Fast or Full sim [string] + FMD->value(xAOD::FileMetaData::simFlavour, simFlavour); + /// It is also possible to access any other info in metadata with + /// FMD->value("SomeMetaInfo", someObject); + readFMD=true; + } + if (!readFMD || !gotDSID || mcChannelNumber == ((unsigned int) -1)){ // in case FileMetaData is bugged and does not have DSID properly stored happens for example for files with 0 events in CollectionTree after skimming + + ATH_MSG_INFO("FileMetaData not found or not readable, trying to read TruthMetaData"); + + bool gotTruthMetaData = true; + const xAOD::TruthMetaDataContainer *truthMetadata = nullptr; + if (ATMetaData.inputMetaStore()->contains<xAOD::TruthMetaDataContainer>("TruthMetaData")) { + if (ATMetaData.inputMetaStore()->retrieve(truthMetadata, "TruthMetaData")) { + if (truthMetadata->size() == 1) { + mcChannelNumber = truthMetadata->at(0)->mcChannelNumber(); + } else { + ATH_MSG_WARNING("TruthMetaData does not have exactly one entry. Cannot reliably determine DSID"); + } + } else { + gotTruthMetaData = false; + } + } else { + gotTruthMetaData = false; + } + if (!gotTruthMetaData) + { + ATH_MSG_ERROR("We cannot retrieve even TruthMetaData to determine DSID"); + return false; + } + } + + /// Print out this information as a cross-check + ATH_MSG_INFO("Using AsgMetadataTool to access the following information\n" + << "productionRelease -> " << productionRelease << "\n" + << "amiTag -> " << amiTag << "\n" + << "AODFixVersion -> " << AODFixVersion << "\n" + << "AODCalibVersion -> " << AODCalibVersion << "\n" + << "dataType -> " << dataType << "\n" + << "geometryVersion -> " << geometryVersion << "\n" + << "conditionsTag -> " << conditionsTag << "\n" + << "beamEnergy -> " << beamEnergy << "\n" + << "beamType -> " << beamType << "\n" + << "mcProcID -> " << int(mcChannelNumber) << "\n" + << "simFlavour -> " << simFlavour << "\n" + << "Not all of this information is propagated to TopConfig"); + + config->setAmiTag(amiTag); + config->setDSID(mcChannelNumber); + + return true; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/AnalysisTrackingHelper.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/AnalysisTrackingHelper.h new file mode 100644 index 000000000000..13b848776983 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/AnalysisTrackingHelper.h @@ -0,0 +1,69 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef _TOPANALYSIS_ANALYSISTRACKINGHELPER_H_ +#define _TOPANALYSIS_ANALYSISTRACKINGHELPER_H_ + +#include <memory> +#include <string> +#include <vector> + +namespace top { + class TopConfig; +} + +namespace top { +/** + * @brief Helper for collecting data for analysis tracking. + */ + class AnalysisTrackingHelper { + public: + AnalysisTrackingHelper(); + ~AnalysisTrackingHelper(); + + /** + * @brief Notify helper that an input file was processed. + * + * @param path Path to the input file. + * @param entriesProcessed Number of entries that were processed. + */ + void addInputFile(std::string const& path, unsigned long long entriesProcessed); + + /** + * @brief Notify helper about configuration options. + * + * @param topConfig Pointer to the TopConfig object. + */ + void setTopConfig(std::shared_ptr<TopConfig> const& topConfig); + + /** + * @brief Store tracking data in current TFile. + * + * @param treename Name of the TTree used to store the data. + * + * @remarks + * It's your responsibility to call TFile::cd() before this function. + */ + void writeTree(std::string const& treename); + private: + struct InputFileInfo { + InputFileInfo(std::string const& path, unsigned long long const entriesProcessed) : + path(path), + entriesProcessed(entriesProcessed) { + } + + std::string const path; + unsigned long long const entriesProcessed; + }; + + void finish(); + + std::string m_json; + bool m_finished; + std::shared_ptr<TopConfig> m_topConfig; + std::vector<InputFileInfo> m_inputFiles; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverBase.h index 31887cf8f138..97426dc94c38 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTSAVERBASE_H_ #define EVENTSAVERBASE_H_ @@ -20,18 +20,17 @@ namespace top { class ParticleLevelEvent; /** - * @brief A base class so users can write their own event saving stuff. Some - * people, for some reason, prefer flat ntuples to xAODs. - */ - class EventSaverBase{ - + * @brief A base class so users can write their own event saving stuff. Some + * people, for some reason, prefer flat ntuples to xAODs. + */ + class EventSaverBase { public: - /** + /** * @brief Default ctor/dtor - ROOT wants to use these, don't use fancy ctors */ - EventSaverBase(){} - virtual ~EventSaverBase(){} - + EventSaverBase() {} + virtual ~EventSaverBase() {} + /** * @brief Called once at the start of the job after the file has been opened. * @@ -39,7 +38,14 @@ namespace top { * @param file You probably need the file if you're going to write to it. * @param extraBranches So you can write extra branches (only for xAOD). */ - virtual void initialize(std::shared_ptr<top::TopConfig> config, TFile* file, const std::vector<std::string>& extraBranches) = 0; + virtual void initialize(std::shared_ptr<top::TopConfig> config, TFile* file, + const std::vector<std::string>& extraBranches) = 0; + + /** + * @brief Method to execute any calculations common for + * reco/particle/parton level. + */ + virtual void execute() {return;} /** * @brief I guess you want to save an event sometimes to. @@ -50,18 +56,18 @@ namespace top { * * @param event The event in question, in the format used internally. */ - virtual void saveEvent(const top::Event& /*event*/){return;} - virtual void saveEventToxAOD(){return;} - - /** + virtual void saveEvent(const top::Event& /*event*/) {return;} + virtual void saveEventToxAOD() {return;} + + /** * @breif Run for every event - * + * * This fills, if requested, the: - * MC truth record + * MC truth record * PDF info * TopPartons */ - virtual void saveTruthEvent(){return;} + virtual void saveTruthEvent() {return;} /*! * @brief Function to save the particle level event. @@ -71,8 +77,8 @@ namespace top { * @param plEvent The particle level event whose contents will be saved. */ virtual void saveParticleLevelEvent(const top::ParticleLevelEvent& /* plEvent */) { - /* Deliberately No-Op */ - return; + /* Deliberately No-Op */ + return; } /*! @@ -83,18 +89,17 @@ namespace top { * @param upgradeEvent The upgrade event whose contents will be saved. */ virtual void saveUpgradeEvent(const top::ParticleLevelEvent& /* plEvent */) { - /* Deliberately No-Op */ - return; + /* Deliberately No-Op */ + return; } /** * @brief So you can write something at the end of the job (like metadata). */ - virtual void finalize(){return;} + virtual void finalize() {return;} ClassDef(top::EventSaverBase, 0); }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverFlatNtuple.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverFlatNtuple.h index 82ab1d577f1b..38e80327578c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverFlatNtuple.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverFlatNtuple.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTSAVERFLATNTUPLE_H_ #define EVENTSAVERFLATNTUPLE_H_ @@ -8,7 +8,6 @@ #include "TopAnalysis/EventSaverBase.h" #include "TopCorrections/ScaleFactorRetriever.h" #include "TopEventSelectionTools/TreeManager.h" -#include "TopObjectSelectionTools/RCJetMC15.h" // Framework include(s): #include "AsgTools/AsgTool.h" @@ -16,19 +15,18 @@ #include "AthContainers/DataVector.h" #include <unordered_map> -namespace top { +namespace top { // fwd declare upgrade class -class UpgradeEvent; + class UpgradeEvent; /** * @brief Some code that writes out a 'standard' flat ntuple. This can be * extended if the user wants to inherit from this and implement the functions * themselves. */ -class EventSaverFlatNtuple : public top::EventSaverBase , public asg::AsgTool { - -public: + class EventSaverFlatNtuple: public top::EventSaverBase, public asg::AsgTool { + public: /** * @brief A default constructor so that this class can be created at * run-time by ROOT. @@ -49,10 +47,17 @@ public: * @param extraBranches Extra info requested (like which selections are * passed). */ - virtual void initialize(std::shared_ptr<top::TopConfig> config, TFile* file, const std::vector<std::string>& extraBranches); + virtual void initialize(std::shared_ptr<top::TopConfig> config, TFile* file, + const std::vector<std::string>& extraBranches) override; + + /** + * @brief Execute stuff common for reco/particle/parton level, + * e.g. loading of weights, PDF sets, etc. + */ + virtual void execute() override; //Keep the asg::AsgTool happy - virtual StatusCode initialize(){return StatusCode::SUCCESS;} + virtual StatusCode initialize() override {return StatusCode::SUCCESS;} /** * @brief Run for every event (actually every systematic for every event). @@ -62,7 +67,10 @@ public: * @param event The top::Event which has had object selection and overlap * removal (if requested) applied to it. */ - virtual void saveEvent(const top::Event& event); + virtual void saveEvent(const top::Event& event) override; // calls the three next functions + virtual void cleanEvent(); // (re-)initialise all relevant variables to default (dummy) values + virtual void calculateEvent(const top::Event& event); // calculate the relevant variables + virtual void fillEvent(const top::Event& event); // calls tree->Fill /** * @breif Run for every event @@ -72,7 +80,10 @@ public: * PDF info * TopPartons */ - virtual void saveTruthEvent(); + virtual void saveTruthEvent() override; // calls the three next functions + virtual void cleanTruthEvent(); // (re-)initialise all relevant variables to default (dummy) values + virtual void calculateTruthEvent(); // calculate the relevant variables + virtual void fillTruthEvent(); // calls tree->Fill /*! * @brief Store the particle level event's content in the particle level @@ -85,7 +96,11 @@ public: * @param plEvent The particle level event whose data content will be * written to the output. */ - virtual void saveParticleLevelEvent(const top::ParticleLevelEvent& plEvent); + virtual void saveParticleLevelEvent(const top::ParticleLevelEvent& plEvent) override; // calls the three next functions + virtual void cleanParticleLevelEvent(); // (re-)initialise all relevant variables to default (dummy) values + virtual void calculateParticleLevelEvent(const top::ParticleLevelEvent& plEvent); // calculate the relevant + // variables + virtual void fillParticleLevelEvent(); // calls tree->Fill /*! * @brief Store the upgrade event's content in the upgrade @@ -98,19 +113,21 @@ public: * @param upgradeEvent The upgrade event whose data content will be * written to the output. */ - virtual void saveUpgradeEvent(const top::ParticleLevelEvent& plEvent); + virtual void saveUpgradeEvent(const top::ParticleLevelEvent& plEvent) override; // calls the three next functions + virtual void cleanUpgradeEvent(); // (re-)initialise all relevant variables to default (dummy) values + virtual void calculateUpgradeEvent(const top::ParticleLevelEvent& plEvent); // calculate the relevant variables + virtual void fillUpgradeEvent(); // calls tree->Fill /** * @brief Not used by the flat ntuple code yet, but needed by the xAOD code. */ - virtual void finalize(); + virtual void finalize() override; /** * @brief shorten name of b-tagging working point (FixedCutBEff_*) */ - std::string shortBtagWP(std::string const & WP) const; - -protected: + std::string shortBtagWP(std::string const& WP) const; + protected: /** * @brief Allow child classes to access the configuration object. */ @@ -124,7 +141,7 @@ protected: * * @return A vector of the treeManagers (one for each systematic). */ - std::vector<std::shared_ptr<top::TreeManager>> treeManagers(); + std::vector<std::shared_ptr<top::TreeManager> > treeManagers(); std::shared_ptr<top::TreeManager> truthTreeManager(); /*! @@ -135,32 +152,40 @@ protected: */ std::shared_ptr<top::TreeManager> particleLevelTreeManager(); + /*! + * @brief Return a shared pointer to the top::TreeManager object that is + * used for the upgrade level output tree. + * @returns A shared pointer to the top::TreeManager object that is used to + * write out the upgrade level event data. + */ + std::shared_ptr<top::TreeManager> upgradeTreeManager(); - /** - * @brief Return a shared pointer to the top::ScaleFactorRetriever object - * which allows us to easily access the SF decorations - * @returns A shared pointer to the top::ScaleFactorRetriever object - */ - std::shared_ptr<top::ScaleFactorRetriever> scaleFactorRetriever(); + /** + * @brief Return a shared pointer to the top::ScaleFactorRetriever object + * which allows us to easily access the SF decorations + * @returns A shared pointer to the top::ScaleFactorRetriever object + */ + //std::shared_ptr<top::ScaleFactorRetriever> scaleFactorRetriever(); + top::ScaleFactorRetriever* scaleFactorRetriever(); /*! * @brief Function to access the branch filters - cf ANALYSISTO-61 * @returns A shared pointer to the m_branchFilters object */ - std::vector<top::TreeManager::BranchFilter> & branchFilters(); - + std::vector<top::TreeManager::BranchFilter>& branchFilters(); + /*! * @brief Internal function which configures the particle level tree * manager. It does branch setup etc. */ - void setupParticleLevelTreeManager(const top::ParticleLevelEvent& plEvent); + void setupParticleLevelTreeManager(/*const top::ParticleLevelEvent& plEvent*/); /*! * @brief Internal function which configures the upgrade tree manager. * It does branch setup etc. */ void setupUpgradeTreeManager(/*const top::UpgradeEvent& upgradeEvent*/); -private: + private: /** * @brief For each selection that we run in the top-xaod code, we "decorate" * event info with a variable saying if this event passed or failed it. @@ -205,13 +230,14 @@ private: std::shared_ptr<top::TopConfig> m_config; ///Scale factors - std::shared_ptr<top::ScaleFactorRetriever> m_sfRetriever; + //std::shared_ptr<top::ScaleFactorRetriever> m_sfRetriever; + top::ScaleFactorRetriever* m_sfRetriever; ///The file where everything goes TFile* m_outputFile; ///A simple way to write out branches, without having to worry about the type. - std::vector<std::shared_ptr<top::TreeManager>> m_treeManagers; + std::vector<std::shared_ptr<top::TreeManager> > m_treeManagers; std::shared_ptr<top::TreeManager> m_truthTreeManager; /// The top::TreeManager used for the particle level data output. @@ -220,7 +246,8 @@ private: /// decisions. The std::pair contains: /// .first --- The name of the selection /// .second --- The variable used for storing into the TTree - std::vector< std::pair<std::string,int> > m_particleLevel_SelectionDecisions; + std::vector< std::pair<std::string, int> > m_particleLevel_SelectionDecisions; + std::vector< std::pair<std::string, int> > m_upgrade_SelectionDecisions; /// TreeManager for upgrade analysis data output std::shared_ptr<top::TreeManager> m_upgradeTreeManager; @@ -231,6 +258,13 @@ private: /// branch filters - cf ANALYSISTO-61 std::vector<top::TreeManager::BranchFilter> m_branchFilters; + /// remove "FT_EFF_" and spaces in named systematics + std::string betterBtagNamedSyst(const std::string WP); + + ///////////////////////////////////// + /// Definition of event variables + ///////////////////////////////////// + ///Decisions on if the event passed / failed a particular selection. std::vector<int> m_selectionDecisions; @@ -243,12 +277,21 @@ private: //Store output PDF weights from LHAPDF std::unordered_map<std::string, std::vector<float> > m_PDF_eventWeights; + // Store boosted jet tagger names + std::vector<std::string> m_boostedJetTaggersNames; + std::vector<std::string> m_boostedJetTaggersNamesCalibrated; + //some event weights float m_weight_mc; float m_weight_pileup; ///-- Pileup SF systematics --/// float m_weight_pileup_UP; float m_weight_pileup_DOWN; + ///---Fwd electrons --/// + float m_weight_fwdElSF; + float m_weight_fwdElSF_FWDEL_SF_ID_UP; + float m_weight_fwdElSF_FWDEL_SF_ID_DOWN; + ///-- Lepton SF --/// float m_weight_leptonSF; ///-- Lepton SF - electron SF systematics --/// @@ -260,6 +303,14 @@ private: float m_weight_leptonSF_EL_SF_ID_DOWN; float m_weight_leptonSF_EL_SF_Isol_UP; float m_weight_leptonSF_EL_SF_Isol_DOWN; + ///-- electron SF advanded correlation model systematics --/// + std::vector<float> m_weight_leptonSF_EL_SF_CorrModel_Reco_UP; + std::vector<float> m_weight_leptonSF_EL_SF_CorrModel_Reco_DOWN; + std::vector<float> m_weight_leptonSF_EL_SF_CorrModel_ID_UP; + std::vector<float> m_weight_leptonSF_EL_SF_CorrModel_ID_DOWN; + std::vector<float> m_weight_leptonSF_EL_SF_CorrModel_Iso_UP; + std::vector<float> m_weight_leptonSF_EL_SF_CorrModel_Iso_DOWN; + ///-- Lepton SF - muon SF systematics --/// float m_weight_leptonSF_MU_SF_Trigger_STAT_UP; float m_weight_leptonSF_MU_SF_Trigger_STAT_DOWN; @@ -284,11 +335,24 @@ private: float m_weight_leptonSF_MU_SF_TTVA_STAT_DOWN; float m_weight_leptonSF_MU_SF_TTVA_SYST_UP; float m_weight_leptonSF_MU_SF_TTVA_SYST_DOWN; + // Additional global event calculated trigger SF + systematics + float m_weight_globalLeptonTriggerSF; + float m_weight_globalLeptonTriggerSF_EL_Trigger_UP; + float m_weight_globalLeptonTriggerSF_EL_Trigger_DOWN; + float m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_UP; + float m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_DOWN; + float m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_UP; + float m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_DOWN; + // Old trigger SFs + float m_weight_oldTriggerSF; + float m_weight_oldTriggerSF_EL_Trigger_UP; + float m_weight_oldTriggerSF_EL_Trigger_DOWN; + float m_weight_oldTriggerSF_MU_Trigger_STAT_UP; + float m_weight_oldTriggerSF_MU_Trigger_STAT_DOWN; + float m_weight_oldTriggerSF_MU_Trigger_SYST_UP; + float m_weight_oldTriggerSF_MU_Trigger_SYST_DOWN; ///-- individual components for lepton SF --/// - float m_weight_indiv_SF_EL_Trigger; - float m_weight_indiv_SF_EL_Trigger_UP; - float m_weight_indiv_SF_EL_Trigger_DOWN; float m_weight_indiv_SF_EL_Reco; float m_weight_indiv_SF_EL_Reco_UP; float m_weight_indiv_SF_EL_Reco_DOWN; @@ -306,11 +370,6 @@ private: float m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN; float m_weight_indiv_SF_EL_ChargeMisID_SYST_UP; float m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN; - float m_weight_indiv_SF_MU_Trigger; - float m_weight_indiv_SF_MU_Trigger_STAT_UP; - float m_weight_indiv_SF_MU_Trigger_STAT_DOWN; - float m_weight_indiv_SF_MU_Trigger_SYST_UP; - float m_weight_indiv_SF_MU_Trigger_SYST_DOWN; float m_weight_indiv_SF_MU_ID; // Muon ID SF systematics (regular) float m_weight_indiv_SF_MU_ID_STAT_UP; @@ -336,68 +395,92 @@ private: // Taus float m_weight_tauSF; - float m_weight_tauSF_ELEOLR_UP; - float m_weight_tauSF_ELEOLR_DOWN; - float m_weight_tauSF_JETID_UP; - float m_weight_tauSF_JETID_DOWN; - float m_weight_tauSF_RECO_UP; - float m_weight_tauSF_RECO_DOWN; + std::map<top::topSFSyst, float> m_weight_tauSF_variations; // Photons float m_weight_photonSF = 0.; float m_weight_photonSF_ID_UP = 0.; float m_weight_photonSF_ID_DOWN = 0.; - float m_weight_photonSF_effIso = 0.; - float m_weight_photonSF_effLowPtIso_UP = 0.; - float m_weight_photonSF_effLowPtIso_DOWN = 0.; - float m_weight_photonSF_effTrkIso_UP = 0.; - float m_weight_photonSF_effTrkIso_DOWN = 0.; - float m_weight_photonSF_isoDDonoff_UP = 0.; - float m_weight_photonSF_isoDDonoff_DOWN = 0.; + float m_weight_photonSF_effIso_UP = 0.; + float m_weight_photonSF_effIso_DOWN = 0.; // nominal b-tagging SF [WP] std::unordered_map<std::string, float> m_weight_bTagSF; std::unordered_map<std::string, float> m_weight_trackjet_bTagSF; + // per-jet nominal btag SF + std::unordered_map<std::string, std::vector<float> > m_perjet_weight_bTagSF; + std::unordered_map<std::string, std::vector<float> > m_perjet_weight_trackjet_bTagSF; + // JVT (c++11 initialization for fun) float m_weight_jvt = 0.0; float m_weight_jvt_up = 0.0; float m_weight_jvt_down = 0.0; + // fJVT + float m_weight_forwardjvt = 0.0; + float m_weight_forwardjvt_up = 0.0; + float m_weight_forwardjvt_down = 0.0; - // Sherpa 2.2 weight + // Sherpa 2.2 weight float m_weight_sherpa_22_vjets = 0.; // eigen variations affecting b-jets [WP] - std::unordered_map<std::string, std::vector<float>> m_weight_bTagSF_eigen_B_up; - std::unordered_map<std::string, std::vector<float>> m_weight_bTagSF_eigen_B_down; - std::unordered_map<std::string, std::vector<float>> m_weight_trackjet_bTagSF_eigen_B_up; - std::unordered_map<std::string, std::vector<float>> m_weight_trackjet_bTagSF_eigen_B_down; + std::unordered_map<std::string, std::vector<float> > m_weight_bTagSF_eigen_B_up; + std::unordered_map<std::string, std::vector<float> > m_weight_bTagSF_eigen_B_down; + std::unordered_map<std::string, std::vector<float> > m_weight_trackjet_bTagSF_eigen_B_up; + std::unordered_map<std::string, std::vector<float> > m_weight_trackjet_bTagSF_eigen_B_down; + + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_bTagSF_eigen_B_up; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_bTagSF_eigen_B_down; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_trackjet_bTagSF_eigen_B_up; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_trackjet_bTagSF_eigen_B_down; // eigen variations affecting c-jets [WP] - std::unordered_map<std::string, std::vector<float>> m_weight_bTagSF_eigen_C_up; - std::unordered_map<std::string, std::vector<float>> m_weight_bTagSF_eigen_C_down; - std::unordered_map<std::string, std::vector<float>> m_weight_trackjet_bTagSF_eigen_C_up; - std::unordered_map<std::string, std::vector<float>> m_weight_trackjet_bTagSF_eigen_C_down; + std::unordered_map<std::string, std::vector<float> > m_weight_bTagSF_eigen_C_up; + std::unordered_map<std::string, std::vector<float> > m_weight_bTagSF_eigen_C_down; + std::unordered_map<std::string, std::vector<float> > m_weight_trackjet_bTagSF_eigen_C_up; + std::unordered_map<std::string, std::vector<float> > m_weight_trackjet_bTagSF_eigen_C_down; + + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_bTagSF_eigen_C_up; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_bTagSF_eigen_C_down; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_trackjet_bTagSF_eigen_C_up; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_trackjet_bTagSF_eigen_C_down; // eigen variations affecting light jets [WP] - std::unordered_map<std::string, std::vector<float>> m_weight_bTagSF_eigen_Light_up; - std::unordered_map<std::string, std::vector<float>> m_weight_bTagSF_eigen_Light_down; - std::unordered_map<std::string, std::vector<float>> m_weight_trackjet_bTagSF_eigen_Light_up; - std::unordered_map<std::string, std::vector<float>> m_weight_trackjet_bTagSF_eigen_Light_down; + std::unordered_map<std::string, std::vector<float> > m_weight_bTagSF_eigen_Light_up; + std::unordered_map<std::string, std::vector<float> > m_weight_bTagSF_eigen_Light_down; + std::unordered_map<std::string, std::vector<float> > m_weight_trackjet_bTagSF_eigen_Light_up; + std::unordered_map<std::string, std::vector<float> > m_weight_trackjet_bTagSF_eigen_Light_down; - // named systematics [WP][name] - std::unordered_map<std::string, std::unordered_map<std::string, float>> m_weight_bTagSF_named_up; - std::unordered_map<std::string, std::unordered_map<std::string, float>> m_weight_bTagSF_named_down; - std::unordered_map<std::string, std::unordered_map<std::string, float>> m_weight_trackjet_bTagSF_named_up; - std::unordered_map<std::string, std::unordered_map<std::string, float>> m_weight_trackjet_bTagSF_named_down; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_bTagSF_eigen_Light_up; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_bTagSF_eigen_Light_down; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_trackjet_bTagSF_eigen_Light_up; + std::unordered_map<std::string, std::vector<std::vector<float> > > m_perjet_weight_trackjet_bTagSF_eigen_Light_down; - // remove "FT_EFF_" and spaces in named systematics - std::string betterBtagNamedSyst (const std::string WP); + // named systematics [WP][name] + std::unordered_map<std::string, std::unordered_map<std::string, float> > m_weight_bTagSF_named_up; + std::unordered_map<std::string, std::unordered_map<std::string, float> > m_weight_bTagSF_named_down; + std::unordered_map<std::string, std::unordered_map<std::string, float> > m_weight_trackjet_bTagSF_named_up; + std::unordered_map<std::string, std::unordered_map<std::string, float> > m_weight_trackjet_bTagSF_named_down; + + std::unordered_map<std::string, + std::unordered_map<std::string, std::vector<float> > > m_perjet_weight_bTagSF_named_up; + std::unordered_map<std::string, + std::unordered_map<std::string, std::vector<float> > > m_perjet_weight_bTagSF_named_down; + std::unordered_map<std::string, + std::unordered_map<std::string, std::vector<float> > > m_perjet_weight_trackjet_bTagSF_named_up; + std::unordered_map<std::string, + std::unordered_map<std::string, + std::vector<float> > > m_perjet_weight_trackjet_bTagSF_named_down; ///-- weights for matrix-method fakes estimate, for each selection and configuration --/// - /// m_fakesMM_weights[selection][configuration] - std::unordered_map<std::string,std::unordered_map<std::string, float>> m_fakesMM_weights; + int m_ASMsize; + std::vector<float> m_ASMweights; + std::vector<std::vector<float> > m_ASMweights_Syst; + std::vector<std::vector<std::string> > m_ASMweights_Systname; + /// Weights for bootstrapping + std::vector<int> m_weight_poisson; //event info unsigned long long m_eventNumber; @@ -406,9 +489,13 @@ private: unsigned int m_mcChannelNumber; float m_mu_original; float m_mu; - // non-collision background flag - usage: https://twiki.cern.ch/twiki/bin/view/Atlas/NonCollisionBackgroundsRunTwo#Recommend_cuts_tools_and_procedu + float m_mu_actual_original; + float m_mu_actual; + // non-collision background flag - usage: + // https://twiki.cern.ch/twiki/bin/view/Atlas/NonCollisionBackgroundsRunTwo#Recommend_cuts_tools_and_procedu unsigned int m_backgroundFlags; - // hasBadMuon flag - see: https://twiki.cern.ch/twiki/bin/viewauth/Atlas/MuonSelectionTool#is_BadMuon_Flag_Event_Veto + // hasBadMuon flag - see: + // https://twiki.cern.ch/twiki/bin/viewauth/Atlas/MuonSelectionTool#is_BadMuon_Flag_Event_Veto unsigned int m_hasBadMuon; //electrons @@ -418,8 +505,11 @@ private: std::vector<float> m_el_phi; std::vector<float> m_el_e; std::vector<float> m_el_charge; + std::vector<float> m_el_faketype; std::vector<float> m_el_topoetcone20; std::vector<float> m_el_ptvarcone20; + std::vector<float> m_el_etcone20; + std::vector<float> m_el_ptcone30; std::vector<char> m_el_isTight; std::vector<char> m_el_CF; // pass charge ID selector (has no charge flip) std::unordered_map<std::string, std::vector<char> > m_el_trigMatched; @@ -427,8 +517,23 @@ private: std::vector<float> m_el_delta_z0_sintheta; std::vector<int> m_el_true_type; std::vector<int> m_el_true_origin; - std::vector<int> m_el_true_typebkg; - std::vector<int> m_el_true_originbkg; + std::vector<int> m_el_true_firstEgMotherTruthType; + std::vector<int> m_el_true_firstEgMotherTruthOrigin; + std::vector<int> m_el_true_firstEgMotherPdgId; + std::vector<char> m_el_true_isPrompt; + std::vector<char> m_el_true_isChargeFl; + std::vector<char> m_el_ECIDS; + std::vector<double> m_el_ECIDSResult; + + //forward electrons + std::vector<float> m_fwdel_pt; + std::vector<float> m_fwdel_eta; + std::vector<float> m_fwdel_phi; + std::vector<float> m_fwdel_e; + std::vector<float> m_fwdel_etcone20; + std::vector<float> m_fwdel_etcone30; + std::vector<float> m_fwdel_etcone40; + std::vector<char> m_fwdel_isTight; //muons std::vector<float> m_mu_pt; @@ -438,41 +543,180 @@ private: std::vector<float> m_mu_charge; std::vector<float> m_mu_topoetcone20; std::vector<float> m_mu_ptvarcone30; + std::vector<float> m_mu_etcone20; + std::vector<float> m_mu_ptcone30; std::vector<char> m_mu_isTight; std::unordered_map<std::string, std::vector<char> > m_mu_trigMatched; std::vector<float> m_mu_d0sig; std::vector<float> m_mu_delta_z0_sintheta; std::vector<int> m_mu_true_type; std::vector<int> m_mu_true_origin; + std::vector<char> m_mu_true_isPrompt; + std::vector<float> m_mu_prodVtx_z; + std::vector<float> m_mu_prodVtx_perp; + std::vector<float> m_mu_prodVtx_phi; + + //soft muons + std::vector<float> m_softmu_pt; + std::vector<float> m_softmu_eta; + std::vector<float> m_softmu_phi; + std::vector<float> m_softmu_e; + std::vector<float> m_softmu_charge; + std::vector<float> m_softmu_d0; + std::vector<float> m_softmu_d0sig; + std::vector<float> m_softmu_delta_z0_sintheta; + std::vector<int> m_softmu_true_type; + std::vector<int> m_softmu_true_origin; + std::vector<int> m_softmu_true_isPrompt; + std::vector<float> m_softmu_SF_ID; + std::vector<float> m_softmu_SF_ID_STAT_UP; + std::vector<float> m_softmu_SF_ID_STAT_DOWN; + std::vector<float> m_softmu_SF_ID_SYST_UP; + std::vector<float> m_softmu_SF_ID_SYST_DOWN; + std::vector<float> m_softmu_SF_ID_STAT_LOWPT_UP; + std::vector<float> m_softmu_SF_ID_STAT_LOWPT_DOWN; + std::vector<float> m_softmu_SF_ID_SYST_LOWPT_UP; + std::vector<float> m_softmu_SF_ID_SYST_LOWPT_DOWN; + std::vector<int> m_softmu_parton_origin_flag; + std::vector<int> m_softmu_particle_origin_flag; + std::vector<int> m_softmu_parent_pdgid; + std::vector<int> m_softmu_b_hadron_parent_pdgid; + std::vector<int> m_softmu_c_hadron_parent_pdgid; + + //temporary: PLIV for electrons+muons + std::vector<float> m_PLIV_el_PromptLeptonRNN_conversion; + std::vector<float> m_PLIV_el_PromptLeptonRNN_non_prompt_b; + std::vector<float> m_PLIV_el_PromptLeptonRNN_non_prompt_c; + std::vector<float> m_PLIV_el_PromptLeptonRNN_prompt; + std::vector<short> m_PLIV_el_PromptLeptonImprovedInput_MVAXBin; + std::vector<float> m_PLIV_el_PromptLeptonImprovedInput_TrackJetNTrack; + std::vector<float> m_PLIV_el_PromptLeptonImprovedInput_topoetcone30rel; + std::vector<float> m_PLIV_el_PromptLeptonImprovedInput_ptvarcone30rel; + std::vector<float> m_PLIV_el_PromptLeptonImprovedInput_PtFrac; + std::vector<float> m_PLIV_el_PromptLeptonImprovedInput_DRlj; + std::vector<float> m_PLIV_el_PromptLeptonImprovedInput_CaloClusterSumEtRel; + std::vector<float> m_PLIV_el_PromptLeptonImprovedInput_PtRel; + std::vector<float> m_PLIV_el_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest_ThetaCutVtx; + std::vector<float> m_PLIV_el_PromptLeptonImprovedVetoBARR; + std::vector<float> m_PLIV_el_PromptLeptonImprovedVetoECAP; + std::vector<float> m_PLIV_mu_PromptLeptonRNN_non_prompt_b; + std::vector<float> m_PLIV_mu_PromptLeptonRNN_non_prompt_c; + std::vector<float> m_PLIV_mu_PromptLeptonRNN_prompt; + std::vector<short> m_PLIV_mu_PromptLeptonImprovedInput_MVAXBin; + std::vector<float> m_PLIV_mu_PromptLeptonImprovedInput_topoetcone30rel; + std::vector<float> m_PLIV_mu_PromptLeptonImprovedInput_PtFrac; + std::vector<float> m_PLIV_mu_PromptLeptonImprovedInput_DRlj; + std::vector<float> m_PLIV_mu_PromptLeptonImprovedInput_ptvarcone30_TightTTVA_pt500rel; + std::vector<float> m_PLIV_mu_PromptLeptonImprovedInput_CaloClusterERel; + std::vector<float> m_PLIV_mu_PromptLeptonImprovedInput_CandVertex_normDistToPriVtxLongitudinalBest; + std::vector<float> m_PLIV_mu_PromptLeptonImprovedVeto; + //photons std::vector<float> m_ph_pt; std::vector<float> m_ph_eta; std::vector<float> m_ph_phi; std::vector<float> m_ph_e; + std::vector<float> m_ph_true_type; + std::vector<float> m_ph_true_origin; + std::vector<float> m_ph_faketype; std::vector<float> m_ph_iso; //taus std::vector<float> m_tau_pt; std::vector<float> m_tau_eta; std::vector<float> m_tau_phi; + std::vector<float> m_tau_e; std::vector<float> m_tau_charge; + std::vector<char> m_tau_isHadronic; //jets std::vector<float> m_jet_pt; std::vector<float> m_jet_eta; std::vector<float> m_jet_phi; std::vector<float> m_jet_e; - std::vector<float> m_jet_mv2c00; std::vector<float> m_jet_mv2c10; - std::vector<float> m_jet_mv2c20; std::vector<float> m_jet_jvt; - std::vector<char> m_jet_passfjvt; + std::vector<float> m_jet_fjvt; + std::vector<char> m_jet_passfjvt; //Could be useful to check pass/fail when fJVT only used in MET std::vector<float> m_jet_ip3dsv1; std::vector<int> m_jet_truthflav; std::vector<int> m_jet_truthPartonLabel; std::vector<char> m_jet_isTrueHS; - std::unordered_map<std::string, std::vector<char>> m_jet_isbtagged;//one vector per jet per WP - std::vector<int> m_jet_tagWeightBin;//tag-weight bin in case Continuous WP is used + std::vector<int> m_jet_HadronConeExclExtendedTruthLabelID; // Newer jet truth flavour label + std::unordered_map<std::string, std::vector<char> > m_jet_isbtagged;//one vector per jet per WP + std::unordered_map<std::string, std::vector<int> > m_jet_tagWeightBin;// one vector per jet per tag-weight bin in + // case Continuous WP is used + + // ghost tracks + std::vector<std::vector<float> > m_jet_ghostTrack_pt; + std::vector<std::vector<float> > m_jet_ghostTrack_eta; + std::vector<std::vector<float> > m_jet_ghostTrack_phi; + std::vector<std::vector<float> > m_jet_ghostTrack_e; + std::vector<std::vector<float> > m_jet_ghostTrack_d0; + std::vector<std::vector<float> > m_jet_ghostTrack_z0; + std::vector<std::vector<float> > m_jet_ghostTrack_qOverP; + + // tracks + std::vector<float> m_track_pt; + std::vector<float> m_track_eta; + std::vector<float> m_track_phi; + std::vector<float> m_track_e; + std::vector<float> m_track_d0; + std::vector<float> m_track_z0; + std::vector<float> m_track_qOverP; + std::vector<float> m_track_charge; + std::vector<float> m_track_d0_significance; + std::vector<float> m_track_z0_significance; + std::vector<float> m_track_phi0; + std::vector<float> m_track_theta; + std::vector<float> m_track_chiSquared; + std::vector<uint8_t> m_track_numberDoF; + + // R21 b-tagging + std::unordered_map<std::string, std::vector<float>> m_jet_DLx; + std::unordered_map<std::string, std::vector<float>> m_jet_DLx_pb; + std::unordered_map<std::string, std::vector<float>> m_jet_DLx_pc; + std::unordered_map<std::string, std::vector<float>> m_jet_DLx_pu; + + // fail-JVT jets + std::vector<float> m_failJvt_jet_pt; + std::vector<float> m_failJvt_jet_eta; + std::vector<float> m_failJvt_jet_phi; + std::vector<float> m_failJvt_jet_e; + std::vector<float> m_failJvt_jet_jvt; + std::vector<float> m_failJvt_jet_fjvt; + std::vector<char> m_failJvt_jet_passfjvt; + std::vector<int> m_failJvt_jet_truthflav; + std::vector<int> m_failJvt_jet_truthPartonLabel; + std::vector<char> m_failJvt_jet_isTrueHS; + std::vector<int> m_failJvt_jet_HadronConeExclExtendedTruthLabelID; // Newer jet truth flavour label + std::vector<std::vector<float> > m_failJvt_jet_ghostTrack_pt; + std::vector<std::vector<float> > m_failJvt_jet_ghostTrack_eta; + std::vector<std::vector<float> > m_failJvt_jet_ghostTrack_phi; + std::vector<std::vector<float> > m_failJvt_jet_ghostTrack_e; + std::vector<std::vector<float> > m_failJvt_jet_ghostTrack_d0; + std::vector<std::vector<float> > m_failJvt_jet_ghostTrack_z0; + std::vector<std::vector<float> > m_failJvt_jet_ghostTrack_qOverP; + + // fail-FJVT jets + std::vector<float> m_failFJvt_jet_pt; + std::vector<float> m_failFJvt_jet_eta; + std::vector<float> m_failFJvt_jet_phi; + std::vector<float> m_failFJvt_jet_e; + std::vector<float> m_failFJvt_jet_jvt; + std::vector<float> m_failFJvt_jet_fjvt; + std::vector<char> m_failFJvt_jet_passjvt; + std::vector<int> m_failFJvt_jet_truthflav; + std::vector<int> m_failFJvt_jet_truthPartonLabel; + std::vector<char> m_failFJvt_jet_isTrueHS; + std::vector<int> m_failFJvt_jet_HadronConeExclExtendedTruthLabelID; // Newer jet truth flavour label + std::vector<std::vector<float> > m_failFJvt_jet_ghostTrack_pt; + std::vector<std::vector<float> > m_failFJvt_jet_ghostTrack_eta; + std::vector<std::vector<float> > m_failFJvt_jet_ghostTrack_phi; + std::vector<std::vector<float> > m_failFJvt_jet_ghostTrack_e; + std::vector<std::vector<float> > m_failFJvt_jet_ghostTrack_d0; + std::vector<std::vector<float> > m_failFJvt_jet_ghostTrack_z0; + std::vector<std::vector<float> > m_failFJvt_jet_ghostTrack_qOverP; // for upgrade, we store the tagging efficiency per jet & whether it is from pileup std::vector<float> m_jet_mv1eff; @@ -484,34 +728,47 @@ private: std::vector<float> m_ljet_phi; std::vector<float> m_ljet_e; std::vector<float> m_ljet_m; - std::vector<float> m_ljet_sd12; + std::vector<int> m_ljet_truthLabel; + + std::unordered_map<std::string, std::vector<float> > m_ljet_substructure; + std::unordered_map<std::string, std::vector<char> > m_ljet_isTagged; + std::unordered_map<std::string, std::vector<float> > m_ljet_tagSF; //track jets std::vector<float> m_tjet_pt; std::vector<float> m_tjet_eta; std::vector<float> m_tjet_phi; std::vector<float> m_tjet_e; - std::vector<float> m_tjet_mv2c00; std::vector<float> m_tjet_mv2c10; - std::vector<float> m_tjet_mv2c20; - std::unordered_map<std::string, std::vector<char>> m_tjet_isbtagged;//one vector per jet per WP - std::vector<int> m_tjet_tagWeightBin;//tag-weight bin in case Continuous WP is used + std::unordered_map<std::string, SG::AuxElement::ConstAccessor<float>> DLx; + std::unordered_map<std::string, std::vector<float>> m_tjet_DLx; + std::unordered_map<std::string, std::vector<float>> m_tjet_DLx_pb; + std::unordered_map<std::string, std::vector<float>> m_tjet_DLx_pc; + std::unordered_map<std::string, std::vector<float>> m_tjet_DLx_pu; + std::unordered_map<std::string, std::vector<char> > m_tjet_isbtagged;//one vector per jet per WP + std::unordered_map<std::string, std::vector<int> > m_tjet_tagWeightBin;//one vector per jet tag-weight bin in case + // Continuous WP is used //re-clustered jets // -> need unordered map for systematics bool m_makeRCJets; // making re-clustered jets bool m_makeVarRCJets; // making VarRC jets + bool m_useRCJSS; // write RCJSS variables + bool m_useRCAdditionalJSS; // write RCJSS additional variables + bool m_useVarRCJSS; // write Variable-R RCJSS variables + bool m_useVarRCAdditionalJSS; // write Variable-R RCJSS additional variables + bool m_useElectronChargeIDSelection; // write ECID tool output variables std::string m_RCJetContainer; // name for RC jets container in TStore std::vector<std::string> m_VarRCJetRho; std::vector<std::string> m_VarRCJetMassScale; - std::unique_ptr<RCJetMC15> m_rc; - std::map<std::string,std::unique_ptr<RCJetMC15> > m_VarRC; std::string m_egamma; // egamma systematic naming scheme std::string m_muonsyst; // muon systematic naming scheme + std::string m_softmuonsyst; // soft muon systematic naming scheme std::string m_jetsyst; // jet systematic naming scheme - std::unordered_map<std::size_t, JetReclusteringTool*> m_jetReclusteringTool; - std::map<std::string,std::vector<float>> m_VarRCjetBranches; - std::map<std::string,std::vector<std::vector<float>>> m_VarRCjetsubBranches; + std::map<std::string, std::vector<float> > m_VarRCjetBranches; + std::map<std::string, std::vector<std::vector<float> > > m_VarRCjetsubBranches; + std::map<std::string, std::vector<float> > m_VarRCjetBranchesParticle; + std::map<std::string, std::vector<std::vector<float> > > m_VarRCjetsubBranchesParticle; std::vector<int> m_rcjet_nsub; std::vector<float> m_rcjet_pt; std::vector<float> m_rcjet_eta; @@ -525,12 +782,54 @@ private: std::vector<std::vector<float> > m_rcjetsub_e; std::vector<std::vector<float> > m_rcjetsub_mv2c10; + std::vector<float> m_rrcjet_pt; + std::vector<float> m_rrcjet_eta; + std::vector<float> m_rrcjet_phi; + std::vector<float> m_rrcjet_e; + + std::vector<float> m_rcjet_tau32_clstr; + std::vector<float> m_rcjet_tau21_clstr; + std::vector<float> m_rcjet_tau3_clstr; + std::vector<float> m_rcjet_tau2_clstr; + std::vector<float> m_rcjet_tau1_clstr; + + std::vector<float> m_rcjet_D2_clstr; + std::vector<float> m_rcjet_ECF1_clstr; + std::vector<float> m_rcjet_ECF2_clstr; + std::vector<float> m_rcjet_ECF3_clstr; + + std::vector<float> m_rcjet_d12_clstr; + std::vector<float> m_rcjet_d23_clstr; + std::vector<float> m_rcjet_Qw_clstr; + std::vector<float> m_rcjet_nconstituent_clstr; + + std::vector<float> m_rcjet_gECF332_clstr; + std::vector<float> m_rcjet_gECF461_clstr; + std::vector<float> m_rcjet_gECF322_clstr; + std::vector<float> m_rcjet_gECF331_clstr; + std::vector<float> m_rcjet_gECF422_clstr; + std::vector<float> m_rcjet_gECF441_clstr; + std::vector<float> m_rcjet_gECF212_clstr; + std::vector<float> m_rcjet_gECF321_clstr; + std::vector<float> m_rcjet_gECF311_clstr; + std::vector<float> m_rcjet_L1_clstr; + std::vector<float> m_rcjet_L2_clstr; + std::vector<float> m_rcjet_L3_clstr; + std::vector<float> m_rcjet_L4_clstr; + std::vector<float> m_rcjet_L5_clstr; + + //met float m_met_met; float m_met_phi; + //these are for specific studies on the met, turned off by default, and turned on with the WriteMETBuiltWithLooseObjects option + float m_met_met_withLooseObjects; + float m_met_phi_withLooseObjects; //KLFitter short m_klfitter_selected; + /// Selection + std::vector<std::string> m_klfitter_selection; /// Error flags std::vector<short> m_klfitter_minuitDidNotConverge; std::vector<short> m_klfitter_fitAbortedDueToNaN; @@ -541,8 +840,9 @@ private: std::vector<unsigned int> m_klfitter_bestPermutation; std::vector<float> m_klfitter_logLikelihood; std::vector<float> m_klfitter_eventProbability; - std::vector<std::vector<double>> m_klfitter_parameters; - std::vector<std::vector<double>> m_klfitter_parameterErrors; + std::vector<unsigned int> m_klfitter_parameters_size; + std::vector<std::vector<double> > m_klfitter_parameters; + std::vector<std::vector<double> > m_klfitter_parameterErrors; /// Model std::vector<float> m_klfitter_model_bhad_pt; @@ -585,12 +885,61 @@ private: std::vector<float> m_klfitter_model_lep_eta; std::vector<float> m_klfitter_model_lep_phi; std::vector<float> m_klfitter_model_lep_E; + std::vector<unsigned int> m_klfitter_model_lep_index; + + std::vector<float> m_klfitter_model_lepZ1_pt; + std::vector<float> m_klfitter_model_lepZ1_eta; + std::vector<float> m_klfitter_model_lepZ1_phi; + std::vector<float> m_klfitter_model_lepZ1_E; + std::vector<unsigned int> m_klfitter_model_lepZ1_index; + + std::vector<float> m_klfitter_model_lepZ2_pt; + std::vector<float> m_klfitter_model_lepZ2_eta; + std::vector<float> m_klfitter_model_lepZ2_phi; + std::vector<float> m_klfitter_model_lepZ2_E; + std::vector<unsigned int> m_klfitter_model_lepZ2_index; std::vector<float> m_klfitter_model_nu_pt; std::vector<float> m_klfitter_model_nu_eta; std::vector<float> m_klfitter_model_nu_phi; std::vector<float> m_klfitter_model_nu_E; + std::vector<float> m_klfitter_model_b_from_top1_pt; + std::vector<float> m_klfitter_model_b_from_top1_eta; + std::vector<float> m_klfitter_model_b_from_top1_phi; + std::vector<float> m_klfitter_model_b_from_top1_E; + std::vector<unsigned int> m_klfitter_model_b_from_top1_jetIndex; + + std::vector<float> m_klfitter_model_b_from_top2_pt; + std::vector<float> m_klfitter_model_b_from_top2_eta; + std::vector<float> m_klfitter_model_b_from_top2_phi; + std::vector<float> m_klfitter_model_b_from_top2_E; + std::vector<unsigned int> m_klfitter_model_b_from_top2_jetIndex; + + std::vector<float> m_klfitter_model_lj1_from_top1_pt; + std::vector<float> m_klfitter_model_lj1_from_top1_eta; + std::vector<float> m_klfitter_model_lj1_from_top1_phi; + std::vector<float> m_klfitter_model_lj1_from_top1_E; + std::vector<unsigned int> m_klfitter_model_lj1_from_top1_jetIndex; + + std::vector<float> m_klfitter_model_lj2_from_top1_pt; + std::vector<float> m_klfitter_model_lj2_from_top1_eta; + std::vector<float> m_klfitter_model_lj2_from_top1_phi; + std::vector<float> m_klfitter_model_lj2_from_top1_E; + std::vector<unsigned int> m_klfitter_model_lj2_from_top1_jetIndex; + + std::vector<float> m_klfitter_model_lj1_from_top2_pt; + std::vector<float> m_klfitter_model_lj1_from_top2_eta; + std::vector<float> m_klfitter_model_lj1_from_top2_phi; + std::vector<float> m_klfitter_model_lj1_from_top2_E; + std::vector<unsigned int> m_klfitter_model_lj1_from_top2_jetIndex; + + std::vector<float> m_klfitter_model_lj2_from_top2_pt; + std::vector<float> m_klfitter_model_lj2_from_top2_eta; + std::vector<float> m_klfitter_model_lj2_from_top2_phi; + std::vector<float> m_klfitter_model_lj2_from_top2_E; + std::vector<unsigned int> m_klfitter_model_lj2_from_top2_jetIndex; + // calculated KLFitter variables for best perm float m_klfitter_bestPerm_topLep_pt; float m_klfitter_bestPerm_topLep_eta; @@ -643,7 +992,10 @@ private: std::vector<float> m_mc_eta; std::vector<float> m_mc_phi; std::vector<float> m_mc_e; + std::vector<double> m_mc_charge; std::vector<int> m_mc_pdgId; + std::vector<int> m_mc_status; + std::vector<int> m_mc_barcode; //PDFInfo std::vector<float> m_PDFinfo_X1; @@ -653,9 +1005,8 @@ private: std::vector<float> m_PDFinfo_Q; std::vector<float> m_PDFinfo_XF1; std::vector<float> m_PDFinfo_XF2; - - //the on-the-fly computed generator weights - //there is one vector of float per entry in the trutheventcontainer (which should have only 1 entry) + + //the on-the-fly computed generator weights stored in EventInfo std::vector<float> m_mc_generator_weights; //Extra variables for Particle Level (bare lepton kinematics and b-Hadron @@ -674,17 +1025,643 @@ private: std::vector<int> m_jet_Ghosts_CHadron_Final_Count; std::vector<int> m_ljet_Ghosts_BHadron_Final_Count; std::vector<int> m_ljet_Ghosts_CHadron_Final_Count; + std::vector<std::vector<int> > m_rcjetsub_Ghosts_BHadron_Final_Count; + std::vector<std::vector<int> > m_rcjetsub_Ghosts_CHadron_Final_Count; + + // Truth tree inserted variables + // This can be expanded as required + // This is just a first pass at doing this sort of thing + std::unordered_map<std::string, int*> m_extraTruthVars_int; + std::unordered_map<std::string, float*> m_extraTruthVars_float; + protected: + ///////////////////////////////////// + /// const getters for the event variables + ///////////////////////////////////// + + ///Decisions on if the event passed / failed a particular selection. + const std::vector<int>& selectionDecisions() const {return m_selectionDecisions;} + + ///Decisions on if the event passed / failed a particular trigger. + const std::unordered_map<std::string, char>& triggerDecisions() const {return m_triggerDecisions;} + + ///Pre-scale of the trigger menu for each event. + const std::unordered_map<std::string, float>& triggerPrescales() const {return m_triggerPrescales;} + //Store output PDF weights from LHAPDF + const std::unordered_map<std::string, std::vector<float> >& PDF_eventWeights() const {return m_PDF_eventWeights;} + + //some event weights + const float& weight_mc() const {return m_weight_mc;} + const float& weight_pileup() const {return m_weight_pileup;} + + ///-- Pileup SF systematics --/// + const float& weight_pileup_UP() const {return m_weight_pileup_UP;} + const float& weight_pileup_DOWN() const {return m_weight_pileup_DOWN;} + + ///-- Lepton SF --/// + const float& weight_leptonSF() const {return m_weight_leptonSF;} + + ///-- Lepton SF - electron SF systematics --/// + const float& weight_leptonSF_EL_SF_Trigger_UP() const {return m_weight_leptonSF_EL_SF_Trigger_UP;} + const float& weight_leptonSF_EL_SF_Trigger_DOWN() const {return m_weight_leptonSF_EL_SF_Trigger_DOWN;} + const float& weight_leptonSF_EL_SF_Reco_UP() const {return m_weight_leptonSF_EL_SF_Reco_UP;} + const float& weight_leptonSF_EL_SF_Reco_DOWN() const {return m_weight_leptonSF_EL_SF_Reco_DOWN;} + const float& weight_leptonSF_EL_SF_ID_UP() const {return m_weight_leptonSF_EL_SF_ID_UP;} + const float& weight_leptonSF_EL_SF_ID_DOWN() const {return m_weight_leptonSF_EL_SF_ID_DOWN;} + const float& weight_leptonSF_EL_SF_Isol_UP() const {return m_weight_leptonSF_EL_SF_Isol_UP;} + const float& weight_leptonSF_EL_SF_Isol_DOWN() const {return m_weight_leptonSF_EL_SF_Isol_DOWN;} + + ///-- Lepton SF - muon SF systematics --/// + const float& weight_leptonSF_MU_SF_Trigger_STAT_UP() const {return m_weight_leptonSF_MU_SF_Trigger_STAT_UP;} + const float& weight_leptonSF_MU_SF_Trigger_STAT_DOWN() const {return m_weight_leptonSF_MU_SF_Trigger_STAT_DOWN;} + const float& weight_leptonSF_MU_SF_Trigger_SYST_UP() const {return m_weight_leptonSF_MU_SF_Trigger_SYST_UP;} + const float& weight_leptonSF_MU_SF_Trigger_SYST_DOWN() const {return m_weight_leptonSF_MU_SF_Trigger_SYST_DOWN;} + // Muon ID SF systematics (regular) + const float& weight_leptonSF_MU_SF_ID_STAT_UP() const {return m_weight_leptonSF_MU_SF_ID_STAT_UP;} + const float& weight_leptonSF_MU_SF_ID_STAT_DOWN() const {return m_weight_leptonSF_MU_SF_ID_STAT_DOWN;} + const float& weight_leptonSF_MU_SF_ID_SYST_UP() const {return m_weight_leptonSF_MU_SF_ID_SYST_UP;} + const float& weight_leptonSF_MU_SF_ID_SYST_DOWN() const {return m_weight_leptonSF_MU_SF_ID_SYST_DOWN;} + // Muon ID SF systematics (low pT) + const float& weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP() const {return m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_UP;} + const float& weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN() const {return m_weight_leptonSF_MU_SF_ID_STAT_LOWPT_DOWN;} + const float& weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP() const {return m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_UP;} + const float& weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN() const {return m_weight_leptonSF_MU_SF_ID_SYST_LOWPT_DOWN;} + // Muon isolation SF systematics + const float& weight_leptonSF_MU_SF_Isol_STAT_UP() const {return m_weight_leptonSF_MU_SF_Isol_STAT_UP;} + const float& weight_leptonSF_MU_SF_Isol_STAT_DOWN() const {return m_weight_leptonSF_MU_SF_Isol_STAT_DOWN;} + const float& weight_leptonSF_MU_SF_Isol_SYST_UP() const {return m_weight_leptonSF_MU_SF_Isol_SYST_UP;} + const float& weight_leptonSF_MU_SF_Isol_SYST_DOWN() const {return m_weight_leptonSF_MU_SF_Isol_SYST_DOWN;} + const float& weight_leptonSF_MU_SF_TTVA_STAT_UP() const {return m_weight_leptonSF_MU_SF_TTVA_STAT_UP;} + const float& weight_leptonSF_MU_SF_TTVA_STAT_DOWN() const {return m_weight_leptonSF_MU_SF_TTVA_STAT_DOWN;} + const float& weight_leptonSF_MU_SF_TTVA_SYST_UP() const {return m_weight_leptonSF_MU_SF_TTVA_SYST_UP;} + const float& weight_leptonSF_MU_SF_TTVA_SYST_DOWN() const {return m_weight_leptonSF_MU_SF_TTVA_SYST_DOWN;} + // Special global lepton trigger SF + systematics + const float& weight_globalLeptonTriggerSF() const {return m_weight_globalLeptonTriggerSF;} + const float& weight_globalLeptonTriggerSF_EL_Trigger_UP() const { + return m_weight_globalLeptonTriggerSF_EL_Trigger_UP; + } + const float& weight_globalLeptonTriggerSF_EL_Trigger_DOWN() const { + return m_weight_globalLeptonTriggerSF_EL_Trigger_DOWN; + } + const float& weight_globalLeptonTriggerSF_MU_Trigger_STAT_UP() const { + return m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_UP; + } + const float& weight_globalLeptonTriggerSF_MU_Trigger_STAT_DOWN() const { + return m_weight_globalLeptonTriggerSF_MU_Trigger_STAT_DOWN; + } + const float& weight_globalLeptonTriggerSF_MU_Trigger_SYST_UP() const {return m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_UP;} + const float& weight_globalLeptonTriggerSF_MU_Trigger_SYST_DOWN() const {return m_weight_globalLeptonTriggerSF_MU_Trigger_SYST_DOWN;} + // Old trigger SFs + const float& weight_oldTriggerSF() const {return m_weight_oldTriggerSF;} + const float& weight_oldTriggerSF_EL_Trigger_UP() const {return m_weight_oldTriggerSF_EL_Trigger_UP;} + const float& weight_oldTriggerSF_EL_Trigger_DOWN() const {return m_weight_oldTriggerSF_EL_Trigger_DOWN;} + const float& weight_oldTriggerSF_MU_Trigger_STAT_UP() const {return m_weight_oldTriggerSF_MU_Trigger_STAT_UP;} + const float& weight_oldTriggerSF_MU_Trigger_STAT_DOWN() const {return m_weight_oldTriggerSF_MU_Trigger_STAT_DOWN;} + const float& weight_oldTriggerSF_MU_Trigger_SYST_UP() const {return m_weight_oldTriggerSF_MU_Trigger_SYST_UP;} + const float& weight_oldTriggerSF_MU_Trigger_SYST_DOWN() const {return m_weight_oldTriggerSF_MU_Trigger_SYST_DOWN;} + + ///-- individual components for lepton SF --/// + const float& weight_indiv_SF_EL_Trigger() const {return weight_oldTriggerSF();} + const float& weight_indiv_SF_EL_Trigger_UP() const {return weight_oldTriggerSF_EL_Trigger_UP();} + const float& weight_indiv_SF_EL_Trigger_DOWN() const {return weight_oldTriggerSF_EL_Trigger_DOWN();} + const float& weight_indiv_SF_EL_Reco() const {return m_weight_indiv_SF_EL_Reco;} + const float& weight_indiv_SF_EL_Reco_UP() const {return m_weight_indiv_SF_EL_Reco_UP;} + const float& weight_indiv_SF_EL_Reco_DOWN() const {return m_weight_indiv_SF_EL_Reco_DOWN;} + const float& weight_indiv_SF_EL_ID() const {return m_weight_indiv_SF_EL_ID;} + const float& weight_indiv_SF_EL_ID_UP() const {return m_weight_indiv_SF_EL_ID_UP;} + const float& weight_indiv_SF_EL_ID_DOWN() const {return m_weight_indiv_SF_EL_ID_DOWN;} + const float& weight_indiv_SF_EL_Isol() const {return m_weight_indiv_SF_EL_Isol;} + const float& weight_indiv_SF_EL_Isol_UP() const {return m_weight_indiv_SF_EL_Isol_UP;} + const float& weight_indiv_SF_EL_Isol_DOWN() const {return m_weight_indiv_SF_EL_Isol_DOWN;} + const float& weight_indiv_SF_EL_ChargeID() const {return m_weight_indiv_SF_EL_ChargeID;} + const float& weight_indiv_SF_EL_ChargeID_UP() const {return m_weight_indiv_SF_EL_ChargeID_UP;} + const float& weight_indiv_SF_EL_ChargeID_DOWN() const {return m_weight_indiv_SF_EL_ChargeID_DOWN;} + const float& weight_indiv_SF_EL_ChargeMisID() const {return m_weight_indiv_SF_EL_ChargeMisID;} + const float& weight_indiv_SF_EL_ChargeMisID_STAT_UP() const {return m_weight_indiv_SF_EL_ChargeMisID_STAT_UP;} + const float& weight_indiv_SF_EL_ChargeMisID_STAT_DOWN() const {return m_weight_indiv_SF_EL_ChargeMisID_STAT_DOWN;} + const float& weight_indiv_SF_EL_ChargeMisID_SYST_UP() const {return m_weight_indiv_SF_EL_ChargeMisID_SYST_UP;} + const float& weight_indiv_SF_EL_ChargeMisID_SYST_DOWN() const {return m_weight_indiv_SF_EL_ChargeMisID_SYST_DOWN;} + const float& weight_indiv_SF_MU_Trigger() const {return weight_oldTriggerSF();} + const float& weight_indiv_SF_MU_Trigger_STAT_UP() const {return weight_oldTriggerSF_MU_Trigger_STAT_UP();} + const float& weight_indiv_SF_MU_Trigger_STAT_DOWN() const {return weight_oldTriggerSF_MU_Trigger_STAT_DOWN();} + const float& weight_indiv_SF_MU_Trigger_SYST_UP() const {return weight_oldTriggerSF_MU_Trigger_SYST_UP();} + const float& weight_indiv_SF_MU_Trigger_SYST_DOWN() const {return weight_oldTriggerSF_MU_Trigger_SYST_DOWN();} + const float& weight_indiv_SF_MU_ID() const {return m_weight_indiv_SF_MU_ID;} + // Muon ID SF systematics (regular) + const float& weight_indiv_SF_MU_ID_STAT_UP() const {return m_weight_indiv_SF_MU_ID_STAT_UP;} + const float& weight_indiv_SF_MU_ID_STAT_DOWN() const {return m_weight_indiv_SF_MU_ID_STAT_DOWN;} + const float& weight_indiv_SF_MU_ID_SYST_UP() const {return m_weight_indiv_SF_MU_ID_SYST_UP;} + const float& weight_indiv_SF_MU_ID_SYST_DOWN() const {return m_weight_indiv_SF_MU_ID_SYST_DOWN;} + // Muon ID SF systematics (low pt) + const float& weight_indiv_SF_MU_ID_STAT_LOWPT_UP() const {return m_weight_indiv_SF_MU_ID_STAT_LOWPT_UP;} + const float& weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN() const {return m_weight_indiv_SF_MU_ID_STAT_LOWPT_DOWN;} + const float& weight_indiv_SF_MU_ID_SYST_LOWPT_UP() const {return m_weight_indiv_SF_MU_ID_SYST_LOWPT_UP;} + const float& weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN() const {return m_weight_indiv_SF_MU_ID_SYST_LOWPT_DOWN;} + // Muon isolation systematics + const float& weight_indiv_SF_MU_Isol() const {return m_weight_indiv_SF_MU_Isol;} + const float& weight_indiv_SF_MU_Isol_SYST_UP() const {return m_weight_indiv_SF_MU_Isol_SYST_UP;} + const float& weight_indiv_SF_MU_Isol_SYST_DOWN() const {return m_weight_indiv_SF_MU_Isol_SYST_DOWN;} + const float& weight_indiv_SF_MU_Isol_STAT_UP() const {return m_weight_indiv_SF_MU_Isol_STAT_UP;} + const float& weight_indiv_SF_MU_Isol_STAT_DOWN() const {return m_weight_indiv_SF_MU_Isol_STAT_DOWN;} + const float& weight_indiv_SF_MU_TTVA() const {return m_weight_indiv_SF_MU_TTVA;} + const float& weight_indiv_SF_MU_TTVA_SYST_UP() const {return m_weight_indiv_SF_MU_TTVA_SYST_UP;} + const float& weight_indiv_SF_MU_TTVA_SYST_DOWN() const {return m_weight_indiv_SF_MU_TTVA_SYST_DOWN;} + const float& weight_indiv_SF_MU_TTVA_STAT_UP() const {return m_weight_indiv_SF_MU_TTVA_STAT_UP;} + const float& weight_indiv_SF_MU_TTVA_STAT_DOWN() const {return m_weight_indiv_SF_MU_TTVA_STAT_DOWN;} + + // Photons + const float& weight_photonSF() const {return m_weight_photonSF;} + const float& weight_photonSF_ID_UP() const {return m_weight_photonSF_ID_UP;} + const float& weight_photonSF_ID_DOWN() const {return m_weight_photonSF_ID_DOWN;} + const float& weight_photonSF_effIso_UP() const {return m_weight_photonSF_effIso_UP;} + const float& weight_photonSF_effIso_DOWN() const {return m_weight_photonSF_effIso_DOWN;} + + // nominal b-tagging SF [WP] + const std::unordered_map<std::string, float>& weight_bTagSF() const {return m_weight_bTagSF;} + const std::unordered_map<std::string, std::vector<float> >& perjet_weight_bTagSF() const {return m_perjet_weight_bTagSF;} + const std::unordered_map<std::string, float>& weight_trackjet_bTagSF() const {return m_weight_trackjet_bTagSF;} + const std::unordered_map<std::string, std::vector<float> >& perjet_weight_trackjet_bTagSF() const {return m_perjet_weight_trackjet_bTagSF;} + + // JVT (c++11 initialization for fun) + const float& weight_jvt() const {return m_weight_jvt;} + const float& weight_jvt_up() const {return m_weight_jvt_up;} + const float& weight_jvt_down() const {return m_weight_jvt_down;} + + // FJVT + const float& weight_forwardjvt() const {return m_weight_forwardjvt;} + const float& weight_forwardjvt_up() const {return m_weight_forwardjvt_up;} + const float& weight_forwardjvt_down() const {return m_weight_forwardjvt_down;} + + // Sherpa 2.2 weight + const float& weight_sherpa_22_vjets() const {return m_weight_sherpa_22_vjets;} + + // eigen variations affecting b-jets [WP] + const std::unordered_map<std::string, std::vector<float> >& weight_bTagSF_eigen_B_up() const {return m_weight_bTagSF_eigen_B_up;} + const std::unordered_map<std::string, std::vector<float> >& weight_bTagSF_eigen_B_down() const {return m_weight_bTagSF_eigen_B_down;} + const std::unordered_map<std::string, std::vector<float> >& weight_trackjet_bTagSF_eigen_B_up() const {return m_weight_trackjet_bTagSF_eigen_B_up;} + const std::unordered_map<std::string, std::vector<float> >& weight_trackjet_bTagSF_eigen_B_down() const {return m_weight_trackjet_bTagSF_eigen_B_down;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_bTagSF_eigen_B_up() const {return m_perjet_weight_bTagSF_eigen_B_up;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_bTagSF_eigen_B_down() const {return m_perjet_weight_bTagSF_eigen_B_down;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_trackjet_bTagSF_eigen_B_up() const {return m_perjet_weight_trackjet_bTagSF_eigen_B_up;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_trackjet_bTagSF_eigen_B_down() const {return m_perjet_weight_trackjet_bTagSF_eigen_B_down;} + // eigen variations affecting c-jets [WP] + const std::unordered_map<std::string, std::vector<float> >& weight_bTagSF_eigen_C_up() const {return m_weight_bTagSF_eigen_C_up;} + const std::unordered_map<std::string, std::vector<float> >& weight_bTagSF_eigen_C_down() const {return m_weight_bTagSF_eigen_C_down;} + const std::unordered_map<std::string, std::vector<float> >& weight_trackjet_bTagSF_eigen_C_up() const {return m_weight_trackjet_bTagSF_eigen_C_up;} + const std::unordered_map<std::string, std::vector<float> >& weight_trackjet_bTagSF_eigen_C_down() const {return m_weight_trackjet_bTagSF_eigen_C_down;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_bTagSF_eigen_C_up() const {return m_perjet_weight_bTagSF_eigen_C_up;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_bTagSF_eigen_C_down() const {return m_perjet_weight_bTagSF_eigen_C_down;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_trackjet_bTagSF_eigen_C_up() const {return m_perjet_weight_trackjet_bTagSF_eigen_C_up;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_trackjet_bTagSF_eigen_C_down() const {return m_perjet_weight_trackjet_bTagSF_eigen_C_down;} + // eigen variations affecting light jets [WP] + const std::unordered_map<std::string, std::vector<float> >& weight_bTagSF_eigen_Light_up() const {return m_weight_bTagSF_eigen_Light_up;} + const std::unordered_map<std::string, std::vector<float> >& weight_bTagSF_eigen_Light_down() const {return m_weight_bTagSF_eigen_Light_down;} + const std::unordered_map<std::string, std::vector<float> >& weight_trackjet_bTagSF_eigen_Light_up() const {return m_weight_trackjet_bTagSF_eigen_Light_up;} + const std::unordered_map<std::string, std::vector<float> >& weight_trackjet_bTagSF_eigen_Light_down() const {return m_weight_trackjet_bTagSF_eigen_Light_down;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_bTagSF_eigen_Light_up() const {return m_perjet_weight_bTagSF_eigen_C_up;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_bTagSF_eigen_Light_down() const {return m_perjet_weight_bTagSF_eigen_C_down;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_trackjet_bTagSF_eigen_Light_up() const {return m_perjet_weight_trackjet_bTagSF_eigen_Light_up;} + const std::unordered_map<std::string, std::vector<std::vector<float> > >& perjet_weight_trackjet_bTagSF_eigen_Light_down() const {return m_perjet_weight_trackjet_bTagSF_eigen_Light_down;} + // named systematics [WP][name] + const std::unordered_map<std::string, std::unordered_map<std::string, float> >& weight_bTagSF_named_up() const {return m_weight_bTagSF_named_up;} + const std::unordered_map<std::string, std::unordered_map<std::string, float> >& weight_bTagSF_named_down() const {return m_weight_bTagSF_named_down;} + const std::unordered_map<std::string, std::unordered_map<std::string, float> >& weight_trackjet_bTagSF_named_up() const {return m_weight_trackjet_bTagSF_named_up;} + const std::unordered_map<std::string, std::unordered_map<std::string, float> >& weight_trackjet_bTagSF_named_down() const {return m_weight_trackjet_bTagSF_named_down;} + const std::unordered_map<std::string, std::unordered_map<std::string, std::vector<float> > >& perjet_weight_bTagSF_named_up() const {return m_perjet_weight_bTagSF_named_up;} + const std::unordered_map<std::string, std::unordered_map<std::string, std::vector<float> > >& perjet_weight_bTagSF_named_down() const {return m_perjet_weight_bTagSF_named_down;} + const std::unordered_map<std::string, std::unordered_map<std::string, std::vector<float> > >& perjet_weight_trackjet_bTagSF_named_up() const {return m_perjet_weight_trackjet_bTagSF_named_up;} + const std::unordered_map<std::string, std::unordered_map<std::string, std::vector<float> > >& perjet_weight_trackjet_bTagSF_named_down() const {return m_perjet_weight_trackjet_bTagSF_named_down;} + + /// Weights for bootstrapping + const std::vector<int>& weight_poisson() const {return m_weight_poisson;} + + //event info + const unsigned long long& eventNumber() const {return m_eventNumber;} + const unsigned int& runNumber() const {return m_runNumber;} + const unsigned int& randomRunNumber() const {return m_randomRunNumber;} + const unsigned int& mcChannelNumber() const {return m_mcChannelNumber;} + const float& mu_original() const {return m_mu_original;} + const float& mu() const {return m_mu;} + + // non-collision background flag - usage: + // https://twiki.cern.ch/twiki/bin/view/Atlas/NonCollisionBackgroundsRunTwo#Recommend_cuts_tools_and_procedu + const unsigned int& backgroundFlags() const {return m_backgroundFlags;} + + // hasBadMuon flag - see: + // https://twiki.cern.ch/twiki/bin/viewauth/Atlas/MuonSelectionTool#is_BadMuon_Flag_Event_Veto + const unsigned int& hasBadMuon() const {return m_hasBadMuon;} + + //electrons + const std::vector<float>& el_pt() const {return m_el_pt;} + const std::vector<float>& el_eta() const {return m_el_eta;} + const std::vector<float>& el_cl_eta() const {return m_el_cl_eta;} + const std::vector<float>& el_phi() const {return m_el_phi;} + const std::vector<float>& el_e() const {return m_el_e;} + const std::vector<float>& el_faketype() const {return m_el_faketype;} + const std::vector<float>& el_charge() const {return m_el_charge;} + const std::vector<float>& el_topoetcone20() const {return m_el_topoetcone20;} + const std::vector<float>& el_ptvarcone20() const {return m_el_ptvarcone20;} + const std::vector<char>& el_isTight() const {return m_el_isTight;} + const std::vector<char>& el_CF() const {return m_el_CF;} // pass charge ID selector (has no charge flip) + const std::unordered_map<std::string, std::vector<char> >& el_trigMatched() const {return m_el_trigMatched;} + const std::vector<float>& el_d0sig() const {return m_el_d0sig;} + const std::vector<float>& el_delta_z0_sintheta() const {return m_el_delta_z0_sintheta;} + const std::vector<int>& el_true_type() const {return m_el_true_type;} + const std::vector<int>& el_true_origin() const {return m_el_true_origin;} + const std::vector<int>& el_true_firstEgMotherTruthType() const {return m_el_true_firstEgMotherTruthType;} + const std::vector<int>& el_true_firstEgMotherTruthOrigin() const {return m_el_true_firstEgMotherTruthOrigin;} + const std::vector<int>& el_true_firstEgMotherPdgId() const {return m_el_true_firstEgMotherPdgId;} + const std::vector<char>& el_true_isPrompt() const {return m_el_true_isPrompt;} + const std::vector<char>& el_true_isChargeFl() const {return m_el_true_isChargeFl;} + + //forward electrons + const std::vector<float>& fwdel_pt() const {return m_fwdel_pt;} + const std::vector<float>& fwdel_eta() const {return m_fwdel_eta;} + const std::vector<float>& fwdel_phi() const {return m_fwdel_phi;} + const std::vector<float>& fwdel_e() const {return m_fwdel_e;} + const std::vector<float>& fwdel_etcone20() const {return m_fwdel_etcone20;} + const std::vector<float>& fwdel_etcone30() const {return m_fwdel_etcone30;} + const std::vector<float>& fwdel_etcone40() const {return m_fwdel_etcone40;} + + //muons + const std::vector<float>& mu_pt() const {return m_mu_pt;} + const std::vector<float>& mu_eta() const {return m_mu_eta;} + const std::vector<float>& mu_phi() const {return m_mu_phi;} + const std::vector<float>& mu_e() const {return m_mu_e;} + const std::vector<float>& mu_charge() const {return m_mu_charge;} + const std::vector<float>& mu_topoetcone20() const {return m_mu_topoetcone20;} + const std::vector<float>& mu_ptvarcone30() const {return m_mu_ptvarcone30;} + const std::vector<char>& mu_isTight() const {return m_mu_isTight;} + const std::unordered_map<std::string, std::vector<char> >& mu_trigMatched() const {return m_mu_trigMatched;} + const std::vector<float>& mu_d0sig() const {return m_mu_d0sig;} + const std::vector<float>& mu_delta_z0_sintheta() const {return m_mu_delta_z0_sintheta;} + const std::vector<int>& mu_true_type() const {return m_mu_true_type;} + const std::vector<int>& mu_true_origin() const {return m_mu_true_origin;} + const std::vector<char>& mu_true_isPrompt() const {return m_mu_true_isPrompt;} + + //soft muons + const std::vector<float>& softmu_pt() const {return m_softmu_pt;} + const std::vector<float>& softmu_eta() const {return m_softmu_eta;} + const std::vector<float>& softmu_phi() const {return m_softmu_phi;} + const std::vector<float>& softmu_e() const {return m_softmu_e;} + const std::vector<float>& softmu_charge() const {return m_softmu_charge;} + const std::vector<float>& softmu_d0() const {return m_softmu_d0;} + const std::vector<float>& softmu_d0sig() const {return m_softmu_d0sig;} + const std::vector<float>& softmu_delta_z0_sintheta() const {return m_softmu_delta_z0_sintheta;} + const std::vector<int>& softmu_true_type() const {return m_softmu_true_type;} + const std::vector<int>& softmu_true_origin() const {return m_softmu_true_origin;} + const std::vector<int>& softmu_true_isPrompt() const {return m_softmu_true_isPrompt;} + + //photons + const std::vector<float>& ph_pt() const {return m_ph_pt;} + const std::vector<float>& ph_eta() const {return m_ph_eta;} + const std::vector<float>& ph_phi() const {return m_ph_phi;} + const std::vector<float>& ph_e() const {return m_ph_e;} + const std::vector<float>& ph_true_type() const {return m_ph_true_type;} + const std::vector<float>& ph_true_origin() const {return m_ph_true_origin;} + const std::vector<float>& ph_faketype() const {return m_ph_faketype;} + const std::vector<float>& ph_iso() const {return m_ph_iso;} + + //taus + const std::vector<float>& tau_pt() const {return m_tau_pt;} + const std::vector<float>& tau_eta() const {return m_tau_eta;} + const std::vector<float>& tau_phi() const {return m_tau_phi;} + const std::vector<float>& tau_charge() const {return m_tau_charge;} + + //jets + const std::vector<float>& jet_pt() const {return m_jet_pt;} + const std::vector<float>& jet_eta() const {return m_jet_eta;} + const std::vector<float>& jet_phi() const {return m_jet_phi;} + const std::vector<float>& jet_e() const {return m_jet_e;} + const std::vector<float>& jet_mv2c10() const {return m_jet_mv2c10;} + const std::vector<float>& jet_jvt() const {return m_jet_jvt;} + const std::vector<float>& jet_forwardjvt() const {return m_jet_fjvt;} + const std::vector<char>& jet_passforwardjvt() const {return m_jet_passfjvt;} + const std::vector<int>& jet_truthflav() const {return m_jet_truthflav;} + const std::vector<int>& jet_truthPartonLabel() const {return m_jet_truthPartonLabel;} + const std::vector<char>& jet_isTrueHS() const {return m_jet_isTrueHS;} + const std::vector<int>& jet_truthflavExtended() const {return m_jet_HadronConeExclExtendedTruthLabelID;} + const std::unordered_map<std::string, std::vector<char> >& jet_isbtagged() const {return m_jet_isbtagged;}//one + // vector + // per jet + // per WP + const std::unordered_map<std::string, std::vector<int> >& jet_tagWeightBin() const {return m_jet_tagWeightBin;}//one + // vector + // per + // jet + // tag-weight + // bin + // in + // case + // Continuous + // WP + // is + // used + // for upgrade, we store the tagging efficiency per jet & whether it is from pileup + const std::vector<float>& jet_mv1eff() const {return m_jet_mv1eff;} + const std::vector<float>& jet_isPileup() const {return m_jet_isPileup;} + + // fail-JVT jets + const std::vector<float>& failJvt_jet_pt() const {return m_failJvt_jet_pt;} + const std::vector<float>& failJvt_jet_eta() const {return m_failJvt_jet_eta;} + const std::vector<float>& failJvt_jet_phi() const {return m_failJvt_jet_phi;} + const std::vector<float>& failJvt_jet_e() const {return m_failJvt_jet_e;} + const std::vector<float>& failJvt_jet_jvt() const {return m_failJvt_jet_jvt;} + const std::vector<float>& failJvt_jet_forwardjvt() const {return m_failJvt_jet_fjvt;} + const std::vector<char>& failJvt_jet_passforwardjvt() const {return m_failJvt_jet_passfjvt;} + const std::vector<int>& failJvt_jet_truthflav() const {return m_failJvt_jet_truthflav;} + const std::vector<int>& failJvt_jet_truthPartonLabel() const {return m_failJvt_jet_truthPartonLabel;} + const std::vector<char>& failJvt_jet_isTrueHS() const {return m_failJvt_jet_isTrueHS;} + const std::vector<int>& failJvt_jet_truthflavExtended() const {return m_failJvt_jet_HadronConeExclExtendedTruthLabelID;} + + // fail-FJVT jets + const std::vector<float>& failFJvt_jet_pt() const {return m_failFJvt_jet_pt;} + const std::vector<float>& failFJvt_jet_eta() const {return m_failFJvt_jet_eta;} + const std::vector<float>& failFJvt_jet_phi() const {return m_failFJvt_jet_phi;} + const std::vector<float>& failFJvt_jet_e() const {return m_failFJvt_jet_e;} + const std::vector<float>& failFJvt_jet_jvt() const {return m_failFJvt_jet_jvt;} + const std::vector<float>& failFJvt_jet_forwardjvt() const {return m_failFJvt_jet_fjvt;} + const std::vector<char>& failFJvt_jet_passjvt() const {return m_failFJvt_jet_passjvt;} + const std::vector<int>& failFJvt_jet_truthflav() const {return m_failFJvt_jet_truthflav;} + const std::vector<int>& failFJvt_jet_truthPartonLabel() const {return m_failFJvt_jet_truthPartonLabel;} + const std::vector<char>& failFJvt_jet_isTrueHS() const {return m_failFJvt_jet_isTrueHS;} + const std::vector<int>& failFJvt_jet_truthflavExtended() const {return m_failFJvt_jet_HadronConeExclExtendedTruthLabelID;} + + //large-R jets + const std::vector<float>& ljet_pt() const {return m_ljet_pt;} + const std::vector<float>& ljet_eta() const {return m_ljet_eta;} + const std::vector<float>& ljet_phi() const {return m_ljet_phi;} + const std::vector<float>& ljet_e() const {return m_ljet_e;} + const std::vector<float>& ljet_m() const {return m_ljet_m;} + const std::vector<int>& ljet_truthLabel() const {return m_ljet_truthLabel;} + + const std::unordered_map<std::string, std::vector<float> >& ljet_substructure() const {return m_ljet_substructure;} + const std::unordered_map<std::string, std::vector<char> >& ljet_isTagged() const {return m_ljet_isTagged;} + const std::vector<char>& ljet_isTagged(const std::string& taggerName) {return m_ljet_isTagged[taggerName];} + + //track jets + const std::vector<float>& tjet_pt() const {return m_tjet_pt;} + const std::vector<float>& tjet_eta() const {return m_tjet_eta;} + const std::vector<float>& tjet_phi() const {return m_tjet_phi;} + const std::vector<float>& tjet_e() const {return m_tjet_e;} + const std::vector<float>& tjet_mv2c10() const {return m_tjet_mv2c10;} + const std::unordered_map<std::string, std::vector<char> >& tjet_isbtagged() const {return m_tjet_isbtagged;}//one + // vector + // per + // jet + // per + // WP + const std::unordered_map<std::string, std::vector<int> >& tjet_tagWeightBin() const {return m_tjet_tagWeightBin;}//one + // vector + // per + // jet + // tag-weight + // bin + // in + // case + // Continuous + // WP + // is + // used + + //re-clustered jets + // -> need unordered map for systematics + const bool& makeRCJets() const {return m_makeRCJets;} // making re-clustered jets + const bool& makeVarRCJets() const {return m_makeVarRCJets;} // making VarRC jets + const std::string& RCJetContainer() const {return m_RCJetContainer;} // name for RC jets container in TStore + const std::vector<std::string>& VarRCJetRho() const {return m_VarRCJetRho;} + const std::vector<std::string>& VarRCJetMassScale() const {return m_VarRCJetMassScale;} + const std::string& egamma() const {return m_egamma;} // egamma systematic naming scheme + const std::string& muonsyst() const {return m_muonsyst;} // muon systematic naming scheme + const std::string& softmuonsyst() const {return m_softmuonsyst;} // soft muon systematic naming scheme + const std::string& jetsyst() const {return m_jetsyst;} // jet systematic naming scheme + const std::map<std::string, std::vector<float> >& VarRCjetBranches() const {return m_VarRCjetBranches;} + const std::map<std::string, std::vector<std::vector<float> > >& VarRCjetsubBranches() const {return m_VarRCjetsubBranches;} + const std::vector<int>& rcjet_nsub() const {return m_rcjet_nsub;} + const std::vector<float>& rcjet_pt() const {return m_rcjet_pt;} + const std::vector<float>& rcjet_eta() const {return m_rcjet_eta;} + const std::vector<float>& rcjet_phi() const {return m_rcjet_phi;} + const std::vector<float>& rcjet_e() const {return m_rcjet_e;} + const std::vector<float>& rcjet_d12() const {return m_rcjet_d12;} + const std::vector<float>& rcjet_d23() const {return m_rcjet_d23;} + const std::vector<std::vector<float> >& rcjetsub_pt() const {return m_rcjetsub_pt;} + const std::vector<std::vector<float> >& rcjetsub_eta() const {return m_rcjetsub_eta;} + const std::vector<std::vector<float> >& rcjetsub_phi() const {return m_rcjetsub_phi;} + const std::vector<std::vector<float> >& rcjetsub_e() const {return m_rcjetsub_e;} + const std::vector<std::vector<float> >& rcjetsub_mv2c10() const {return m_rcjetsub_mv2c10;} + const std::vector<float>& rcjet_tau32_clstr() const {return m_rcjet_tau32_clstr;} + const std::vector<float>& rcjet_tau21_clstr() const {return m_rcjet_tau21_clstr;} + const std::vector<float>& rcjet_tau3_clstr() const {return m_rcjet_tau3_clstr;} + const std::vector<float>& rcjet_tau2_clstr() const {return m_rcjet_tau2_clstr;} + const std::vector<float>& rcjet_tau1_clstr() const {return m_rcjet_tau1_clstr;} + const std::vector<float>& rcjet_D2_clstr() const {return m_rcjet_D2_clstr;} + const std::vector<float>& rcjet_ECF1_clstr() const {return m_rcjet_ECF1_clstr;} + const std::vector<float>& rcjet_ECF2_clstr() const {return m_rcjet_ECF2_clstr;} + const std::vector<float>& rcjet_ECF3_clstr() const {return m_rcjet_ECF3_clstr;} + const std::vector<float>& rcjet_d12_clstr() const {return m_rcjet_d12_clstr;} + const std::vector<float>& rcjet_d23_clstr() const {return m_rcjet_d23_clstr;} + const std::vector<float>& rcjet_Qw_clstr() const {return m_rcjet_Qw_clstr;} + const std::vector<float>& rcjet_nconstituent_clstr() const {return m_rcjet_nconstituent_clstr;} + const std::vector<float>& rcjet_gECF332_clstr() const {return m_rcjet_gECF332_clstr;} + const std::vector<float>& rcjet_gECF461_clstr() const {return m_rcjet_gECF461_clstr;} + const std::vector<float>& rcjet_gECF322_clstr() const {return m_rcjet_gECF322_clstr;} + const std::vector<float>& rcjet_gECF331_clstr() const {return m_rcjet_gECF331_clstr;} + const std::vector<float>& rcjet_gECF422_clstr() const {return m_rcjet_gECF422_clstr;} + const std::vector<float>& rcjet_gECF441_clstr() const {return m_rcjet_gECF441_clstr;} + const std::vector<float>& rcjet_gECF212_clstr() const {return m_rcjet_gECF212_clstr;} + const std::vector<float>& rcjet_gECF321_clstr() const {return m_rcjet_gECF321_clstr;} + const std::vector<float>& rcjet_gECF311_clstr() const {return m_rcjet_gECF311_clstr;} + + const std::vector<float>& rcjet_L1_clstr() const {return m_rcjet_L1_clstr;} + const std::vector<float>& rcjet_L2_clstr() const {return m_rcjet_L2_clstr;} + const std::vector<float>& rcjet_L3_clstr() const {return m_rcjet_L3_clstr;} + const std::vector<float>& rcjet_L4_clstr() const {return m_rcjet_L4_clstr;} + const std::vector<float>& rcjet_L5_clstr() const {return m_rcjet_L5_clstr;} + + //met + const float& met_met() const {return m_met_met;} + const float& met_phi() const {return m_met_phi;} + + ///KLFitter + const short& klfitter_selected() const {return m_klfitter_selected;} + /// Selection + const std::vector<std::string> klfitter_selection() const {return m_klfitter_selection;} + /// Error flags + const std::vector<short>& klfitter_minuitDidNotConverge() const {return m_klfitter_minuitDidNotConverge;} + const std::vector<short>& klfitter_fitAbortedDueToNaN() const {return m_klfitter_fitAbortedDueToNaN;} + const std::vector<short>& klfitter_atLeastOneFitParameterAtItsLimit() const {return m_klfitter_atLeastOneFitParameterAtItsLimit;} + const std::vector<short>& klfitter_invalidTransferFunctionAtConvergence() const {return m_klfitter_invalidTransferFunctionAtConvergence;} + /// Global result + const std::vector<unsigned int>& klfitter_bestPermutation() const {return m_klfitter_bestPermutation;} + const std::vector<float>& klfitter_logLikelihood() const {return m_klfitter_logLikelihood;} + const std::vector<float>& klfitter_eventProbability() const {return m_klfitter_eventProbability;} + const std::vector<unsigned int>& klfitter_parameters_size() const {return m_klfitter_parameters_size;} + const std::vector<std::vector<double> >& klfitter_parameters() const {return m_klfitter_parameters;} + const std::vector<std::vector<double> >& klfitter_parameterErrors() const {return m_klfitter_parameterErrors;} + /// Model + const std::vector<float>& klfitter_model_bhad_pt() const {return m_klfitter_model_bhad_pt;} + const std::vector<float>& klfitter_model_bhad_eta() const {return m_klfitter_model_bhad_eta;} + const std::vector<float>& klfitter_model_bhad_phi() const {return m_klfitter_model_bhad_phi;} + const std::vector<float>& klfitter_model_bhad_E() const {return m_klfitter_model_bhad_E;} + const std::vector<unsigned int>& klfitter_model_bhad_jetIndex() const {return m_klfitter_model_bhad_jetIndex;} + const std::vector<float>& klfitter_model_blep_pt() const {return m_klfitter_model_blep_pt;} + const std::vector<float>& klfitter_model_blep_eta() const {return m_klfitter_model_blep_eta;} + const std::vector<float>& klfitter_model_blep_phi() const {return m_klfitter_model_blep_phi;} + const std::vector<float>& klfitter_model_blep_E() const {return m_klfitter_model_blep_E;} + const std::vector<unsigned int>& klfitter_model_blep_jetIndex() const {return m_klfitter_model_blep_jetIndex;} + const std::vector<float>& klfitter_model_lq1_pt() const {return m_klfitter_model_lq1_pt;} + const std::vector<float>& klfitter_model_lq1_eta() const {return m_klfitter_model_lq1_eta;} + const std::vector<float>& klfitter_model_lq1_phi() const {return m_klfitter_model_lq1_phi;} + const std::vector<float>& klfitter_model_lq1_E() const {return m_klfitter_model_lq1_E;} + const std::vector<unsigned int>& klfitter_model_lq1_jetIndex() const {return m_klfitter_model_lq1_jetIndex;} + const std::vector<float>& klfitter_model_lq2_pt() const {return m_klfitter_model_lq2_pt;} + const std::vector<float>& klfitter_model_lq2_eta() const {return m_klfitter_model_lq2_eta;} + const std::vector<float>& klfitter_model_lq2_phi() const {return m_klfitter_model_lq2_phi;} + const std::vector<float>& klfitter_model_lq2_E() const {return m_klfitter_model_lq2_E;} + const std::vector<unsigned int>& klfitter_model_lq2_jetIndex() const {return m_klfitter_model_lq2_jetIndex;} + const std::vector<float>& klfitter_model_Higgs_b1_pt() const {return m_klfitter_model_Higgs_b1_pt;} + const std::vector<float>& klfitter_model_Higgs_b1_eta() const {return m_klfitter_model_Higgs_b1_eta;} + const std::vector<float>& klfitter_model_Higgs_b1_phi() const {return m_klfitter_model_Higgs_b1_phi;} + const std::vector<float>& klfitter_model_Higgs_b1_E() const {return m_klfitter_model_Higgs_b1_E;} + const std::vector<unsigned int>& klfitter_model_Higgs_b1_jetIndex() const {return m_klfitter_model_Higgs_b1_jetIndex;} + const std::vector<float>& klfitter_model_Higgs_b2_pt() const {return m_klfitter_model_Higgs_b2_pt;} + const std::vector<float>& klfitter_model_Higgs_b2_eta() const {return m_klfitter_model_Higgs_b2_eta;} + const std::vector<float>& klfitter_model_Higgs_b2_phi() const {return m_klfitter_model_Higgs_b2_phi;} + const std::vector<float>& klfitter_model_Higgs_b2_E() const {return m_klfitter_model_Higgs_b2_E;} + const std::vector<unsigned int>& klfitter_model_Higgs_b2_jetIndex() const {return m_klfitter_model_Higgs_b2_jetIndex;} + const std::vector<float>& klfitter_model_lep_pt() const {return m_klfitter_model_lep_pt;} + const std::vector<float>& klfitter_model_lep_eta() const {return m_klfitter_model_lep_eta;} + const std::vector<float>& klfitter_model_lep_phi() const {return m_klfitter_model_lep_phi;} + const std::vector<float>& klfitter_model_lep_E() const {return m_klfitter_model_lep_E;} + const std::vector<float>& klfitter_model_nu_pt() const {return m_klfitter_model_nu_pt;} + const std::vector<float>& klfitter_model_nu_eta() const {return m_klfitter_model_nu_eta;} + const std::vector<float>& klfitter_model_nu_phi() const {return m_klfitter_model_nu_phi;} + const std::vector<float>& klfitter_model_nu_E() const {return m_klfitter_model_nu_E;} + const std::vector<float>& klfitter_model_b_from_top1_pt() const {return m_klfitter_model_b_from_top1_pt;} + const std::vector<float>& klfitter_model_b_from_top1_eta() const {return m_klfitter_model_b_from_top1_eta;} + const std::vector<float>& klfitter_model_b_from_top1_phi() const {return m_klfitter_model_b_from_top1_phi;} + const std::vector<float>& klfitter_model_b_from_top1_E() const {return m_klfitter_model_b_from_top1_E;} + const std::vector<unsigned int>& klfitter_model_b_from_top1_jetIndex() const {return m_klfitter_model_b_from_top1_jetIndex;} + const std::vector<float>& klfitter_model_b_from_top2_pt() const {return m_klfitter_model_b_from_top2_pt;} + const std::vector<float>& klfitter_model_b_from_top2_eta() const {return m_klfitter_model_b_from_top2_eta;} + const std::vector<float>& klfitter_model_b_from_top2_phi() const {return m_klfitter_model_b_from_top2_phi;} + const std::vector<float>& klfitter_model_b_from_top2_E() const {return m_klfitter_model_b_from_top2_E;} + const std::vector<unsigned int>& klfitter_model_b_from_top2_jetIndex() const {return m_klfitter_model_b_from_top2_jetIndex;} + const std::vector<float>& klfitter_model_lj1_from_top1_pt() const {return m_klfitter_model_lj1_from_top1_pt;} + const std::vector<float>& klfitter_model_lj1_from_top1_eta() const {return m_klfitter_model_lj1_from_top1_eta;} + const std::vector<float>& klfitter_model_lj1_from_top1_phi() const {return m_klfitter_model_lj1_from_top1_phi;} + const std::vector<float>& klfitter_model_lj1_from_top1_E() const {return m_klfitter_model_lj1_from_top1_E;} + const std::vector<unsigned int>& klfitter_model_lj1_from_top1_jetIndex() const {return m_klfitter_model_lj1_from_top1_jetIndex;} + const std::vector<float>& klfitter_model_lj2_from_top1_pt() const {return m_klfitter_model_lj2_from_top1_pt;} + const std::vector<float>& klfitter_model_lj2_from_top1_eta() const {return m_klfitter_model_lj2_from_top1_eta;} + const std::vector<float>& klfitter_model_lj2_from_top1_phi() const {return m_klfitter_model_lj2_from_top1_phi;} + const std::vector<float>& klfitter_model_lj2_from_top1_E() const {return m_klfitter_model_lj2_from_top1_E;} + const std::vector<unsigned int>& klfitter_model_lj2_from_top1_jetIndex() const {return m_klfitter_model_lj2_from_top1_jetIndex;} + const std::vector<float>& klfitter_model_lj1_from_top2_pt() const {return m_klfitter_model_lj1_from_top2_pt;} + const std::vector<float>& klfitter_model_lj1_from_top2_eta() const {return m_klfitter_model_lj1_from_top2_eta;} + const std::vector<float>& klfitter_model_lj1_from_top2_phi() const {return m_klfitter_model_lj1_from_top2_phi;} + const std::vector<float>& klfitter_model_lj1_from_top2_E() const {return m_klfitter_model_lj1_from_top2_E;} + const std::vector<unsigned int>& klfitter_model_lj1_from_top2_jetIndex() const {return m_klfitter_model_lj1_from_top2_jetIndex;} + const std::vector<float>& klfitter_model_lj2_from_top2_pt() const {return m_klfitter_model_lj2_from_top2_pt;} + const std::vector<float>& klfitter_model_lj2_from_top2_eta() const {return m_klfitter_model_lj2_from_top2_eta;} + const std::vector<float>& klfitter_model_lj2_from_top2_phi() const {return m_klfitter_model_lj2_from_top2_phi;} + const std::vector<float>& klfitter_model_lj2_from_top2_E() const {return m_klfitter_model_lj2_from_top2_E;} + const std::vector<unsigned int>& klfitter_model_lj2_from_top2_jetIndex() const {return m_klfitter_model_lj2_from_top2_jetIndex;} + + // calculated KLFitter variables for best perm + const float& klfitter_bestPerm_topLep_pt() const {return m_klfitter_bestPerm_topLep_pt;} + const float& klfitter_bestPerm_topLep_eta() const {return m_klfitter_bestPerm_topLep_eta;} + const float& klfitter_bestPerm_topLep_phi() const {return m_klfitter_bestPerm_topLep_phi;} + const float& klfitter_bestPerm_topLep_E() const {return m_klfitter_bestPerm_topLep_E;} + const float& klfitter_bestPerm_topLep_m() const {return m_klfitter_bestPerm_topLep_m;} + const float& klfitter_bestPerm_topHad_pt() const {return m_klfitter_bestPerm_topHad_pt;} + const float& klfitter_bestPerm_topHad_eta() const {return m_klfitter_bestPerm_topHad_eta;} + const float& klfitter_bestPerm_topHad_phi() const {return m_klfitter_bestPerm_topHad_phi;} + const float& klfitter_bestPerm_topHad_E() const {return m_klfitter_bestPerm_topHad_E;} + const float& klfitter_bestPerm_topHad_m() const {return m_klfitter_bestPerm_topHad_m;} + const float& klfitter_bestPerm_ttbar_pt() const {return m_klfitter_bestPerm_ttbar_pt;} + const float& klfitter_bestPerm_ttbar_eta() const {return m_klfitter_bestPerm_ttbar_eta;} + const float& klfitter_bestPerm_ttbar_phi() const {return m_klfitter_bestPerm_ttbar_phi;} + const float& klfitter_bestPerm_ttbar_E() const {return m_klfitter_bestPerm_ttbar_E;} + const float& klfitter_bestPerm_ttbar_m() const {return m_klfitter_bestPerm_ttbar_m;} + // PseudoTop variables + const float& PseudoTop_Reco_ttbar_pt() const {return m_PseudoTop_Reco_ttbar_pt;} + const float& PseudoTop_Reco_ttbar_eta() const {return m_PseudoTop_Reco_ttbar_eta;} + const float& PseudoTop_Reco_ttbar_phi() const {return m_PseudoTop_Reco_ttbar_phi;} + const float& PseudoTop_Reco_ttbar_m() const {return m_PseudoTop_Reco_ttbar_m;} + const float& PseudoTop_Reco_top_had_pt() const {return m_PseudoTop_Reco_top_had_pt;} + const float& PseudoTop_Reco_top_had_eta() const {return m_PseudoTop_Reco_top_had_eta;} + const float& PseudoTop_Reco_top_had_phi() const {return m_PseudoTop_Reco_top_had_phi;} + const float& PseudoTop_Reco_top_had_m() const {return m_PseudoTop_Reco_top_had_m;} + const float& PseudoTop_Reco_top_lep_pt() const {return m_PseudoTop_Reco_top_lep_pt;} + const float& PseudoTop_Reco_top_lep_eta() const {return m_PseudoTop_Reco_top_lep_eta;} + const float& PseudoTop_Reco_top_lep_phi() const {return m_PseudoTop_Reco_top_lep_phi;} + const float& PseudoTop_Reco_top_lep_m() const {return m_PseudoTop_Reco_top_lep_m;} + const float& PseudoTop_Particle_ttbar_pt() const {return m_PseudoTop_Particle_ttbar_pt;} + const float& PseudoTop_Particle_ttbar_eta() const {return m_PseudoTop_Particle_ttbar_eta;} + const float& PseudoTop_Particle_ttbar_phi() const {return m_PseudoTop_Particle_ttbar_phi;} + const float& PseudoTop_Particle_ttbar_m() const {return m_PseudoTop_Particle_ttbar_m;} + const float& PseudoTop_Particle_top_had_pt() const {return m_PseudoTop_Particle_top_had_pt;} + const float& PseudoTop_Particle_top_had_eta() const {return m_PseudoTop_Particle_top_had_eta;} + const float& PseudoTop_Particle_top_had_phi() const {return m_PseudoTop_Particle_top_had_phi;} + const float& PseudoTop_Particle_top_had_m() const {return m_PseudoTop_Particle_top_had_m;} + const float& PseudoTop_Particle_top_lep_pt() const {return m_PseudoTop_Particle_top_lep_pt;} + const float& PseudoTop_Particle_top_lep_eta() const {return m_PseudoTop_Particle_top_lep_eta;} + const float& PseudoTop_Particle_top_lep_phi() const {return m_PseudoTop_Particle_top_lep_phi;} + const float& PseudoTop_Particle_top_lep_m() const {return m_PseudoTop_Particle_top_lep_m;} + + //MC + const std::vector<float>& mc_pt() const {return m_mc_pt;} + const std::vector<float>& mc_eta() const {return m_mc_eta;} + const std::vector<float>& mc_phi() const {return m_mc_phi;} + const std::vector<float>& mc_e() const {return m_mc_e;} + const std::vector<double>& mc_charge() const {return m_mc_charge;} + const std::vector<int>& mc_pdgId() const {return m_mc_pdgId;} + const std::vector<int>& mc_status() const {return m_mc_status;} + const std::vector<int>& mc_barcode() const {return m_mc_barcode;} + + //PDFInfo + const std::vector<float>& PDFinfo_X1() const {return m_PDFinfo_X1;} + const std::vector<float>& PDFinfo_X2() const {return m_PDFinfo_X2;} + const std::vector<int>& PDFinfo_PDGID1() const {return m_PDFinfo_PDGID1;} + const std::vector<int>& PDFinfo_PDGID2() const {return m_PDFinfo_PDGID2;} + const std::vector<float>& PDFinfo_Q() const {return m_PDFinfo_Q;} + const std::vector<float>& PDFinfo_XF1() const {return m_PDFinfo_XF1;} + const std::vector<float>& PDFinfo_XF2() const {return m_PDFinfo_XF2;} + + //the on-the-fly computed generator weights stored in EventInfo + const std::vector<float>& mc_generator_weights() const {return m_mc_generator_weights;} + + //Extra variables for Particle Level (bare lepton kinematics and b-Hadron + //tagging information). + const std::vector<float>& el_pt_bare() const {return m_el_pt_bare;} + const std::vector<float>& el_eta_bare() const {return m_el_eta_bare;} + const std::vector<float>& el_phi_bare() const {return m_el_phi_bare;} + const std::vector<float>& el_e_bare() const {return m_el_e_bare;} + const std::vector<float>& mu_pt_bare() const {return m_mu_pt_bare;} + const std::vector<float>& mu_eta_bare() const {return m_mu_eta_bare;} + const std::vector<float>& mu_phi_bare() const {return m_mu_phi_bare;} + const std::vector<float>& mu_e_bare() const {return m_mu_e_bare;} + const std::vector<int>& jet_Ghosts_BHadron_Final_Count() const {return m_jet_Ghosts_BHadron_Final_Count;} + const std::vector<int>& jet_Ghosts_CHadron_Final_Count() const {return m_jet_Ghosts_CHadron_Final_Count;} + const std::vector<int>& ljet_Ghosts_BHadron_Final_Count() const {return m_ljet_Ghosts_BHadron_Final_Count;} + const std::vector<int>& ljet_Ghosts_CHadron_Final_Count() const {return m_ljet_Ghosts_CHadron_Final_Count;} + const std::vector<std::vector<int> >& rcjetsub_Ghosts_BHadron_Final_Count() const {return m_rcjetsub_Ghosts_BHadron_Final_Count;} + const std::vector<std::vector<int> >& rcjetsub_Ghosts_CHadron_Final_Count() const {return m_rcjetsub_Ghosts_CHadron_Final_Count;} // Truth tree inserted variables // This can be expanded as required // This is just a first pass at doing this sort of thing - std::unordered_map<std::string,int*> m_extraTruthVars_int; - std::unordered_map<std::string,float*> m_extraTruthVars_float; + const std::unordered_map<std::string, int*>& extraTruthVars_int() const {return m_extraTruthVars_int;} + + // Prompt lepton definition for event saver + std::pair<bool, bool> isPromptElectron(int type, int origin, int egMotherType, int egMotherOrigin, int egMotherPdgId, int RecoCharge); + bool isPromptMuon(int type, int origin); - ClassDef(top::EventSaverFlatNtuple, 0); -}; + int filterBranches(const top::TreeManager*, const std::string& variable); + ClassDefOverride(top::EventSaverFlatNtuple, 0); + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverxAOD.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverxAOD.h index 9bd316923938..cd17afeead83 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverxAOD.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverxAOD.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTSAVERXAOD_H_ #define EVENTSAVERXAOD_H_ @@ -13,14 +13,12 @@ class TFile; namespace top { - /** * @brief Write out the selected events in xAOD format. At some point this will * be the future. But probably not right now. Still too many missing features. */ -class EventSaverxAOD : public top::EventSaverBase , public asg::AsgTool { - -public: + class EventSaverxAOD: public top::EventSaverBase, public asg::AsgTool { + public: /** * @brief Kept simple, set the output container prefix (so they have a * different name to the input containers). @@ -46,11 +44,12 @@ public: * EventInfo. e.g. the branch that tells you if an event passed a certain * selection. If you add it here, it'll be written to the output file. */ - virtual void initialize(std::shared_ptr<top::TopConfig> config, TFile* file, const std::vector<std::string>& extraBranches); - + virtual void initialize(std::shared_ptr<top::TopConfig> config, TFile* file, + const std::vector<std::string>& extraBranches); + //Keep the asg::AsgTool happy - virtual StatusCode initialize(){return StatusCode::SUCCESS;} - + virtual StatusCode initialize() {return StatusCode::SUCCESS;} + /** * @brief Save an event. * @@ -73,8 +72,7 @@ public: ///xAOD needs to write some more stuff to the file at the end of a job virtual void finalize(); - -private: + private: ///Name to prepend to the output containers const std::string m_prefix; @@ -85,8 +83,7 @@ private: TFile* m_outputFile; ClassDef(top::EventSaverxAOD, 0); -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverxAODNext.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverxAODNext.h index ff2257b9f749..9aa702bf8dd3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverxAODNext.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSaverxAODNext.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTSAVERXAODNEXT_H_ #define EVENTSAVERXAODNEXT_H_ @@ -13,76 +13,72 @@ class TFile; namespace top { - /** - * @brief Write out the selected events in xAOD format. - * Next generation xAOD output - still in development - */ - class EventSaverxAODNext : public top::EventSaverBase , public asg::AsgMetadataTool { - - public: - - EventSaverxAODNext(); - - virtual ~EventSaverxAODNext(); - - /** - * @brief This does some configuration of the output file. It also keeps track - * of which branches should be saved. - * - * You surely don't need all the branches, but if you do remove the - * corresponding line. - * - * We can't do much in the constructor, like I would like, because we're - * letting root make this. So instead we have a function here. - * - * @param config The top::TopConfig object that contains lots of settings and - * stuff. - * @param file The output TFile that you want to save things to. - * @param extraBranches List of extra branches that (currently) are attached to - * EventInfo. e.g. the branch that tells you if an event passed a certain - * selection. If you add it here, it'll be written to the output file. + * @brief Write out the selected events in xAOD format. + * Next generation xAOD output - still in development + */ + class EventSaverxAODNext: public top::EventSaverBase, public asg::AsgMetadataTool { + public: + EventSaverxAODNext(); + + virtual ~EventSaverxAODNext(); + + /** + * @brief This does some configuration of the output file. It also keeps track + * of which branches should be saved. + * + * You surely don't need all the branches, but if you do remove the + * corresponding line. + * + * We can't do much in the constructor, like I would like, because we're + * letting root make this. So instead we have a function here. + * + * @param config The top::TopConfig object that contains lots of settings and + * stuff. + * @param file The output TFile that you want to save things to. + * @param extraBranches List of extra branches that (currently) are attached to + * EventInfo. e.g. the branch that tells you if an event passed a certain + * selection. If you add it here, it'll be written to the output file. */ - virtual void initialize(std::shared_ptr<top::TopConfig> config, TFile* file, const std::vector<std::string>& extraBranches); - - //Keep the asg::AsgTool happy - virtual StatusCode initialize(){return StatusCode::SUCCESS;} - - - virtual void saveEventToxAOD(); - - ///xAOD needs to write some more stuff to the file at the end of a job - virtual void finalize(); - - private: - ///We need access to the configuration file to get the container names. - std::shared_ptr<top::TopConfig> m_config; - - ///We need to hold on to the output file - TFile* m_outputFile; - - bool m_saveAllObjects; - - // helper typedef - typedef std::map<std::size_t,std::map<unsigned int,unsigned int>> ThinningMap_t; - typedef ThinningMap_t::const_iterator ThinningMap_Itr; - - std::shared_ptr<ThinningMap_t> savePhotons(const bool saveEventObjects); - std::shared_ptr<ThinningMap_t> saveElectrons(const bool saveEventObjects); - std::shared_ptr<ThinningMap_t> saveMuons(const bool saveEventObjects); - std::shared_ptr<ThinningMap_t> saveTaus(const bool saveEventObjects); - std::shared_ptr<ThinningMap_t> saveJets(const bool saveEventObjects); - std::shared_ptr<ThinningMap_t> saveLargeRJets(const bool saveEventObjects); - std::shared_ptr<ThinningMap_t> saveTrackJets(const bool saveEventObjects); - - std::vector<unsigned int> thinObjectSelection(const std::size_t hashValue , - const std::vector<unsigned int>& objectList , - const std::shared_ptr<ThinningMap_t> thinningMap) const; - - - ClassDef(top::EventSaverxAODNext, 0); - }; + virtual void initialize(std::shared_ptr<top::TopConfig> config, TFile* file, + const std::vector<std::string>& extraBranches); + + //Keep the asg::AsgTool happy + virtual StatusCode initialize() {return StatusCode::SUCCESS;} + + + virtual void saveEventToxAOD(); + + ///xAOD needs to write some more stuff to the file at the end of a job + virtual void finalize(); + private: + ///We need access to the configuration file to get the container names. + std::shared_ptr<top::TopConfig> m_config; + + ///We need to hold on to the output file + TFile* m_outputFile; + bool m_saveAllObjects; + + // helper typedef + typedef std::map<std::size_t, std::map<unsigned int, unsigned int> > ThinningMap_t; + typedef ThinningMap_t::const_iterator ThinningMap_Itr; + + std::shared_ptr<ThinningMap_t> savePhotons(const bool saveEventObjects); + std::shared_ptr<ThinningMap_t> saveElectrons(const bool saveEventObjects); + std::shared_ptr<ThinningMap_t> saveMuons(const bool saveEventObjects); + std::shared_ptr<ThinningMap_t> saveTaus(const bool saveEventObjects); + std::shared_ptr<ThinningMap_t> saveJets(const bool saveEventObjects); + std::shared_ptr<ThinningMap_t> saveLargeRJets(const bool saveEventObjects); + std::shared_ptr<ThinningMap_t> saveTrackJets(const bool saveEventObjects); + + std::vector<unsigned int> thinObjectSelection(const std::size_t hashValue, + const std::vector<unsigned int>& objectList, + const std::shared_ptr<ThinningMap_t> thinningMap) const; + + + ClassDef(top::EventSaverxAODNext, 0); + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSelection.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSelection.h index 116fa78daa2c..a5d54b3f4dcc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSelection.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSelection.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTSELECTION_H_ #define EVENTSELECTION_H_ @@ -34,8 +34,8 @@ namespace top { * of events passing each cut. It is also responsible for writing out the * 4-vectors in the output file if the user so wished. */ -class EventSelection final { -public: + class EventSelection final { + public: /** * @brief Construct using a vector of cuts. * @@ -46,7 +46,9 @@ public: * It also sets up a histogram which contains all the cuts on the x-axis * and each bin is the number of events passing a cut (in order). */ - EventSelection(const std::string& name, const std::vector<std::string>& cutNames, TFile* outputFile, const std::vector<std::unique_ptr<top::ToolLoaderBase>>& toolLoaders,std::shared_ptr<top::TopConfig> config, EL::Worker* wk); + EventSelection(const std::string& name, const std::vector<std::string>& cutNames, TFile* outputFile, + const std::vector<std::unique_ptr<top::ToolLoaderBase> >& toolLoaders, + std::shared_ptr<top::TopConfig> config, EL::Worker* wk); /** * @brief Does not do anything @@ -71,25 +73,25 @@ public: /** * @brief Assignment is not allowed. */ - EventSelection& operator=(const EventSelection&) = delete; - - /** + EventSelection& operator = (const EventSelection&) = delete; + + /** * @brief Count the number of initial events */ - virtual void countInitial(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) const; - /** + virtual void countInitial(const float mcEventWeight, const float pileupWeight, const float zvtxWeight) const; + /** * @brief Count the number of events passing GRL */ - virtual void countGRL(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) const; - /** + virtual void countGRL(const float mcEventWeight, const float pileupWeight, const float zvtxWeight) const; + /** * @brief Count the number of events passing Good Calo */ - virtual void countGoodCalo(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) const; + virtual void countGoodCalo(const float mcEventWeight, const float pileupWeight, const float zvtxWeight) const; /** * @brief Count the number of events passing Primary Vertex */ - virtual void countPrimaryVertex(const float mcEventWeight,const float pileupWeight,const float zvtxWeight) const; - + virtual void countPrimaryVertex(const float mcEventWeight, const float pileupWeight, const float zvtxWeight) const; + /** * @brief Apply the selection for each event. * @@ -162,7 +164,7 @@ public: * @return The list of configurations */ std::vector<std::string> GetFakesMMConfigs() const; - + /** * @brief Tells if the event should be saved if it passes this selection * @@ -170,15 +172,14 @@ public: * */ bool ToBeSaved() const {return m_toBeSaved;}; - -private: + private: /** * @brief Print a cutflow showing the number of events passing each cut. */ virtual void printCuts(); ///Vector of all the tools that will be used in the analysis. - std::vector<std::unique_ptr<EventSelectorBase>> m_allCuts; + std::vector<std::unique_ptr<EventSelectorBase> > m_allCuts; ///The cutflow histogram filled by the tool. mutable TH1D* m_cutflow; @@ -214,6 +215,7 @@ private: ///The particle level cutflow histogram filled by the tool. mutable TH1D* m_cutflowParticleLevel; + mutable TH1D* m_cutflowParticleLevelMCWeights; ///The upgrade level cutflow histogram filled by the tool. mutable TH1D* m_cutflowUpgradeLevel; @@ -231,12 +233,14 @@ private: /// std::shared_ptr<TopConfig> m_config; - ///Scale factors - std::unique_ptr<ScaleFactorRetriever> m_sfRetriever; + ///Scale factors + ScaleFactorRetriever* m_sfRetriever; + /// Function to setup the tool in one place + void initialiseTopScaleFactorRetriever(std::shared_ptr<TopConfig> config); // Nominal hash value - std::size_t m_nominalHashValue; - + std::size_t m_nominalHashValue; + // Does this selection contain initial and GRL? // If so, what are their positions in the cut flow? bool m_containsInitial; @@ -247,13 +251,12 @@ private: unsigned int m_positionGRL; unsigned int m_positionGoodCalo; unsigned int m_positionPrimaryVertex; - + // If true, event will be saved if it passes this selection // If false, event will only be saved if it passes another selection // If an event is saved, the flags of all selections (those passed and those not passed) are saved bool m_toBeSaved; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSelectionManager.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSelectionManager.h index 53f793c3f333..3da71c551e44 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSelectionManager.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/EventSelectionManager.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTSELECTIONMANAGER_H_ #define EVENTSELECTIONMANAGER_H_ @@ -17,7 +17,7 @@ namespace EL { class Worker; } -namespace xAOD{ +namespace xAOD { class SystematicEvent; } @@ -27,7 +27,7 @@ namespace top { class ParticleLevelEvent; } -namespace top{ +namespace top { /** * @brief Maybe you want to run multiple selections (e+jets, mu+jets) on the * same input files at the same time. This class helps. @@ -37,8 +37,8 @@ namespace top{ * selections at the same time on the same input files. You could imagine * running ee, mumu, emu, e+jets and mu+jets. */ -class EventSelectionManager { -public: + class EventSelectionManager { + public: /** * @brief Loads the file and initialises all the relevant tools. * @@ -47,7 +47,9 @@ public: * string format * @param outputFile Output file for attaching plots to, etc. */ - explicit EventSelectionManager(const std::vector<SelectionConfigurationData>& selectionConfigData, TFile* outputFile, const std::string& toolLoaderNames, std::shared_ptr<top::TopConfig> config,EL::Worker* wk = nullptr); + explicit EventSelectionManager(const std::vector<SelectionConfigurationData>& selectionConfigData, + TFile* outputFile, const std::string& toolLoaderNames, + std::shared_ptr<top::TopConfig> config, EL::Worker* wk = nullptr); /** * @brief Does not need to do anything @@ -61,24 +63,24 @@ public: EventSelectionManager() = delete; EventSelectionManager(const EventSelectionManager& rhs) = delete; - EventSelectionManager& operator=(const EventSelectionManager& rhs) = delete; - + EventSelectionManager& operator = (const EventSelectionManager& rhs) = delete; + /** * @brief Count the number of initial events */ - virtual void countInitial(const float mcEventWeight,const float pileupWeight,const float zvtxWeight); + virtual void countInitial(const float mcEventWeight, const float pileupWeight, const float zvtxWeight); /** * @brief Count the number of events passing GRL */ - virtual void countGRL(const float mcEventWeight,const float pileupWeight,const float zvtxWeight); + virtual void countGRL(const float mcEventWeight, const float pileupWeight, const float zvtxWeight); /** * @brief Count the number of events passing Good Calo */ - virtual void countGoodCalo(const float mcEventWeight,const float pileupWeight,const float zvtxWeight); + virtual void countGoodCalo(const float mcEventWeight, const float pileupWeight, const float zvtxWeight); /** * @brief Count the number of events passing Primary Vertex */ - virtual void countPrimaryVertex(const float mcEventWeight,const float pileupWeight,const float zvtxWeight); + virtual void countPrimaryVertex(const float mcEventWeight, const float pileupWeight, const float zvtxWeight); /** * @brief Run through the event selections for each event. @@ -95,7 +97,7 @@ public: * @return Returns true if the event passes at least one selection for which * SAVE is requested (for saving events to trees). */ - virtual bool apply(top::Event& event,const xAOD::SystematicEvent& currentSystematic); + virtual bool apply(top::Event& event, const xAOD::SystematicEvent& currentSystematic); /*! * @brief Execute the event selection using the Particle Level data. @@ -144,7 +146,7 @@ public: * for each selection is added (this is stored in event info). */ virtual void addExtraBranches(std::vector<std::string>& extraBranchList); - + /** * @brief Gives you the lists of the Fakes MM configurations associated to a selection. * @@ -153,12 +155,10 @@ public: * @param selection The requested selection. */ std::vector<std::string> GetFakesMMConfigs(std::string selection) const; - -private: + private: ///A vector of EventSelection objects, for doing fancy things std::vector<top::EventSelection> m_selections; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/MsgCategory.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/MsgCategory.h new file mode 100644 index 000000000000..4a75fbb02458 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/MsgCategory.h @@ -0,0 +1,12 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#ifndef TOPANALYSIS_MSG_CATEGORY_H_ +#define TOPANALYSIS_MSG_CATEGORY_H_ +#include <AsgMessaging/MessageCheck.h> + +// define custom message source for top-xaod and related tools +// this ensures we get "top-xaod" in the messages to know where they're coming from +ANA_MSG_HEADER(TopAnalysis) + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/ObjectLoaderBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/ObjectLoaderBase.h index 08984fddff5a..792d0af3dfa0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/ObjectLoaderBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/ObjectLoaderBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef OBJECTLOADERBASE_H_ #define OBJECTLOADERBASE_H_ @@ -9,8 +9,8 @@ #include <memory> namespace top { -class TopConfig; -class TopObjectSelection; + class TopConfig; + class TopObjectSelection; /** * @brief People seem to want to be able to configure the objects used in their @@ -19,8 +19,8 @@ class TopObjectSelection; * selection object then this can be deleted. * */ -class ObjectLoaderBase { -public: + class ObjectLoaderBase { + public: /** * @brief This will inherit from this, but it doesn't do anything really. */ @@ -37,8 +37,7 @@ public: virtual top::TopObjectSelection* init(std::shared_ptr<top::TopConfig> topConfig) = 0; ClassDef(top::ObjectLoaderBase, 0) -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/ObjectLoaderStandardCuts.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/ObjectLoaderStandardCuts.h index cbcf30c59cfe..7f5ba3453f32 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/ObjectLoaderStandardCuts.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/ObjectLoaderStandardCuts.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef OBJECTLOADERSTANDARDCUTS_H_ #define OBJECTLOADERSTANDARDCUTS_H_ @@ -8,7 +8,6 @@ #include "TopAnalysis/ObjectLoaderBase.h" namespace top { - /** * @brief This loads our "standard" object selection used in the top group. * @@ -17,9 +16,8 @@ namespace top { * write your own in a separate library then when you change release it wont * be a big deal). */ -class ObjectLoaderStandardCuts : public ObjectLoaderBase { -public: - + class ObjectLoaderStandardCuts: public ObjectLoaderBase { + public: /** * @brief Setup the cuts. Probably easiest if you look at the code, no? * @@ -30,8 +28,7 @@ public: top::TopObjectSelection* init(std::shared_ptr<top::TopConfig> topConfig); ClassDef(top::ObjectLoaderStandardCuts, 0) -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/Tools.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/Tools.h index 9833c9d8f03b..613d72b399c6 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/Tools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/Tools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPTOOLS_H__ #define TOPTOOLS_H__ @@ -10,10 +10,13 @@ #include "xAODRootAccess/TEvent.h" +#include "xAODCutFlow/CutBookkeeper.h" +#include "xAODCutFlow/CutBookkeeperContainer.h" + #include "TopConfiguration/TopConfig.h" /** - * @file TopAnalysis/Tools.h + * @file Tools.h * * Some tools to make life in the xAOD world a bit easier. Including ways * to initialise, guess the best "mode" to open an xAOD with, load cuts, list @@ -21,8 +24,8 @@ */ namespace top { -class TopObjectSelection; -class EventSaverBase; + class TopObjectSelection; + class EventSaverBase; /** * @brief A little wrapper for the xAOD tools. Also turns enabled the failure @@ -31,7 +34,7 @@ class EventSaverBase; * @param failOnUnchecked Terminate the job on unchecked status codes by * default. */ -void xAODInit(bool failOnUnchecked = true); + void xAODInit(bool failOnUnchecked = true); /** * @brief Sometimes we need to know if we're running on a primary xAOD or a @@ -45,7 +48,7 @@ void xAODInit(bool failOnUnchecked = true); * @param inputFile A pointer to the input file * @return True if this is a primary xAOD */ -bool isFilePrimaryxAOD(TFile* inputFile); + bool isFilePrimaryxAOD(TFile* inputFile); /** * @brief Some of our things need to know if the events are MC or data before @@ -56,21 +59,33 @@ bool isFilePrimaryxAOD(TFile* inputFile); * @param eventInfoName Name of the EventInfo container in the xAOD * @return True if MC simulation, false for data */ -bool isFileSimulation(TFile* inputFile, const std::string& eventInfoName); + bool isFileSimulation(TFile* inputFile, const std::string& eventInfoName); + +/** + * @brief For fallback cases when metadata is broken in dxAOD, we need to know + * how many MC generator weights are stored in the MC sample. This is needed + * to determine, whether there is an unambiguous choice of nominal weight (e.g. + * only one weight in sample), or if we can't conclusively tell which one it is. + * + * @param inputFile A pointer to the input file + * @param eventInfoName Name of the EventInfo container in the xAOD + * @return Size of vector of MC generator weights + */ + size_t MCweightsSize(TFile* inputFile, const std::string& eventInfoName); -bool isTruthDxAOD(TFile* inputFile); + bool isTruthDxAOD(TFile* inputFile); -unsigned int getDSID(TFile* inputFile, const std::string& eventInfoName); + unsigned int getDSID(TFile* inputFile, const std::string& eventInfoName); -/** +/** * @brief Some of our things need to know if the events are AFII or FullSim - * for certain systematics. - * - * @param inputFile A pointer to the input file - * @param eventInfoName Name of the EventInfo container in the xAOD - * @return True if fast simulation, false for FullSim + * for certain systematics. + * + * @param inputFile A pointer to the input file + * @param eventInfoName Name of the EventInfo container in the xAOD + * @return True if fast simulation, false for FullSim */ -bool isFileFastSim(TFile* inputFile); + bool isFileFastSim(TFile* inputFile); /** * @brief Function to determine the derivation type using string manipulation @@ -80,8 +95,39 @@ bool isFileFastSim(TFile* inputFile); * @return string with the derivation stream name */ -std::string getDerivationStream(TFile* inputFile); + std::string getDerivationStream(TFile* inputFile); + +/** + * @brief Search bookkeepers for ones matching AllExecutedEvents, and which + * originate from AOD before skimming. + * + * @param cutBookKeepers Container with bookkeepers + * @param names Vector of names of the selected bookkeepers + * @param sumW Vector of sum of weights of the selected bookkeepers + * @param isHLLHC Whether this is a HLLHC ugprade sample, it uses different stream for bookkeepers + */ + void parseCutBookkeepers(const xAOD::CutBookkeeperContainer *cutBookKeepers, + std::vector<std::string> &names, std::vector<float>& sumW, const bool isHLLHC=false); + +/** + * @brief Get raw number of events before skimming from "AllExecutedEvents" bookkeeper + * + * @param cutBookKeepers Container with CutBookkeepers + * @param isHLLHC Whether this is a HLLHC ugprade sample, it uses different stream for bookkeepers + * + * @return number of raw events before skimming + */ + ULong64_t getRawEventsBookkeeper(const xAOD::CutBookkeeperContainer *cutBookKeepers, + const bool isHLLHC=false); +/** + * @brief Rename CutBookkeeper names according to MC generator weight names reported by PMGTruthWeightTool + * + * @param bookkeeper_names Vector of original AllExecutedEvents* bookkeeper names + * @param pmg_weight_names Vector with MC generator weight names from PMGTruthWeightTool + */ + void renameCutBookkeepers(std::vector<std::string>& bookkepeer_names, + const std::vector<std::string>& pmg_weight_names); /** * @brief xAODs can be accessed in class or branch access mode. Guess 'the best' @@ -105,7 +151,7 @@ std::string getDerivationStream(TFile* inputFile); * * @return BranchAccess (preferred) or ClassAccess if the test fails. */ -xAOD::TEvent::EAuxMode guessAccessMode(const std::string& filename, const std::string& electronCollectionName); + xAOD::TEvent::EAuxMode guessAccessMode(const std::string& filename, const std::string& electronCollectionName); /** * @brief Load the file and make a vector of the cuts to pass on to the @@ -116,7 +162,7 @@ xAOD::TEvent::EAuxMode guessAccessMode(const std::string& filename, const std::s * * @return a vector with one cut-tool and configuration per line. */ -std::vector<std::string> loadCuts(const std::string& filename); + std::vector<std::string> loadCuts(const std::string& filename); /** * @brief Given a filename for a text file, parse it and extract a list of root @@ -128,7 +174,7 @@ std::vector<std::string> loadCuts(const std::string& filename); * @param filename The text file that we want to parse. * @return A vector of filenames. */ -std::vector<std::string> fileList(const std::string& filename); + std::vector<std::string> fileList(const std::string& filename); /** * @brief Open each file in the vector and get the number of events in it. @@ -141,7 +187,7 @@ std::vector<std::string> fileList(const std::string& filename); * @param filenames A vector of filenames to check. * @return The total yield for all files. */ -unsigned int checkFiles(const std::vector<std::string>& filenames); + size_t checkFiles(const std::vector<std::string>& filenames); /** * @brief So that we can load external libraries with (1) extra event selection @@ -153,7 +199,7 @@ unsigned int checkFiles(const std::vector<std::string>& filenames); * @param libraryNames The name of the library, for exmample * libTopEventSelectionTools */ -void loadLibraries(const std::string& libraryNames); + void loadLibraries(const std::string& libraryNames); /** * @brief Users may want to define (and load!) their own object selection. Once @@ -168,7 +214,7 @@ void loadLibraries(const std::string& libraryNames); * * @return The object selection pointer. */ -top::TopObjectSelection* loadObjectSelection(std::shared_ptr<top::TopConfig> config); + top::TopObjectSelection* loadObjectSelection(std::shared_ptr<top::TopConfig> config); /** * @brief Users may also want to write out custom ntuples / xAODs. This too @@ -181,8 +227,19 @@ top::TopObjectSelection* loadObjectSelection(std::shared_ptr<top::TopConfig> con * @return If everything works, then a pointer to the event saver object. * Otherwise the program should end and tell people why. */ -top::EventSaverBase* loadEventSaver(std::shared_ptr<top::TopConfig> config); + top::EventSaverBase* loadEventSaver(std::shared_ptr<top::TopConfig> config); + +/** + * @brief This function will be used to load the metadata object and pull information + * from it. We will then need to look at storing the info in TopConfig + * + * @param inputFile Include a single TFile which we load and read + * @param config Pass in the config, before it is fixed, so that we can add info + * + * @return If successful, return true, else return false + */ + bool readMetaData(TFile* inputFile, std::shared_ptr<top::TopConfig> config); } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMPFlowDatatest.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMPFlowDatatest.py new file mode 100755 index 000000000000..5b3f7d155342 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMPFlowDatatest.py @@ -0,0 +1,28 @@ +#! /usr/bin/env python +# This script is designed to be used as a quick runtime ctest in the CI framework +# We use python to better handle getting our validation cutfile which should be stable +# We will augment the NEvents line in our cutfile to limit the job +# This is primarily to catch any runtime changes introduced before they are merged + +from PathResolver import PathResolver +from CI_test import CITest +import sys,ROOT + +cutfilename = "validation-cuts-pflow.txt" +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +returnCode = CITest("TOPQ1 DATA", + cutfilename, + cutfilepath, + "/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/dev/AnalysisTop/ContinuousIntegration/Data/p4173/"+ + "data16_13TeV.AllYear.physics_Main.PhysCont.DAOD_TOPQ1.grp16_v01_p4173/DAOD_TOPQ1.21542408._000018.pool.root.1", + [("#NEvents.*","NEvents 3000")]) + +if returnCode != 0: + print "Error in EMPFlow TOPQ1 Data" + sys.exit(returnCode) + +# -- Return 0 as all tests were successful -- # +sys.exit(0) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMPFlowMCtest.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMPFlowMCtest.py new file mode 100755 index 000000000000..ed62c91a15df --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMPFlowMCtest.py @@ -0,0 +1,29 @@ +#! /usr/bin/env python +# This script is designed to be used as a quick runtime ctest in the CI framework +# We use python to better handle getting our validation cutfile which should be stable +# We will augment the NEvents line in our cutfile to limit the job +# This is primarily to catch any runtime changes introduced before they are merged + +from PathResolver import PathResolver +from CI_test import CITest +import sys,ROOT + +cutfilename = "validation-cuts-pflow.txt" +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +returnCode = CITest("TOPQ1 MC", + cutfilename, + cutfilepath, + "/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/dev/AnalysisTop/ContinuousIntegration/MC/p4174/"+ + "mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_s3126_r9364_p4174/"+ + "test.pool.root", + [("#NEvents.*","NEvents 100")]) + +if returnCode != 0: + print "Error in EMPFlow TOPQ1 MC" + sys.exit(returnCode) + +# -- Return 0 as all tests were successful -- # +sys.exit(0) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMTopoDatatest.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMTopoDatatest.py new file mode 100755 index 000000000000..cab12b1c4043 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMTopoDatatest.py @@ -0,0 +1,28 @@ +#! /usr/bin/env python +# This script is designed to be used as a quick runtime ctest in the CI framework +# We use python to better handle getting our validation cutfile which should be stable +# We will augment the NEvents line in our cutfile to limit the job +# This is primarily to catch any runtime changes introduced before they are merged + +from PathResolver import PathResolver +from CI_test import CITest +import sys,ROOT + +cutfilename = "validation-cuts.txt" +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +returnCode = CITest("TOPQ1 DATA", + cutfilename, + cutfilepath, + "/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/dev/AnalysisTop/ContinuousIntegration/Data/p4173/"+ + "data16_13TeV.AllYear.physics_Main.PhysCont.DAOD_TOPQ1.grp16_v01_p4173/DAOD_TOPQ1.21542408._000018.pool.root.1", + [("#NEvents.*","NEvents 3000")]) + +if returnCode != 0: + print "Error in EMTopo TOPQ1 Data" + sys.exit(returnCode) + +# -- Return 0 as all tests were successful -- # +sys.exit(0) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMTopoMCtest.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMTopoMCtest.py new file mode 100755 index 000000000000..0c0f9acccb6e --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_EMTopoMCtest.py @@ -0,0 +1,29 @@ +#! /usr/bin/env python +# This script is designed to be used as a quick runtime ctest in the CI framework +# We use python to better handle getting our validation cutfile which should be stable +# We will augment the NEvents line in our cutfile to limit the job +# This is primarily to catch any runtime changes introduced before they are merged + +from PathResolver import PathResolver +from CI_test import CITest +import sys,ROOT + +cutfilename = "validation-cuts.txt" +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +returnCode = CITest("TOPQ1 MC", + cutfilename, + cutfilepath, + "/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/dev/AnalysisTop/ContinuousIntegration/MC/p4174/"+ + "mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_s3126_r9364_p4174/"+ + "test.pool.root", + [("#NEvents.*","NEvents 100")]) + +if returnCode != 0: + print "Error in EMTopo TOPQ1 MC" + sys.exit(returnCode) + +# -- Return 0 as all tests were successful -- # +sys.exit(0) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_test.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_test.py new file mode 100755 index 000000000000..92e3bb059d2f --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/CI_test.py @@ -0,0 +1,52 @@ +#! /usr/bin/env python +# This script is designed to be used as a quick runtime ctest in the CI framework +# We use python to better handle getting our validation cutfile which should be stable +# We will augment the NEvents line in our cutfile to limit the job +# This is primarily to catch any runtime changes introduced before they are merged + +import sys, subprocess, random, os, shlex, ROOT, shutil + +def CITest(testname, cutfile, cutfilepath, inputfile, sedreplace): + """ Templated test to allow extension """ + print "CI Integration Test :",testname + + # -- Settings -- + cutfilename = cutfile + inputfilename = inputfile + + # -- Move to a unique directory -- + cwd = os.getcwd() + rundir = str(random.randrange(10**8)) + os.mkdir(rundir) + os.chdir(rundir) + + # -- Get the validation file path from the most recent location -- + + # -- Print the file location for debugging -- + print "CI Integration Test : Using cutfile %s"%(cutfilepath) + print "CI Integration Test : Using inputfile %s"%(inputfilename) + + # -- Copy the cutfile locally to be updated -- + shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- + inputfilepath = open("input.txt","w") + inputfilepath.write(inputfilename+"\n") + inputfilepath.close() + + # -- Edit the cutfile to set any provided options -- + for (old, new) in sedreplace: + cmd = "sed -i -e 's/"+old+"/"+new+"/g' %s"%(cutfilename) + proc = subprocess.Popen(shlex.split(cmd)) + proc.wait() + + # -- Run top-xaod -- + cmd = "top-xaod %s input.txt"%(cutfilename) + proc = subprocess.Popen(shlex.split(cmd)) + proc.wait() + + # Return to starting directory + os.chdir(cwd) + + # -- Check the return code and exit this script with that -- + return proc.returncode diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/ConfigExampleMakeQuarkGluonFractionPlots.xml b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/ConfigExampleMakeQuarkGluonFractionPlots.xml new file mode 100644 index 000000000000..e875a0e13dbe --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/ConfigExampleMakeQuarkGluonFractionPlots.xml @@ -0,0 +1,32 @@ +<configuration> +<!-- Configuration file to compute the gluon fraction --> + <!-- Paths configuration. If folder attribute is empty, assume folder="JetFlavorPlots" if scalefactor attribute is empty, assume scalefactor="1.0" --> + <!-- Path to nominal input file or txt list (this is valid for any path) --> + <nominal path="./nominal_list.txt" folder="JetFlavorPlots" /> + <!-- If you want the Loose selection, just specify in the folder field, like: --> + <!-- + <nominal path="/afs/cern.ch/user/m/mscornaj/QGFPlots/prova.root" folder="JetFlavorPlots_Loose" /> + --> + <!-- Systematic uncertainties (you can add as much as you want) --> + <!-- one point systematic example: delta=scalefactor*abs(central-variation)/central --> + <systematic1point name="GeneratorSyst1P" central="./nominal.root" variation="./alternative_generator.root" scalefactor="1.0" folder_variation="JetFlavorPlots" folder_central="JetFlavorPlots" /> + <systematic1point name="PartonShowerSyst1P" central="./nominal.root" variation="./alternative_shower_list.txt" scalefactor="1.0" folder_variation="JetFlavorPlots" folder_central="JetFlavorPlots" /> + <!-- two point systematic example: delta_up=scalefactor*abs(central-variation_up)/central delta_down=scalefactor*abs(central-variation_down)/central --> + <systematic2point name="IFSRSyst2P" central="./nominal_list.txt" folder_central="JetFlavorPlots" variation_up="./IFSR_UP.root" folder_up="JetFlavorPlots_RadHigh" variation_down="./IFSR_DOWN.root" folder_down="JetFlavorPlots_RadLow" scalefactor="1.0" /> + <!-- Path to output file --> + <output path="FlavourComposition.root" /> + <!-- End paths configuration --> + <!-- Channel list (add as much as you want) --> + <channel name="mumu_2016" /> + <channel name="mumu_2015" /> + <channel name="ee_2015" /> + <channel name="ee_2016" /> + <!-- Merge different channels in single QGF histogram --> + <mergechannels value="false" /> + <!-- Run the extended configuration? --> + <detailed value="false" /> + <!-- Compute the gluon fraction taking into account only light quarks or also heavy quarks ( light, lightC(default) or lightCB ) --> + <gluon_vs_flavour value="lightC" /> + <!-- Save histograms as PS files --> + <do_ps value="true" /> +</configuration> diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/MakeQuarkGluonFractionPlots.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/MakeQuarkGluonFractionPlots.cxx new file mode 100644 index 000000000000..782be55c195c --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/MakeQuarkGluonFractionPlots.cxx @@ -0,0 +1,771 @@ +// Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +// =============================================================================== +// Macro to compute the gluon initiated jets fraction in your sample/selection +// To run the macro: .x MakeQuarkGluonFractionPlots.cxx+("config.txt") +// =============================================================================== +#include "MakeQuarkGluonFractionPlots.h" + +MakeQuarkGluonFractionPlots::MakeQuarkGluonFractionPlots(std::string filename): + m_doGluVsFlavour("lightC"), + m_channel({}), + m_detailedConfig(false), + m_OutputFile("FlavourComposition"), + m_doPS(false){ + + //Suppressing info/error/... ROOT messages + gErrorIgnoreLevel = 5000; + TH1::AddDirectory(kFALSE); + gStyle->SetPaintTextFormat(".3f"); + gROOT->SetBatch(kTRUE); + printf("\n %s\n MakeQuarkGluonFractionPlots::MakeQuarkGluonFractionPlots\n %s\n",std::string(75,'=').c_str(),std::string(75,'=').c_str()); + //---------------------------- + // reading configuration file + //---------------------------- + readXMLConfigFile(filename); + printXMLConfigFile(); + //----------------------------------------------------------------------------------------------- + // plotting the 2D input histograms in a ps file and storing them in a vector and + // compute the gluon fraction for nominal and systematic samples + //----------------------------------------------------------------------------------------------- + std::string psfilename; + TCanvas c1; + //Maps to store histograms + std::map<std::string, TH2D*> h_input; + std::vector< std::map<std::string, TH2D*> > h_input_1P; + std::vector< std::map<std::string, TH2D*> > h_input_1PVar; + std::vector< std::map<std::string, TH2D*> > h_input_2P; + std::vector< std::map<std::string, TH2D*> > h_input_2PUp; + std::vector< std::map<std::string, TH2D*> > h_input_2PDown; + printf("\n %s\n Retrieving histograms\n %s\n",std::string(75,'%').c_str(),std::string(75,'%').c_str()); + if(m_mergechannels){ + psfilename = "PlotsGluonFraction_AllChannels.ps"; + if(m_doPS) c1.Print((psfilename+"[").c_str()); + bool createMap = true; + for(unsigned int c=0; c<m_channel.size(); ++c){ + std::string append = "nominal_"; + DumpToMap(h_input, m_configNominal.path, m_channel.at(c), m_configNominal.folder, append, createMap); + createMap = false; + } + if(m_doPS) drawhistos(h_input, psfilename); + for(unsigned int v=0; v<m_config1PointVec.size(); ++v){ + createMap = true; + std::map<std::string, TH2D*> map_temp; + for(unsigned int c=0; c<m_channel.size(); ++c){ + std::string append = "central1P_"+std::to_string(v)+"_"; + DumpToMap(map_temp, m_config1PointVec.at(v).central, m_channel.at(c), m_config1PointVec.at(v).folder_c, append, createMap); + createMap = false; + } + h_input_1P.push_back(map_temp); + if(m_doPS) drawhistos(h_input_1P.at(v), psfilename); + } + for(unsigned int v=0; v<m_config1PointVec.size(); ++v){ + createMap = true; + std::map<std::string, TH2D*> map_temp; + for(unsigned int c=0; c<m_channel.size(); ++c){ + std::string append = "variation1P_"+std::to_string(v)+"_"; + DumpToMap(map_temp, m_config1PointVec.at(v).variation, m_channel.at(c), m_config1PointVec.at(v).folder_v, append, createMap); + createMap = false; + } + h_input_1PVar.push_back(map_temp); + if(m_doPS) drawhistos(h_input_1PVar.at(v), psfilename); + } + for(unsigned int v=0; v<m_config2PointVec.size(); ++v){ + createMap = true; + std::map<std::string, TH2D*> map_temp; + for(unsigned int c=0; c<m_channel.size(); ++c){ + std::string append = "central2P_"+std::to_string(v)+"_"; + DumpToMap(map_temp, m_config2PointVec.at(v).central, m_channel.at(c), m_config2PointVec.at(v).folder_c, append, createMap); + createMap = false; + } + h_input_2P.push_back(map_temp); + if(m_doPS) drawhistos(h_input_2P.at(v), psfilename); + } + for(unsigned int v=0; v<m_config2PointVec.size(); ++v){ + createMap = true; + std::map<std::string, TH2D*> map_temp; + for(unsigned int c=0; c<m_channel.size(); ++c){ + std::string append = "variation2PUp_"+std::to_string(v)+"_"; + DumpToMap(map_temp, m_config2PointVec.at(v).variation_up, m_channel.at(c), m_config2PointVec.at(v).folder_up, append, createMap); + createMap = false; + } + h_input_2PUp.push_back(map_temp); + if(m_doPS) drawhistos(h_input_2PUp.at(v), psfilename); + } + for(unsigned int v=0; v<m_config2PointVec.size(); ++v){ + createMap = true; + std::map<std::string, TH2D*> map_temp; + for(unsigned int c=0; c<m_channel.size(); ++c){ + std::string append = "variation2PDown_"+std::to_string(v)+"_"; + DumpToMap(map_temp, m_config2PointVec.at(v).variation_down, m_channel.at(c), m_config2PointVec.at(v).folder_down, append, createMap); + createMap = false; + } + h_input_2PDown.push_back(map_temp); + if(m_doPS) drawhistos(h_input_2PDown.at(v), psfilename); + } + CreateQGFFile("AllChannels",h_input,h_input_1P,h_input_1PVar,h_input_2P,h_input_2PUp,h_input_2PDown); + } + else{ + for(unsigned int c=0; c<m_channel.size(); ++c){ + psfilename = "PlotsGluonFraction_" + m_channel.at(c) +".ps"; + if(m_doPS) c1.Print((psfilename+"[").c_str()); + bool createMap = true; + std::string append = "nominal_"; + + //Clear the input map + h_input.clear(); + h_input_1P.clear(); + h_input_1PVar.clear(); + h_input_2P.clear(); + h_input_2PUp.clear(); + h_input_2PDown.clear(); + + DumpToMap(h_input, m_configNominal.path, m_channel.at(c), m_configNominal.folder, append, createMap); + if(m_doPS) drawhistos(h_input, psfilename); + + for(unsigned int v=0; v<m_config1PointVec.size(); ++v){ + std::map<std::string, TH2D*> map_temp; + std::string append = "central1P_"+std::to_string(v)+"_"+m_channel.at(c)+"_"; + DumpToMap(map_temp, m_config1PointVec.at(v).central, m_channel.at(c), m_config1PointVec.at(v).folder_c, append, createMap); + h_input_1P.push_back(map_temp); + if(m_doPS) drawhistos(h_input_1P.at(v), psfilename); + } + for(unsigned int v=0; v<m_config1PointVec.size(); ++v){ + std::map<std::string, TH2D*> map_temp; + std::string append = "variation1P_"+std::to_string(v)+"_"+m_channel.at(c)+"_"; + DumpToMap(map_temp, m_config1PointVec.at(v).variation, m_channel.at(c), m_config1PointVec.at(v).folder_v, append, createMap); + h_input_1PVar.push_back(map_temp); + if(m_doPS) drawhistos(h_input_1PVar.at(v), psfilename); + } + for(unsigned int v=0; v<m_config2PointVec.size(); ++v){ + std::map<std::string, TH2D*> map_temp; + std::string append = "central2P_"+std::to_string(v)+"_"+m_channel.at(c)+"_"; + DumpToMap(map_temp, m_config2PointVec.at(v).central, m_channel.at(c), m_config2PointVec.at(v).folder_c, append, createMap); + h_input_2P.push_back(map_temp); + if(m_doPS) drawhistos(h_input_2P.at(v), psfilename); + } + for(unsigned int v=0; v<m_config2PointVec.size(); ++v){ + std::map<std::string, TH2D*> map_temp; + std::string append = "variation2PUp_"+std::to_string(v)+"_"+m_channel.at(c)+"_"; + DumpToMap(map_temp, m_config2PointVec.at(v).variation_up, m_channel.at(c), m_config2PointVec.at(v).folder_up, append, createMap); + h_input_2PUp.push_back(map_temp); + if(m_doPS) drawhistos(h_input_2PUp.at(v), psfilename); + } + for(unsigned int v=0; v<m_config2PointVec.size(); ++v){ + std::map<std::string, TH2D*> map_temp; + std::string append = "variation2PDown_"+std::to_string(v)+"_"+m_channel.at(c)+"_"; + DumpToMap(map_temp, m_config2PointVec.at(v).variation_down, m_channel.at(c), m_config2PointVec.at(v).folder_down, append, createMap); + h_input_2PDown.push_back(map_temp); + if(m_doPS) drawhistos(h_input_2PDown.at(v), psfilename); + } + CreateQGFFile(m_channel.at(c),h_input,h_input_1P,h_input_1PVar,h_input_2P,h_input_2PUp,h_input_2PDown); + } + } +} +/********************************************* + * Drawing methods + * *******************************************/ +// Draw histograms from a map +void MakeQuarkGluonFractionPlots::drawhistos(std::map<std::string, TH2D*> histos, std::string psfilename){ + TCanvas c1; + c1.SetLogx(); + for (std::map<std::string, TH2D*>::iterator it = histos.begin() ; it != histos.end(); ++it){ + TH2D *h = it->second; + if(h->Integral()==0.) continue; + h->Draw("COLZtext"); + c1.Print(psfilename.c_str()); + + } +} +// Draw histograms from a vector +void MakeQuarkGluonFractionPlots::drawhistos(std::vector<TH2D*> histos, std::string psfilename){ + TCanvas c1; + c1.SetLogx(); + for (std::vector<TH2D*>::iterator it = histos.begin() ; it != histos.end(); ++it){ + TH2D *h = *it; + if(h->Integral()==0.) continue; + h->Draw("COLZtext"); + c1.Print(psfilename.c_str()); + + } +} +//Write histograms to file (nominal and uncertainties, if presents) +void MakeQuarkGluonFractionPlots::createOutputFile(std::string filename, std::vector<TH2D*> histos, std::vector<TH2D*> histosUnc){ + TFile *fout = new TFile(filename.c_str(),"recreate"); + fout->cd(); + for (std::vector<TH2D*>::iterator it = histos.begin() ; it != histos.end(); ++it) (*it)->Write(); + for (std::vector<TH2D*>::iterator it = histosUnc.begin() ; it != histosUnc.end(); ++it) { if((*it)!= NULL) (*it)->Write();} + fout->Close(); + std::cout<<" Histograms are saved in "<<filename<<std::endl; +} +/************************************************************** + * QGF Evaluation - related methods + * ************************************************************/ +void MakeQuarkGluonFractionPlots::DumpToMap(std::map<std::string, TH2D*> &h_map, std::string filename, std::string channel, std::string folder, std::string keyname, bool createMap){ + bool newMap = createMap; + bool istxt = ( (filename.find(".txt") + 4 ) == filename.length()); + if(istxt){ + std::string f_name; + ifstream reader; + reader.open (filename); + while(!reader.eof()){ + getline(reader,f_name); + if(f_name.compare("")==0) continue; + DumpFileToMap(h_map, f_name, channel, folder, keyname, newMap); + newMap = false; + } + reader.close(); + } + else + DumpFileToMap(h_map, filename, channel, folder, keyname, newMap); +} +void MakeQuarkGluonFractionPlots::DumpFileToMap(std::map<std::string, TH2D*> &h_map, std::string filename, std::string channel, std::string folder, std::string keyname, bool createMap){ + TFile *f_in=TFile::Open(filename.c_str()); + std::string dirname = channel + "/"+folder; + TDirectory* dir = f_in->GetDirectory(dirname.c_str()); + if(!dir) { + std::cout<<" ERROR: directory "<<dirname<<" not found in file "<<filename<<"! Exiting.\n"; + abort(); + } + TIter next(dir->GetListOfKeys()); + TKey *key; + int counter = 0; + while ((key = (TKey*)next())) { + TClass *cl = gROOT->GetClass(key->GetClassName()); + if (!cl->InheritsFrom("TH2D")) continue; + TH2D *h = (TH2D*)key->ReadObj(); + if(createMap){ + std::string histoname = keyname + std::to_string(counter); + ++counter; + std::string orig_name = h->GetName(); + h->SetName(histoname.c_str()); + std::string titlename = keyname + "_" + orig_name; + h->SetTitle(titlename.c_str()); + h->SetStats(kTRUE); // Activate or desactivate the statistics box + gStyle->SetStatY(0.95); // Set y-position (fraction of pad size) + gStyle->SetStatX(0.89); // Set x-position (fraction of pad size) + h_map.insert( std::pair<std::string, TH2D* >( orig_name, h ) ); + } + else{ + h_map.at(h->GetName())->Add(h); + } + } +} +//QGF File creation +void MakeQuarkGluonFractionPlots::CreateQGFFile(std::string prename, std::map<std::string, TH2D*> h_input,std::vector< std::map<std::string, TH2D*> > h_input_1P,std::vector< std::map<std::string, TH2D*> > h_input_1PVar,std::vector< std::map<std::string, TH2D*> > h_input_2P,std::vector< std::map<std::string, TH2D*> > h_input_2PUp,std::vector< std::map<std::string, TH2D*> > h_input_2PDown){ + //Since I am here, all histograms have already been retrieved! + printf("\n %s\n Computing the gluon fraction in %s channel\n %s\n",std::string(75,'%').c_str(),prename.c_str(),std::string(75,'%').c_str()); + std::string outputName = prename + "_" + m_OutputFile; + //Creating ps file to plot all flavour plots/channel + std::string psfilename = "PlotsGluonFraction_" + prename +".ps"; + TCanvas c1; + if(m_doPS) c1.Print((psfilename+"[").c_str()); + //Nominal + printf("\n %s\n Computing QGF (nominal): \n %s\n",std::string(75,'=').c_str(),std::string(75,'=').c_str()); + std::vector<TH2D*> fractionhistos=computeQuarkGluonFraction(h_input, m_doGluVsFlavour, prename); + if(m_doPS) drawhistos(fractionhistos, psfilename); + //Systematics: + std::vector<std::vector<TH2D*>> h_fractionUnc1PSyst; + std::vector<std::vector<TH2D*>> h_fractionUnc2PSyst_up; + std::vector<std::vector<TH2D*>> h_fractionUnc2PSyst_down; + printf("\n %s\n Computing QGF (%s): \n %s\n",std::string(75,'%').c_str(),"1 point systematics",std::string(75,'%').c_str()); + for(unsigned int v=0; v<m_config1PointVec.size(); ++v){ + std::string prehistname="central_1PSystematic" + std::to_string(v) ; + std::string prehistnameVar="variation_1PSystematic" + std::to_string(v) ;//std::to_string(v) + "variation_1PSystematic"; + printf("\n %s\n Computing QGF (%s): \n %s\n",std::string(75,'=').c_str(),m_config1PointVec.at(v).name.c_str(),std::string(75,'=').c_str()); + std::vector<TH2D*> qgf_nominal = computeQuarkGluonFraction(h_input_1P.at(v), m_doGluVsFlavour, prehistname); + if(m_doPS) drawhistos(qgf_nominal, psfilename); + std::vector<TH2D*> qgf_variation = computeQuarkGluonFraction(h_input_1PVar.at(v), m_doGluVsFlavour, prehistnameVar); + if(m_doPS) drawhistos(qgf_variation, psfilename); + prehistname=std::to_string(v) + "_1PSystematic_delta"; + h_fractionUnc1PSyst.push_back(getDelta(qgf_nominal, qgf_variation, m_config1PointVec.at(v).scalefactor, prehistname)); //nominal-var + if(m_doPS) drawhistos(h_fractionUnc1PSyst.at(v), psfilename); + } + printf("\n %s\n Computing QGF (%s): \n %s\n",std::string(75,'%').c_str(),"2 point systematics",std::string(75,'%').c_str()); + for(unsigned int v=0; v<m_config2PointVec.size(); ++v){ + std::string prehistname=std::to_string(v) + "_2PSystematic"; + printf("\n %s\n Computing QGF (%s): \n %s\n",std::string(75,'=').c_str(),m_config2PointVec.at(v).name.c_str(),std::string(75,'=').c_str()); + std::vector<TH2D*> qgf_nominal = computeQuarkGluonFraction(h_input_2P.at(v), m_doGluVsFlavour, prehistname); + if(m_doPS) drawhistos(qgf_nominal, psfilename); + std::vector<TH2D*> qgf_variationUp = computeQuarkGluonFraction(h_input_2PUp.at(v), m_doGluVsFlavour, prehistname); + if(m_doPS) drawhistos(qgf_variationUp, psfilename); + prehistname=std::to_string(v) + "_2PSystematic_deltaUp"; + h_fractionUnc2PSyst_up.push_back(getDelta(qgf_variationUp, qgf_nominal, m_config2PointVec.at(v).scalefactor, prehistname)); //up-nominal + if(m_doPS) drawhistos(h_fractionUnc2PSyst_up.at(v), psfilename); + + std::vector<TH2D*> qgf_variationDown = computeQuarkGluonFraction(h_input_2PDown.at(v), m_doGluVsFlavour, prehistname); + if(m_doPS) drawhistos(qgf_variationDown, psfilename); + prehistname=std::to_string(v) + "_2PSystematic_deltaDown"; + h_fractionUnc2PSyst_down.push_back(getDelta(qgf_nominal, qgf_variationDown, m_config2PointVec.at(v).scalefactor, prehistname)); //up-nominal + if(m_doPS) drawhistos(h_fractionUnc2PSyst_down.at(v), psfilename); + + } + //----------------------------------------------------------- + // compute the uncertainty histograms + //----------------------------------------------------------- + printf("\n %s\n Computing the total systematic uncertainty: \n %s\n",std::string(75,'=').c_str(),std::string(75,'=').c_str()); + std::vector<TH2D*> fractionTotalUnc = evaluateQGFUncertaity(h_fractionUnc1PSyst,h_fractionUnc2PSyst_up,h_fractionUnc2PSyst_down,prename); + if(m_doPS) drawhistos( fractionTotalUnc, psfilename); + //------------------------------------------------------------------ + // create output file to store fraction histograms in a root file + //------------------------------------------------------------------ + printf("\n %s\n Writing output file: \n %s\n",std::string(75,'%').c_str(),std::string(75,'%').c_str()); + if(m_config1PointVec.size()+m_config2PointVec.size()) + createOutputFile(outputName, fractionhistos, fractionTotalUnc); + else + createOutputFile(outputName, fractionhistos, {}); + //close ps file + c1.Print((psfilename+"]").c_str()); +} +// Evaluate Delta +std::vector<TH2D*> MakeQuarkGluonFractionPlots::getDelta (std::vector<TH2D*> h_nom, std::vector<TH2D*> h_var, double scale, std::string prehistname){ + std::vector<TH2D*> QuarkGluonDiffFractionhistos; + if(h_nom.size() != h_var.size()) std::cout<<"ERROR: Systematic variation don't have the same number of histograms!\n"; + std::string JetCollection = extractJetCollectionName((h_nom.at(0))->GetName()); + for(size_t i = 0; i<h_nom.size(); i++){ + //return diff*(nominal-varied) + std::string njets = extractJetNumber(h_nom.at(i)->GetName()); + std::string histname = prehistname + "_gluonFractionError_" + njets + "_" + JetCollection; + TH2D *hist_diff; + hist_diff = (TH2D*)((h_nom.at(i))->Clone(histname.c_str())); + hist_diff->Add((TH2D*)(h_var.at(i)), -1); + hist_diff->Scale(scale); + hist_diff->SetTitle(hist_diff->GetName()); + hist_diff->SetStats(kFALSE); + QuarkGluonDiffFractionhistos.push_back(hist_diff); + } + return QuarkGluonDiffFractionhistos; +} + +//Evaluate uncertainty +std::vector<TH2D*> MakeQuarkGluonFractionPlots::evaluateQGFUncertaity(std::vector<std::vector<TH2D*> > f_1P, std::vector<std::vector<TH2D*> > f_2PUp, std::vector<std::vector<TH2D*> > f_2PDown, std::string channel){ + std::vector<TH2D*> histUnc; + TH2D *h_tmp; + std::string h_tmp_name; + if(f_1P.size()!=0){ + h_tmp = (TH2D*)((f_1P.at(0)).at(0))->Clone("TH2_tmp_TotalUnc"); + h_tmp_name = ((f_1P.at(0)).at(0))->GetName(); + } + else{ + h_tmp = (TH2D*)((f_2PUp.at(0)).at(0))->Clone("TH2_tmp_TotalUnc"); + h_tmp_name = ((f_2PUp.at(0)).at(0))->GetName(); + } + std::string JetCollection = extractJetCollectionName(h_tmp_name); + // create a new uncertainty histogram (take the bin and axis from the histograms) + int binX = h_tmp->GetXaxis()->GetNbins(); + int binY = h_tmp->GetYaxis()->GetNbins(); + h_tmp->Reset(); + h_tmp->Sumw2(); + //Get squared 1P systematics histograms + std::vector<TH2D*> squared_histos1P; + if(f_1P.size()!=0){ + for(unsigned int h=0; h<f_1P.at(0).size(); ++h){ + + std::string h_tmp_name = ((f_1P.at(0)).at(h))->GetName(); + std::string h_new_name("TH2_tmp_1P_TotalUnc_"+std::to_string(h)); + TH2D *h_tmp = (TH2D*)((f_1P.at(0)).at(h))->Clone(h_new_name.c_str()); + h_tmp->Reset(); + h_tmp->Sumw2(); + for(int x = 0; x <= binX; ++x){ + for(int y = 0; y <= binY; ++y){ + int bin = h_tmp->GetBin(x,y); + float sq_err = 0.; + for(unsigned int hs=0; hs<f_1P.size(); ++hs){ + sq_err+=pow(((f_1P.at(hs)).at(h))->GetBinContent(bin),2); + } + + h_tmp->SetBinContent(bin,sq_err); + } + } + squared_histos1P.push_back(h_tmp); + } + } + //Get squared 2P systematics (symmetrized) histograms + std::vector<TH2D*> squared_histos2P; + if(f_2PUp.size()!=0){ + for(unsigned int h=0; h<f_2PUp.at(0).size(); ++h){ + std::string h_tmp_name = ((f_2PUp.at(0)).at(h))->GetName(); + std::string h_new_name("TH2_tmp_2P_TotalUnc_"+std::to_string(h)); + TH2D *h_tmp = (TH2D*)((f_2PUp.at(0)).at(h))->Clone(h_new_name.c_str()); + h_tmp->Reset(); + h_tmp->Sumw2(); + for(int x = 0; x <= binX; ++x){ + for(int y = 0; y <= binY; ++y){ + int bin = h_tmp->GetBin(x,y); + float sq_err = 0.; + float sq_err_up = 0.; + float sq_err_down = 0.; + for(unsigned int hs=0; hs<f_2PUp.size(); ++hs){ + float err_up = ((f_2PUp.at(hs)).at(h))->GetBinContent(bin); + float err_down = ((f_2PDown.at(hs)).at(h))->GetBinContent(bin); + /* 4 different cases: + * (+,-): no action + * (-,+): swap + * (+,+): (max(+,+),0) + * (-,-): (0,min(-,-)) + */ + bool isneg_up = std::signbit(err_up); + bool isneg_down = std::signbit(err_down); + if((isneg_up)&&(!isneg_down)){ + float tmp_swap = err_up; + err_up = err_down; + err_down = tmp_swap; + } + else if((!isneg_up)&&(!isneg_down)){ + err_up = std::max(err_up,err_down); + err_down = 0.; + } + else if((isneg_up)&&(isneg_down)){ + err_down = std::min(err_up,err_down); + err_up = 0.; + } + sq_err_up+=pow(err_up,2); + sq_err_down+=pow(err_down,2); + } + //symmetrize error + sq_err=pow((sqrt(sq_err_down)+sqrt(sq_err_up))/2.,2); + h_tmp->SetBinContent(bin,sq_err); + } + } + squared_histos2P.push_back(h_tmp); + } + } + //Filling empty final histograms (just to retrieve correct binning + std::vector<TH2D*> final_histos; + + if(f_1P.size()!=0){ + for(unsigned int h=0; h<f_1P.at(0).size(); ++h){ + std::string h_tmp_name = ((f_1P.at(0)).at(h))->GetName(); + std::string JetCollection = extractJetCollectionName(h_tmp_name); + std::string njets = extractJetNumber(h_tmp_name); + std::string histoname = channel + "_gluonFractionError_"+ njets + JetCollection; + TH2D *h_tmp = (TH2D*)((f_1P.at(0)).at(h))->Clone(histoname.c_str()); + h_tmp->Reset(); + h_tmp->SetTitle(histoname.c_str()); + h_tmp->Sumw2(); + final_histos.push_back(h_tmp); + } + } + else{ + for(unsigned int h=0; h<f_2PUp.at(0).size(); ++h){ + std::string h_tmp_name = ((f_2PUp.at(0)).at(h))->GetName(); + std::string JetCollection = extractJetCollectionName(h_tmp_name); + std::string njets = extractJetNumber(h_tmp_name); + std::string histoname = channel + "_gluonFractionError_"+ njets + "_" + JetCollection; + TH2D *h_tmp = (TH2D*)((f_2PUp.at(0)).at(h))->Clone(histoname.c_str()); + h_tmp->Reset(); + h_tmp->SetTitle(histoname.c_str()); + h_tmp->Sumw2(); + final_histos.push_back(h_tmp); + } + } + //Filling final histograms + for(unsigned int h=0; h<final_histos.size(); ++h){ + for(int x = 0; x <= binX; ++x){ + for(int y = 0; y <= binY; ++y){ + int bin = h_tmp->GetBin(x,y); + float content = 0.; + + if((squared_histos1P.size())!=0){ + content+=(squared_histos1P.at(h))->GetBinContent(bin); + } + if((squared_histos2P.size())!=0){ + content+=(squared_histos2P.at(h))->GetBinContent(bin); + } + content = sqrt(content); + final_histos.at(h)->SetBinContent(bin,content); + } + } + } + return final_histos; +} +// Compute quark-gluon composition +std::vector<TH2D*> MakeQuarkGluonFractionPlots::computeQuarkGluonFraction (std::map< std::string, TH2D* > inputhistos, std::string quarkflavour, std::string prename){ + std::vector<TH2D*> QuarkGluonFractionhistos; + std::string jetCollection = extractJetCollectionName(inputhistos.begin()->first); + int njets = (inputhistos.size()-6)/5; //FIXME this can be potentially wrong + if(!m_detailedConfig){ + std::string name_gluons = "gluon_jets_"; name_gluons += jetCollection.c_str(); + std::string name_quarks = "quark_jets_"; name_quarks += jetCollection.c_str(); + TH2D *hist_g = inputhistos[name_gluons]; + TH2D *hist_q = inputhistos[name_quarks]; + //Ratio is f=g/(g+q) + std::string name_fraction = prename + "_gluonFraction_" + jetCollection; + TH2D *hist_ratio = (TH2D*)hist_g->Clone(name_fraction.c_str()); + hist_ratio->SetTitle(hist_ratio->GetName()); + hist_ratio->SetStats(kFALSE); + TH2D *hist_summ = (TH2D*)hist_g->Clone("hist_summ"); //denominator + hist_summ->Add(hist_q); + hist_ratio->Divide(hist_summ); + QuarkGluonFractionhistos.push_back(hist_ratio); + } + else{ + for (int nj = -1; nj < njets ; nj++) { //nj = -1 mean inclusive case + std::string name_gluons = "gluon_jets_"; + std::string name_lquarks = "lightquark_jets_"; + std::string name_cquarks = "cquark_jets_"; + std::string name_bquarks = "bquark_jets_"; + std::string name_other = "other_jets_"; + std::string name_fraction = prename + "_gluonFraction_"; + if (nj==-1){ + name_gluons += jetCollection; + name_lquarks += jetCollection; + name_cquarks += jetCollection; + name_bquarks += jetCollection; + name_other += jetCollection; + name_fraction += jetCollection; + } + else{ + std::string name_append="njet" + std::to_string(nj) + "_" + jetCollection; + name_gluons += name_append; + name_lquarks += name_append; + name_cquarks += name_append; + name_bquarks += name_append; + name_other += name_append; + name_fraction += name_append; + } + TH2D *hist_g = inputhistos[name_gluons]; + TH2D *hist_lj = inputhistos[name_lquarks]; + TH2D *hist_cj = inputhistos[name_cquarks]; + TH2D *hist_bj = inputhistos[name_bquarks]; + TH2D *hist_oth = inputhistos[name_other]; + //Ratio is f=g/(g+lj[light]+cj[lightC]+bj[lightCB]) + TH2D *hist_ratio = (TH2D*)hist_g->Clone(name_fraction.c_str()); + hist_ratio->SetTitle(hist_ratio->GetName()); + hist_ratio->SetStats(kFALSE); + std::string name_summ = "hist_summ_" + std::to_string(nj); //denominator + TH2D *hist_summ = (TH2D*)hist_g->Clone(name_summ.c_str()); + hist_summ->Add(hist_lj); + if(quarkflavour.compare("light") == 0){ + hist_ratio->Divide(hist_summ);} + else if (quarkflavour.compare("lightC") == 0){ + hist_summ->Add(hist_cj); + hist_ratio->Divide(hist_summ);} + else if(quarkflavour.compare("lightCB") == 0){ + hist_summ->Add(hist_cj); + hist_summ->Add(hist_bj); + hist_ratio->Divide(hist_summ);} + else + std::cout<< " WARNING: no flavor known to calculate the gluon fraction" << std::endl; + QuarkGluonFractionhistos.push_back(hist_ratio); + } + } + return QuarkGluonFractionhistos; +} +// Extract jet collection name +std::string MakeQuarkGluonFractionPlots::extractJetCollectionName(std::string histoname){ + if(histoname.find("EMPFlow")!=std::string::npos) return "AntiKt4EMPFlow"; + else if(histoname.find("EMTopo")!=std::string::npos) return "AntiKt4EMTopo"; + else if(histoname.find("LCTopo")!=std::string::npos) return "AntiKt4LCTopo"; + else std::cout<<"ERROR: jet collection not found"<<std::endl; + return NULL; +} +// Extract number of jets +std::string MakeQuarkGluonFractionPlots::extractJetNumber(std::string histoname){ + std::string njets; + std::size_t found = histoname.find("njet"); + if (found!=std::string::npos){ + std::size_t first= histoname.find("njet"); + std::size_t last = histoname.find("_AntiKt"); + njets = histoname.substr(first,(last-first)); + } + return njets; +} +/************************************************************** + * Configuration - related methods + * ************************************************************/ +void MakeQuarkGluonFractionPlots::printXMLConfigFile(){ + printf("\n %s\n Extracting configuration: \n %s\n",std::string(75,'=').c_str(),std::string(75,'=').c_str()); + std::cout<<" Nominal input file: "<<m_configNominal.path<<std::endl; + checkFile(m_configNominal.path); + std::cout<<" Nominal folder: "<<m_configNominal.folder<<std::endl; + std::cout<<" The gluon fraction will be calculated for the following channels: \n"; + for(unsigned int i=0; i<m_channel.size(); ++i) + std::cout<<"\t"<<i<<") "<<m_channel.at(i)<<std::endl; + if(m_detailedConfig) std::cout<<" It will be calculated for different jet multiplicities.\n"; + if(m_mergechannels) std::cout<<" The different channels will be merged.\n"; + std::cout<<" The gluon fraction will be calculated taking into account: "<< m_doGluVsFlavour<< " jets\n"; + std::cout<<"\n\n Systematic samples:\n"; + std::cout<<"\t 1 PointSystematic samples:\n"; + for(unsigned int i=0; i<m_config1PointVec.size();++i){ + std::cout<<"\t("<<i<<") "<<m_config1PointVec.at(i).name<<"\n"; + std::cout<<"\t\tCentral file: "<<m_config1PointVec.at(i).central<<std::endl; + checkFile(m_config1PointVec.at(i).central); + std::cout<<"\t\tCentral folder: "<<m_config1PointVec.at(i).folder_c<<std::endl; + std::cout<<"\t\tVariated file: "<<m_config1PointVec.at(i).variation<<std::endl; + checkFile(m_config1PointVec.at(i).variation); + std::cout<<"\t\tVariated folder: "<<m_config1PointVec.at(i).folder_v<<std::endl; + std::cout<<"\t\tScalefactor to apply: "<<m_config1PointVec.at(i).scalefactor<<std::endl; + } + std::cout<<"\t 2 PointSystematic samples:\n"; + for(unsigned int i=0; i<m_config2PointVec.size();++i){ + std::cout<<"\t("<<i<<") "<<m_config2PointVec.at(i).name<<"\n"; + std::cout<<"\t\tCentral file: "<<m_config2PointVec.at(i).central<<std::endl; + checkFile(m_config2PointVec.at(i).central); + std::cout<<"\t\tCentral folder : "<<m_config2PointVec.at(i).folder_c<<std::endl; + std::cout<<"\t\tUp-variated file: "<<m_config2PointVec.at(i).variation_up<<std::endl; + checkFile(m_config2PointVec.at(i).variation_up); + std::cout<<"\t\tUp-variated folder: "<<m_config2PointVec.at(i).folder_up<<std::endl; + std::cout<<"\t\tDown-variated file: "<<m_config2PointVec.at(i).variation_down<<std::endl; + checkFile(m_config2PointVec.at(i).variation_down); + std::cout<<"\t\tDown-variated folder: "<<m_config2PointVec.at(i).folder_down<<std::endl; + std::cout<<"\t\tScalefactor to apply: "<<m_config2PointVec.at(i).scalefactor<<std::endl; + } + std::cout<<"\n\n The histograms will be stored inside [channel]_"<<m_OutputFile<<std::endl; + if (m_doPS) std::cout<<" All plots will be stored in PS files "<<std::endl; + printf("\n %s\n Configuration Extracted\n %s\n",std::string(75,'=').c_str(),std::string(75,'=').c_str()); +} + +void MakeQuarkGluonFractionPlots::AbortXMLDecode(std::string value){ + std::cout<<"ERROR! Unknown attribute: "<<value<<". Aborting!\n"; + abort(); +} + +bool MakeQuarkGluonFractionPlots::decodeFloat(TXMLEngine xml, XMLAttrPointer_t attr, std::string match, float &value){ + if(strncmp(xml.GetAttrName(attr),match.c_str(),100)!=0) return false; + value=std::stof(xml.GetAttrValue(attr)); + return true; +} + +bool MakeQuarkGluonFractionPlots::decodeString(TXMLEngine xml, XMLAttrPointer_t attr, std::string match, std::string &value){ + if(strncmp(xml.GetAttrName(attr),match.c_str(),100)!=0) return false; + value=xml.GetAttrValue(attr); + return true; +} + +bool MakeQuarkGluonFractionPlots::decodeBool(TXMLEngine xml, XMLAttrPointer_t attr, std::string match, bool &value){ + if(strncmp(xml.GetAttrName(attr),match.c_str(),100)!=0) return false; + if(strncmp(xml.GetAttrValue(attr),"true",100)==0) + value=true; + else if(strncmp(xml.GetAttrValue(attr),"false",100)==0) + value=false; + else{ + std::cout<<"ERROR! Unknown attribute value: "<<xml.GetAttrValue(attr)<<". Choose between true or false! Exiting!\n"; + abort(); + } + return true; +} + +void MakeQuarkGluonFractionPlots::readXMLConfigFile(std::string configfile){ + TXMLEngine xml; + // Now try to parse xml file + XMLDocPointer_t xmldoc = xml.ParseFile(configfile.c_str()); + if (xmldoc==0) { + std::cout<<"ERROR! No valid xml configuration file provided! Aborting!\n"; + abort(); + } + // Access to main node + XMLNodePointer_t mainnode = xml.DocGetRootElement(xmldoc); + // Loop through all nodes and subnodes + readXMLNode(xml, mainnode); + // Release memory before exit + xml.FreeDoc(xmldoc); +} +void MakeQuarkGluonFractionPlots::readXMLNode(TXMLEngine xml, XMLNodePointer_t node){ + if(strncmp(xml.GetNodeName(node),"nominal",100)==0){ + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + while (attr!=0) { + bool pass=0; + pass+=decodeString(xml, attr, "path", m_configNominal.path); + pass+=decodeString(xml, attr, "folder", m_configNominal.folder); + if(!pass) AbortXMLDecode(xml.GetAttrName(attr)); + attr = xml.GetNextAttr(attr); + } + } + else if(strncmp(xml.GetNodeName(node),"systematic1point",100)==0){ + config_1PointSyst temp_config1Point; + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + while (attr!=0) { + bool pass=0; + pass+=decodeString(xml, attr, "name", temp_config1Point.name); + pass+=decodeString(xml, attr, "central", temp_config1Point.central); + pass+=decodeString(xml, attr, "variation", temp_config1Point.variation); + pass+=decodeFloat(xml, attr, "scalefactor", temp_config1Point.scalefactor); + pass+=decodeString(xml, attr, "folder_central", temp_config1Point.folder_c); + pass+=decodeString(xml, attr, "folder_variation", temp_config1Point.folder_v); + if(!pass) AbortXMLDecode(xml.GetAttrName(attr)); + attr = xml.GetNextAttr(attr); + } + m_config1PointVec.push_back(temp_config1Point); + } + else if(strncmp(xml.GetNodeName(node),"systematic2point",100)==0){ + config_2PointSyst temp_config2Point; + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + while (attr!=0) { + bool pass=0; + pass+=decodeString(xml, attr, "name", temp_config2Point.name); + pass+=decodeString(xml, attr, "central", temp_config2Point.central); + pass+=decodeString(xml, attr, "variation_up", temp_config2Point.variation_up); + pass+=decodeString(xml, attr, "variation_down", temp_config2Point.variation_down); + pass+=decodeFloat(xml, attr, "scalefactor", temp_config2Point.scalefactor); + pass+=decodeString(xml, attr, "folder_central", temp_config2Point.folder_c); + pass+=decodeString(xml, attr, "folder_up", temp_config2Point.folder_up); + pass+=decodeString(xml, attr, "folder_down", temp_config2Point.folder_down); + if(!pass) AbortXMLDecode(xml.GetAttrName(attr)); + attr = xml.GetNextAttr(attr); + } + m_config2PointVec.push_back(temp_config2Point); + std::cout<<"systematic2point\n"; + } + else if(strncmp(xml.GetNodeName(node),"output",100)==0){ + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + if(!decodeString(xml, attr, "path", m_OutputFile)) AbortXMLDecode(xml.GetAttrName(attr)); + } + else if(strncmp(xml.GetNodeName(node),"channel",100)==0){ + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + std::string tmp_channel=""; + if(!decodeString(xml, attr, "name", tmp_channel)) AbortXMLDecode(xml.GetAttrName(attr)); + m_channel.push_back(tmp_channel); + } + else if(strncmp(xml.GetNodeName(node),"mergechannels",100)==0){ + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + if(!decodeBool(xml, attr, "value", m_mergechannels)) AbortXMLDecode(xml.GetAttrName(attr)); + } + else if(strncmp(xml.GetNodeName(node),"detailed",100)==0){ + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + if(!decodeBool(xml, attr, "value", m_detailedConfig)) AbortXMLDecode(xml.GetAttrName(attr)); + } + else if(strncmp(xml.GetNodeName(node),"gluon_vs_flavour",100)==0){ + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + if(!decodeString(xml, attr, "value", m_doGluVsFlavour)) AbortXMLDecode(xml.GetAttrName(attr)); + if(strncmp(xml.GetAttrValue(attr),"light" ,100) + *strncmp(xml.GetAttrValue(attr),"lightC" ,100) + *strncmp(xml.GetAttrValue(attr),"lightCB",100)) + AbortXMLDecode(xml.GetAttrName(attr)); + } + else if(strncmp(xml.GetNodeName(node),"do_ps",100)==0){ + XMLAttrPointer_t attr = xml.GetFirstAttr(node); + if(!decodeBool(xml, attr, "value", m_doPS)) AbortXMLDecode(xml.GetAttrName(attr)); + } + //Loop over child nodes + XMLNodePointer_t child = xml.GetChild(node); + while (child!=0) { + readXMLNode(xml, child); + child = xml.GetNext(child); + } +} +void MakeQuarkGluonFractionPlots::checkFile(std::string inputfilename){ + bool istxt = ( (inputfilename.find(".txt") + 4 ) == inputfilename.length()); + if(istxt){ + std::string f_name; + ifstream reader; + reader.open (inputfilename); + while(!reader.eof()){ + getline(reader,f_name); + if(f_name.compare("")==0) continue; + TFile *f = TFile::Open(f_name.c_str()); + if (f->IsZombie()){ + std::cout<<"File "<<f_name<<" from list "<<inputfilename<<" not found! Please check against your configuration file! Aborting|\n"; + abort(); + } + } + reader.close(); + } + else{ + TFile f(inputfilename.c_str()); + if (f.IsZombie()){ + std::cout<<"File "<<inputfilename<<" not found! Please check against your configuration file! Aborting|\n"; + abort(); + } + } +} + diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/MakeQuarkGluonFractionPlots.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/MakeQuarkGluonFractionPlots.h new file mode 100644 index 000000000000..d4282739f4af --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/MakeQuarkGluonFractionPlots.h @@ -0,0 +1,136 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ +//Author: Regina Moles Valls - <regina.moles.valls@cern.ch> +//R21 migration: Matteo Scornajenghi - <matteo.scornajenghi@cern.ch> + +#ifndef MAKEQUARKGLUONFRACTIONPLOTS_H +#define MAKEQUARKGLUONFRACTIONPLOTS_H + +#include <iostream> +#include <string> +#include <fstream> +#include <sstream> +#include <stdlib.h> +#include <vector> +#include "TStyle.h" +#include "TCanvas.h" +#include "TFile.h" +#include "TKey.h" +#include "TH2D.h" +#include "TPostScript.h" +#include <TError.h> +#include "TROOT.h" +#include "TClass.h" +#include "TXMLEngine.h" +#include <map> +#include <fstream> + +// =============================================================================== +// Macro to compute the gluon initiated jets fraction in your sample/selection +// =============================================================================== +struct config_NominalInput{ + config_NominalInput(): path(""),folder("JetFlavorPlots"){} + std::string path; + std::string folder; +}; +struct config_1PointSyst{ + config_1PointSyst(): name(""),central(""),variation(""),scalefactor(1),folder_c("JetFlavorPlots"),folder_v("JetFlavorPlots"){} + std::string name; + std::string central; + std::string variation; + float scalefactor; + std::string folder_c; + std::string folder_v; +}; +struct config_2PointSyst{ + config_2PointSyst(): name(""),central(""),variation_up(""),variation_down(""),scalefactor(1),folder_c("JetFlavorPlots"),folder_up("JetFlavorPlots"),folder_down("JetFlavorPlots"){} + std::string name; + std::string central; + std::string variation_up; + std::string variation_down; + float scalefactor; + std::string folder_c; + std::string folder_up; + std::string folder_down; +}; + +class MakeQuarkGluonFractionPlots { + + public: +//new functions + void printXMLConfigFile(); + void readXMLConfigFile(std::string configfile); + void readXMLNode(TXMLEngine xml, XMLNodePointer_t node); + bool decodeBool(TXMLEngine xml, XMLAttrPointer_t attr, std::string match, bool &value); + bool decodeString(TXMLEngine xml, XMLAttrPointer_t attr, std::string match, std::string &value); + bool decodeFloat(TXMLEngine xml, XMLAttrPointer_t attr, std::string match, float &value); + void AbortXMLDecode(std::string value); +//end new + + //function that reads the configuration file and makes the gluon fraction plots + MakeQuarkGluonFractionPlots(std::string configfile); + + //function to check if the file exists + void checkFile(std::string filename); + + //function to draw histograms from a map + void drawhistos(std::map<std::string, TH2D*> histos, std::string psfilename); + //function to draw histograms from a vector + void drawhistos(std::vector<TH2D*> histos, std::string psfilename); + + //function to extract the JetCollectionName + std::string extractJetCollectionName(std::string histoname); + + //function to extract the JetNumber + std::string extractJetNumber(std::string histoname); + + //function to compute the gluon fraction + std::vector<TH2D*> computeQuarkGluonFraction (std::map< std::string,TH2D* > inputhistos, std::string quarkflavour, std::string prename); + + //function to create the output file + void createOutputFile(std::string filename,std::vector<TH2D*> histos, std::vector<TH2D*> histosUnc ); + + //Subtract + std::vector<TH2D*> getDelta (std::vector<TH2D*> h_nom, std::vector<TH2D*> h_var, double scale, std::string prehistname); + + //function to compute the total systematic uncertainty + std::vector<TH2D*> evaluateQGFUncertaity(std::vector<std::vector<TH2D*> > f_1P, std::vector<std::vector<TH2D*> > f_2PUp, std::vector<std::vector<TH2D*> > f_2PDown, std::string channel); + + + + + private: + // QuarkGluon fraction can be calculated respect to different quark flavours + // light: computed only talking into account light quarks (gluons/light-quarks) + // lightC default): computed only talking into account light quarks (gluons/light-quarks+c-quarks) + // lightCB: computed only talking into account light quarks (gluons/light-quarks+c-quarks+b-quarks) + std::string m_doGluVsFlavour; + + // channel:name of the folder where the histograms has been stored: ee, mumu, emu, mujets, ejets... + std::vector<std::string> m_channel; + + //compute the gluon fraction versus jet multiplicity + bool m_detailedConfig; + + // name of the output file + std::string m_OutputFile; + + // store plots in PS files + bool m_doPS; + + config_NominalInput m_configNominal; + std::vector<config_1PointSyst> m_config1PointVec; + std::vector<config_2PointSyst> m_config2PointVec; + + bool m_mergechannels; + + void DumpToMap(std::map<std::string, TH2D*> &h_map, std::string filename, std::string channel, std::string folder, std::string keyname, bool createMap); + void DumpFileToMap(std::map<std::string, TH2D*> &h_map, std::string filename, std::string channel, std::string folder, std::string keyname, bool createMap); + void CreateQGFFile(std::string prename, std::map<std::string, TH2D*> h_input,std::vector< std::map<std::string, TH2D*> > h_input_1P,std::vector< std::map<std::string, TH2D*> > h_input_1PVar,std::vector< std::map<std::string, TH2D*> > h_input_2P,std::vector< std::map<std::string, TH2D*> > h_input_2PUp,std::vector< std::map<std::string, TH2D*> > h_input_2PDown); + +}; + + +#endif + diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/at-pkg b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/at-pkg index 5f1b64bcde01..3042fa0686c6 100755 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/at-pkg +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/at-pkg @@ -23,7 +23,6 @@ atlas_depends_on_subdirs( PUBLIC TopPartons TopObjectSelectionTools TopSystematicObjectMaker - TopFakes TopDataPreparation TopHLUpgrade ) @@ -53,7 +52,6 @@ atlas_add_library( $pkgname Root/*.cxx Root/*.h Root/*.icc TopPartons TopObjectSelectionTools TopSystematicObjectMaker - TopFakes TopDataPreparation TopHLUpgrade \${ROOT_LIBRARIES} @@ -77,7 +75,6 @@ atlas_install_scripts( scripts/*.py ) # TopPartons # TopObjectSelectionTools # TopSystematicObjectMaker -# TopFakes # TopDataPreparation # TopHLUpgrade # ${ROOT_LIBRARIES} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/generate_art_configs.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/generate_art_configs.py new file mode 100755 index 000000000000..73a4050e30c6 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/generate_art_configs.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# +# Generate cut files for ARTs from validation-cuts.txt. +# To be run from directory PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share. + +import sys +import re + + +def rewriteConfig(artConfigName, inputConfigPath, campaign, overrides=None, klfitter=False, actualmurw=False): + overrides2 = {} + if overrides is not None: + overrides2.update(overrides) + overrides = overrides2 + if not actualmurw: + overrides.setdefault('PRWActualMu_FS', None) + overrides.setdefault('PRWActualMu_AF', None) + rexEol = re.compile(r'[\n\r]*$') + rexLine = re.compile(r'(\s*)(\S+)(\s+)') + rexSelection = re.compile(r'\s*(?:SELECTION|SUB)\b') + rexCampaignSpecificStart = re.compile(r'(?i)\s*#\s*(mc\w+) configuration\s*$') + rexCampaignSpecificEnd = re.compile(r'#?PRWLumiCalcFiles\b') + section = 1 # 1 = config options, 2 = selections + campaignSpecificState = None # True (False) = forcefully enable (disable) current campaign-specific set of config options + emitted = set() # which config keys have already been written + def writeln(line): + out.write(line) + out.write('\n') + with open(inputConfigPath, 'rb') as f: + with open('ART/artcut_test_' + artConfigName + '.txt', 'wb') as out: + for line in f: + line = rexEol.sub('', line) + if section == 1: + if not rexSelection.match(line): + + # hacks for per-campaign PRW configuration + m = rexCampaignSpecificStart.match(line) + if m: + campaignSpecificState = m.group(1).lower() == campaign.lower() + if campaignSpecificState and campaign.lower() == 'mc16a': + campaignSpecificState = None # mc16a enabled by default + if campaignSpecificState is False: + if rexCampaignSpecificEnd.match(line): + campaignSpecificState = None + continue + if campaignSpecificState is True and line.startswith('#PRW'): + line = line[1:] + + m = rexLine.match(line) + if m: + k = m.group(2) + if k in overrides: + if k not in emitted: + v = overrides[k] + emitted.add(k) + if v is not None: + writeln(' '.join((k, v))) + else: + writeln(line) + else: + writeln(line) + continue + # emit remaining options that did not appear in the original config file + for k, v in overrides.iteritems(): + if v is not None and k not in emitted: + writeln(' '.join((k, v))) + # done with config options + section = 2 + + if section == 2: + m = re.match('^#?((?:RECO::)?KLFITTER.*)', line) + if m: + line = m.group(1) + if not klfitter: + line = '#' + line + writeln(line) + + +rewriteConfig('410470afmc16a', 'validation-cuts.txt', 'mc16a') +rewriteConfig('410470afmc16d', 'validation-cuts.txt', 'mc16d') +rewriteConfig('410470fsmc16a', 'validation-cuts.txt', 'mc16a') +rewriteConfig('410470fsmc16d', 'validation-cuts.txt', 'mc16d') +rewriteConfig('410470fsmc16dactualmurw', 'validation-cuts.txt', 'mc16d', actualmurw=True) +rewriteConfig('410470fsmc16apflow', 'validation-cuts.txt', 'mc16a', overrides={ + 'JetCollectionName': 'AntiKt4EMPFlowJets_BTagging201810', + }) +rewriteConfig('410470fsmc16dpflow', 'validation-cuts.txt', 'mc16d', overrides={ + 'JetCollectionName': 'AntiKt4EMPFlowJets_BTagging201810', + }) +rewriteConfig('410470fsmc16asysts', 'validation-cuts.txt', 'mc16a', overrides={ + 'Systematics': 'All', + }) +rewriteConfig('410470fsmc16dsysts', 'validation-cuts.txt', 'mc16d', overrides={ + 'Systematics': 'All', + }) +rewriteConfig('410470fsmc16dklfitter', 'validation-cuts.txt', 'mc16d', klfitter=True) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/validation-data.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/validation-data.py new file mode 100755 index 000000000000..9f81a2bbacf6 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/validation-data.py @@ -0,0 +1,398 @@ +#!/usr/bin/env python + +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +import ROOT +import random,string + +import TopExamples.AtlasStyle + +import sys +import os +import re + +def thumbnail(plot, width, height): + img = ROOT.TASImage(plot) + img.Scale(width, height) + name = plot.replace('.png', '_tn.png') + img.WriteImage(name) + +def br(): + out.write('<br>\n') + +def h1(txt): + out.write('<h1>%s</h1>\n' % txt) + +def h3(txt): + out.write('<h3>%s</h3>\n' % txt) + + +# rebin histogram to add underflow and overflow bins +def addUnderOverflowBin(h): + # see https://root.cern.ch/phpBB3/viewtopic.php?t=6764 + # function to paint the histogram h with extra bins for underflows/overflows + nx = h.GetNbinsX()+1 + xbins = [] + for r in range(nx+1): + xbins.append(h.GetBinLowEdge(r)) + + xbins.append(xbins[nx-1]+h.GetBinWidth(nx)) + # book a temporary histogram having extra bins, change name to avoid memory leak warnings + xName="".join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(5)) + htmp = ROOT.TH1D(h.GetName()+xName, h.GetTitle(), nx+1, h.GetBinLowEdge(1)-h.GetBinWidth(1), xbins[nx]) + # Set up plot for markers and errors + htmp.Sumw2() + # fill the new histogram including the underflows/overflows + for r in range(nx+1): + htmp.SetBinContent(htmp.FindBin(htmp.GetBinCenter(r+1)),h.GetBinContent(r)) + htmp.SetBinError(htmp.FindBin(htmp.GetBinCenter(r+1)),h.GetBinError(r)) + + htmp.SetEntries(h.GetEffectiveEntries()) + htmp.SetXTitle(h.GetXaxis().GetTitle()) + htmp.SetYTitle(h.GetYaxis().GetTitle()) + return htmp + + +# create ratio plot +def createRatio(h1, h2): + hRatio = h1.Clone("hRatio") + hRatio.SetLineColor(ROOT.kBlack) + hRatio.SetMarkerStyle(20) + hRatio.SetTitle("") + hRatio.SetMinimum(0.8) + hRatio.SetMaximum(1.20) + #hRatio.Sumw2() # this should have already been done in addUnderOverflowBin (warnings if uncommented) + hRatio.SetStats(0) + hRatio.Divide(h2) + + # Adjust y-axis settings + y = hRatio.GetYaxis() + y.SetTitle("Ratio") + y.SetNdivisions(505) + y.SetTitleSize(20) + y.SetTitleFont(43) + y.SetTitleOffset(1.2) + y.SetLabelFont(43) + y.SetLabelSize(15) + + # Adjust x-axis settings + x = hRatio.GetXaxis() + x.SetTitleSize(20) + x.SetTitleFont(43) + x.SetTitleOffset(3.5) + x.SetLabelFont(43) + x.SetLabelSize(10) + return hRatio + + +def createCanvasPads(): + c1.cd() + # Upper histogram plot is pad1 + pad1.SetBottomMargin(0) + pad1.Draw() + # Lower ratio plot is pad2 + pad2.SetTopMargin(0) + pad2.SetBottomMargin(0.2) + pad2.SetGridx() + pad2.SetGridy() + pad2.Draw() + + +def plot(name): + legend = ROOT.TLegend(0.70, 0.80, 0.90, 0.90) + legend.SetFillColor(0) + legend.SetFillStyle(0) + legend.SetBorderSize(0) + legend.SetTextFont(72) + legend.SetTextSize(0.04) + + stack = ROOT.THStack() + h = [] # list of rebinned histograms for the stack + + for i, f in enumerate(files): + h_orig = f.Get(name) + if h_orig == None: + print "Cannot find :",name,"in",f.GetName() + return None + h.append(addUnderOverflowBin(h_orig)) + + h[i].SetLineColor(histogramStyles[i].m_linecolour) + h[i].SetLineStyle(histogramStyles[i].m_linestyle) + h[i].SetLineWidth(histogramStyles[i].m_linewidth) + h[i].SetFillColor(histogramStyles[i].m_fillcolour) + + version = re.findall("\d+[\.]?", names[i]) + if (version): + versionName = 'AT-%s'% ''.join(str(e) for e in version) + else: + versionName = names[i].replace('.root','') + legend.AddEntry(h[i], versionName, 'f') + + stack.Add(h[i]) + + #for the cutflow histograms print the number of entries on the bin + txt = 'hist nostack' + if name.find('cutflow') > -1: + txt += ' text' + + # Create different pads + createCanvasPads() + pad1.cd() + + stack.Draw(txt) + stack.GetHistogram().GetXaxis().SetTitle(h[0].GetXaxis().GetTitle()) + stack.GetHistogram().GetYaxis().SetTitle(h[0].GetYaxis().GetTitle()) + # Change the size of the numbers in the Y axis and the range + stack.GetHistogram().GetYaxis().SetLabelSize(0.04) + Ymax = stack.GetHistogram().GetMaximum() + stack.SetMaximum(Ymax+0.1*Ymax) + + legend.Draw('same') + + if len(files) == 2: + # Create ratio plot + hRatio = createRatio(h[0],h[1]) + pad2.cd() + hRatio.Draw() + + thesame = True + for i in range(1, h[0].GetNbinsX()): #h.Chi2Test better? + if h[0].GetBinContent(i) != h[1].GetBinContent(i): + thesame = False + + if not thesame: + x1 = stack.GetHistogram().GetXaxis().GetXmin() + x2 = stack.GetHistogram().GetXaxis().GetXmax() + + y1 = stack.GetHistogram().GetMinimum() + y2 = stack.GetHistogram().GetMaximum() + + pad1.cd() + box = ROOT.TBox(x1, y1, x2, y2) + box.SetFillStyle(0) + box.SetLineColor(ROOT.kRed) + box.SetLineWidth(3) + box.Draw('same') + + + #write the channel in the top right + caption = name.split('/')[0] + lmode = ROOT.TLatex() + lmode.SetTextAlign(31); #right, obviously + lmode.SetNDC() + lmode.SetTextColor(1) + lmode.SetTextFont(72) + lmode.SetTextSize(0.04) + lmode.DrawLatex(0.95, 0.96, caption) + + filename = name.replace('/','_') + '.png' + c1.Print(outputdir + '/' + filename) + thumbnail(outputdir + '/' + filename, 250, 250) + out.write('<a href="%s"><img src="%s"></a>\n' % (filename, filename.replace('.png', '_tn.png'))) + + +# electron plots +def plotElectrons(channel): + h3('Electrons') + plot(channel + '/el_true_type') + plot(channel + '/el_n') + br() + plot(channel + '/el_pt') + plot(channel + '/el_eta') + plot(channel + '/el_phi') + plot(channel + '/el_charge') + plot(channel + '/el_trkpart_charge') + br() + + plot(channel + '/el_topoetcone20') + plot(channel + '/el_topoetcone30') + plot(channel + '/el_topoetcone40') + br() + + plot(channel + '/el_ptcone20') + plot(channel + '/el_ptcone30') + plot(channel + '/el_ptcone40') + br() + + plot(channel + '/el_ptvarcone20') + plot(channel + '/el_ptvarcone30') + plot(channel + '/el_ptvarcone40') + br() + + +# muon plots +def plotMuons(channel): + h3('Muons') + plot(channel + '/mu_true_type') + plot(channel + '/mu_n') + br() + plot(channel + '/mu_pt') + plot(channel + '/mu_eta') + plot(channel + '/mu_phi') + plot(channel + '/mu_charge') + br() + + plot(channel + '/mu_topoetcone20') + plot(channel + '/mu_topoetcone30') + plot(channel + '/mu_topoetcone40') + br() + + plot(channel + '/mu_ptcone20') + plot(channel + '/mu_ptcone30') + plot(channel + '/mu_ptcone40') + br() + + plot(channel + '/mu_ptvarcone20') + plot(channel + '/mu_ptvarcone30') + plot(channel + '/mu_ptvarcone40') + br() + + +# photon plots +def plotPhotons(channel): + h3('Photons') + plot(channel + '/ph_n') + plot(channel + '/ph_pt') + plot(channel + '/ph_eta') + plot(channel + '/ph_phi') + plot(channel + '/ph_e') + plot(channel + '/ph_ptvarcone20') + br() + + +# jet and large-R jet plots +def plotJets(channel): + h3('All Jets') + plot(channel + '/jet_n') + br() + plot(channel + '/jet_pt') + plot(channel + '/jet_eta') + plot(channel + '/jet_phi') + plot(channel + '/jet_e') + br() + plot(channel + '/jet_mv2c10') + plot(channel + '/jet_truthflav') + plot(channel + '/jet_isbtagged_MV2c10_77') + plot(channel + '/jet_btagSF_MV2c10_77') + + for i in range(4): + h3('Jet%d' % i) + plot(channel + '/jet%d_pt' % i) + plot(channel + '/jet%d_eta' % i) + plot(channel + '/jet%d_phi' % i) + plot(channel + '/jet%d_e' % i) + br() + plot(channel + '/jet%d_mv2c10' % i) + plot(channel + '/jet%d_truthflav' % i) + plot(channel + '/jet%d_isbtagged_MV2c10_77' % i) + plot(channel + '/jet%d_btagSF_MV2c10_77' % i) + + h3('Large-R jet') + plot(channel + '/ljet_n') + plot(channel + '/ljet_pt') + plot(channel + '/ljet_eta') + plot(channel + '/ljet_phi') + plot(channel + '/ljet_m') + plot(channel + '/ljet_sd12') + + + +# tau plots +def plotTau(channel): + h3('Tau') + plot(channel + '/taujet_n') + plot(channel + '/taujet_pt') + plot(channel + '/taujet_eta') + plot(channel + '/taujet_phi') + plot(channel + '/taujet_charge') + + + +ROOT.gROOT.SetBatch(True) + +channels = ['ejets_2015', 'ejets_2016', 'mujets_2015', 'mujets_2016', 'ee_2015', 'ee_2016', 'mumu_2015', 'mumu_2016', 'emu_2015', 'emu_2016'] +particles = ['Electrons', 'Muons', 'Photons', 'Jets', 'Tau', 'MET'] + + +if len(sys.argv) < 2: + print 'Try:' + print 'python %s outputdir/ primary.root rel_1.root' % sys.argv[0] + sys.exit() + +outputdir = sys.argv[1] + +names = sys.argv[2:] +print 'Expecting these files', names + +#try to make it, but don't worry too much if it already exists +try: + os.mkdir(outputdir) +except: + pass + +class HistStyle: + def __init__(self, linecolour, linestyle, linewidth, fillcolour): + self.m_linecolour = linecolour + self.m_linestyle = linestyle + self.m_linewidth = linewidth + self.m_fillcolour = fillcolour + +histogramStyles = [ + HistStyle(ROOT.kYellow, 1, 3, ROOT.kYellow), + HistStyle(ROOT.kBlack, 2, 3, 0), + HistStyle(ROOT.kRed, 3, 3, 0), + HistStyle(ROOT.kGreen, 4, 3, 0), + HistStyle(ROOT.kBlue, 5, 3, 0), + HistStyle(ROOT.kGray, 6, 3, ROOT.kGray), +] + +files = [] +for name in names: + files.append(ROOT.TFile.Open(name)) + +if len(files) > len(histogramStyles): + print 'You are trying to open more files than we have styles' + print 'edit the histogramStyles list and add some more' + sys.exit(1) + +out = open(outputdir + '/index.html', 'w') +c1 = ROOT.TCanvas('c1', '', 600, 600) +pad1 = ROOT.TPad("pad1", "pad1", 0, 0.3, 1, 1.0) +pad2 = ROOT.TPad("pad2", "pad2", 0, 0.05, 1, 0.3) + +h3('Cutflows') +for channel in channels: + plot(channel + '/cutflow') + +for channel in channels: + h1(channel) + + h3('Event stuff') + plot(channel + '/mc_weight') + plot(channel + '/pileup_weight') + plot(channel + '/event_mu') + plot(channel + '/jvt_SF') + + print channel + + if 'Electrons' in particles: + plotElectrons(channel) + + if 'Muons' in particles: + plotMuons(channel) + + if 'Photons' in particles: + plotPhotons(channel) + + if 'Jets' in particles: + plotJets(channel) + + if 'Taus' in particles: + plotTaus(channel) + + + h3('MET') + plot(channel + '/event_met_et') + plot(channel + '/event_met_phi') + +out.close() diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/validation.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/validation.py index 0b4cc37b6445..9c0b17d53b91 100755 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/validation.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/scripts/validation.py @@ -269,8 +269,8 @@ def plotJets(channel): br() plot(channel + '/jet_mv2c10') plot(channel + '/jet_truthflav') - plot(channel + '/jet_isbtagged_77') - plot(channel + '/jet_btagSF_77') + plot(channel + '/jet_isbtagged_MV2c10_77') + plot(channel + '/jet_btagSF_MV2c10_77') for i in range(4): h3('Jet%d' % i) @@ -281,8 +281,8 @@ def plotJets(channel): br() plot(channel + '/jet%d_mv2c10' % i) plot(channel + '/jet%d_truthflav' % i) - plot(channel + '/jet%d_isbtagged_77' % i) - plot(channel + '/jet%d_btagSF_77' % i) + plot(channel + '/jet%d_isbtagged_MV2c10_77' % i) + plot(channel + '/jet%d_btagSF_MV2c10_77' % i) h3('Large-R jet') plot(channel + '/ljet_n') diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470afmc16a.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470afmc16a.txt new file mode 100644 index 000000000000..7d88e74845da --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470afmc16a.txt @@ -0,0 +1,666 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use +# MC16a configuration + +### This setup is for the CI tests +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/CI.prw.merged.root + +### Use following lines (uncomment) for your config file +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/prw.merged.root + +PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20170619/PHYS_StandardGRL_All_Good_25ns_276262-284484_OflLumi-13TeV-008.root GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root + + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470afmc16d.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470afmc16d.txt new file mode 100644 index 000000000000..8593ff03c6c5 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470afmc16d.txt @@ -0,0 +1,659 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use + +# MC16d configuration +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.AF.v2/CI.prw.merged.root +PRWLumiCalcFiles GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.lumicalc.OflLumi-13TeV-010.root + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16a.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16a.txt new file mode 100644 index 000000000000..7d88e74845da --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16a.txt @@ -0,0 +1,666 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use +# MC16a configuration + +### This setup is for the CI tests +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/CI.prw.merged.root + +### Use following lines (uncomment) for your config file +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/prw.merged.root + +PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20170619/PHYS_StandardGRL_All_Good_25ns_276262-284484_OflLumi-13TeV-008.root GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root + + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16apflow.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16apflow.txt new file mode 100644 index 000000000000..8efe455701e0 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16apflow.txt @@ -0,0 +1,666 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use +# MC16a configuration + +### This setup is for the CI tests +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/CI.prw.merged.root + +### Use following lines (uncomment) for your config file +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/prw.merged.root + +PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20170619/PHYS_StandardGRL_All_Good_25ns_276262-284484_OflLumi-13TeV-008.root GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root + + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMPFlowJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16asysts.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16asysts.txt new file mode 100644 index 000000000000..44ef3f743ce1 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16asysts.txt @@ -0,0 +1,666 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use +# MC16a configuration + +### This setup is for the CI tests +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/CI.prw.merged.root + +### Use following lines (uncomment) for your config file +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/prw.merged.root + +PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20170619/PHYS_StandardGRL_All_Good_25ns_276262-284484_OflLumi-13TeV-008.root GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root + + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics All +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16d.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16d.txt new file mode 100644 index 000000000000..8593ff03c6c5 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16d.txt @@ -0,0 +1,659 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use + +# MC16d configuration +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.AF.v2/CI.prw.merged.root +PRWLumiCalcFiles GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.lumicalc.OflLumi-13TeV-010.root + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dactualmurw.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dactualmurw.txt new file mode 100644 index 000000000000..0294a1b39b25 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dactualmurw.txt @@ -0,0 +1,661 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use + +# MC16d configuration +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.AF.v2/CI.prw.merged.root +PRWActualMu_FS GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +PRWActualMu_AF GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +PRWLumiCalcFiles GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.lumicalc.OflLumi-13TeV-010.root + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dklfitter.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dklfitter.txt new file mode 100644 index 000000000000..27778c324d5f --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dklfitter.txt @@ -0,0 +1,659 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use + +# MC16d configuration +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.AF.v2/CI.prw.merged.root +PRWLumiCalcFiles GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.lumicalc.OflLumi-13TeV-010.root + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dpflow.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dpflow.txt new file mode 100644 index 000000000000..379fac330b98 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dpflow.txt @@ -0,0 +1,659 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use + +# MC16d configuration +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.AF.v2/CI.prw.merged.root +PRWLumiCalcFiles GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.lumicalc.OflLumi-13TeV-010.root + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMPFlowJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dsysts.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dsysts.txt new file mode 100644 index 000000000000..3fffa54bfc6f --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/ART/artcut_test_410470fsmc16dsysts.txt @@ -0,0 +1,659 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use + +# MC16d configuration +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.AF.v2/CI.prw.merged.root +PRWLumiCalcFiles GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.lumicalc.OflLumi-13TeV-010.root + + +BTagCDIPath xAODBTaggingEfficiency/13TeV/2019-21-13TeV-MC16-CDI-2019-10-07_v1.root + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics All +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None + +### Tau configuration +TauPt 25000 +TauJetIDWP Medium +TauJetIDWPLoose Medium +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingWP MV2c10:FixedCutBEff_77 MV2c10:Continuous DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/example-config.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/example-config.txt new file mode 100644 index 000000000000..89ad1df916dc --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/example-config.txt @@ -0,0 +1,286 @@ +#this is an example configuration file for AnalysisTop; refer to https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21 for a guide on most common options +#IMPORTANT: THIS IS ONLY AN EXAMPLE AND NOT A RECOMMENDATION OF THE BEST CONFIGURATION TO BE USED (because there is no single configuration optimal for all cases) +#the values used for all the possible config options are printed at the beginning of the execution of top-xaod +#all options not explicitely configured in the file use the default values +#all available options and their default values can be seen here https://gitlab.cern.ch/atlas/athena/-/blob/21.2/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx +#(this is the default link for the HEAD version, if you're using a specific release, search e.g. "21.2.XXX" from the drop-down release menu to see the one relative to your version) + +############General setup########### +#these are the libraries included for the execution. Update if you add a package (e.g. if you add MyCustomSaver, you have to add libMyCustomSaver to the list below) +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +#use this to run on a limited number of events; comment to run on all events in the input files provided via the filelist +#NEvents 500 + +#if you want to use a custom object selection, in case existing configurable options are not enough, change this (see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#5_Extend_AnalysisTop_for_your_ow ) +ObjectSelectionName top::ObjectLoaderStandardCuts +#if you want to use a custom event saver, change this (see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#5_Extend_AnalysisTop_for_your_ow ) +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents # AllEvents-> store all events, SelectedEvents -> store events passing at least one of the event-level selections (defined below) +OutputFilename output.root + +# DoTight/DoLoose to activate the loose and tight trees, can be: Data, MC, Both, False. Loose trees are tipically used for multijetestimation in data, see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#Systematics +DoTight Both +DoLoose Data + +### Systematics you want to run +Systematics Nominal #Nominal->only nominal. All -> all systematics (will be much slower). You can also use AllMuons, AllJets... see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#Systematics + +#If you use MedaData (as you usually should) IsAFII (needed for fast simulation) is automatically set, see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#FullSim_vs_AFII +UseAodMetaData True +#IsAFII False + +############GRL and PRW############# +#here Good Run List and Pileup Reweighting settings are provided, see https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/TopGroupDataDerivationList#Lumicalc_GRL_and_PRW_files for the most update settings + +##these are the settings for MC16a +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/prw.merged.root +PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20170619/PHYS_StandardGRL_All_Good_25ns_276262-284484_OflLumi-13TeV-008.root GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root + +###########Reco-level object definitions (i.e. object-level selection)########## + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMPFlowJets_BTagging201903 +LargeJetCollectionName None # can be e.g. AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName None #can be e.g. TauJets +PhotonCollectionName None #can be e.g. Photons +TrackJetCollectionName None #can be e.g. AntiKtVR30Rmax4Rmin02TrackJets_BTagging201903 +JetGhostTrackDecoName None # can be e.g. GhostTrack + +### Electron configuration +ElectronPt 25000 +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation FCTight +ElectronIsolationLoose None + +### Muon configuration +MuonPt 25000 +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation FCTight_FixedRad +MuonIsolationLoose None +doExtraSmearing False +do2StationsHighPt False + +### Jet configuration +JetPt 25000 +JVTWP Default + +### B-tagging configuration +BTaggingCaloJetWP DL1r:FixedCutBEff_77 +# for track jet, use BTaggingTrackJetWP option + +###########Reco-level systematics models########## +ElectronEfficiencySystematicModel TOTAL +EgammaSystematicModel 1NP_v1 #egamma calibration uncertainties model +JetUncertainties_NPModel CategoryReduction #JES +JetJERSmearingModel Simple #JER + +###########Truth-level settings########## +#see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#Truth_options for more info +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthDressedWZJets +TruthLargeRJetCollectionName None # can be AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory False # can be e.g. ttbar +TopPartonLevel False #this option only exists for recent releases; it switches on/off writing the "truth" partol-level tree +TopParticleLevel False #this switches on/off writing the "particleLevel" tree +TruthBlockInfo False +PDFInfo True + +############################################## +#############Event-level selections########### +############################################## +###more info here https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#Which_event_level_cuts_can_I_use +###see https://gitlab.cern.ch/atlas/athena/-/blob/21.2/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts-pflow.txt for some more complicated examples +### here we have just very simple selections for ttbar e+jets/mu+jets channels +### these should be considered as a simple example AND NOT as suggestions for real analyses, that should carefully evaluate the selections applied + +#####General definition of periods##### + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + +#####Reco-level definitions###### + +### basic sub-selections with mandatory cuts for reco level + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +### lepton trigger and offline cuts sub-selections + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +### e+jets selections + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +#RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:DL1r:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +### mu+jets selections + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +#RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:DL1r:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +##### particle-level selection ##### + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/input-data-rel21.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/input-data-rel21.txt index 158d152f748c..02a97f994bee 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/input-data-rel21.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/input-data-rel21.txt @@ -1,10 +1 @@ -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000027.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000153.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000393.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000073.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000228.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000422.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000132.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000279.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000146.pool.root.1 -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/data/data16_13TeV.00311321.physics_Main.deriv.DAOD_TOPQ1.r9264_p3083_p3142/DAOD_TOPQ1.11286123._000368.pool.root.1 +/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/dev/AnalysisTop/ContinuousIntegration/Data/p4173/data16_13TeV.AllYear.physics_Main.PhysCont.DAOD_TOPQ1.grp16_v01_p4173/DAOD_TOPQ1.21542408._000018.pool.root.1 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/input-mc-rel21.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/input-mc-rel21.txt index c37f9f0daa93..d1b25bc90b75 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/input-mc-rel21.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/input-mc-rel21.txt @@ -1 +1 @@ -root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/phys-top/topreco/rel21/mc/group.phys-top.11303793.EXT0._000011.DAOD_TOPQ1.DAOD.root +/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/dev/AnalysisTop/ContinuousIntegration/MC/p4174/mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_s3126_r9364_p4174/test.pool.root diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/nocuts.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/nocuts.txt index c958a57ad82f..c259eb231b94 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/nocuts.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/nocuts.txt @@ -43,12 +43,13 @@ ElectronIsolationLoose None MuonQuality Medium MuonQualityLoose Medium -MuonIsolation Gradient +MuonIsolation PflowTight_FixedRad MuonIsolationLoose None -FakesControlRegionDoLooseMC False -OverlapRemovalLeptonDef Tight -ApplyElectronInJetSubtraction False +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data NEvents 2000 diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/upgrade-cuts.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/upgrade-cuts.txt new file mode 100644 index 000000000000..00de68ae65e7 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/upgrade-cuts.txt @@ -0,0 +1,364 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +#These aren't used in upgrade studies, just filled so top-xaod doesn't complain +GRLDir GoodRunsLists +GRLFile data15_13TeV/20160720/physics_25ns_20.7.xml data16_13TeV/20161101/physics_25ns_20.7.xml +PRWConfigFiles +PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20160720/physics_25ns_20.7.lumicalc.OflLumi-13TeV-005.root GoodRunsLists/data16_13TeV/20161101/physics_25ns_20.7.lumicalc.OflLumi-13TeV-005.root + +TDPPath TopUpgradeGrid/XSection-MC15-14TeV.data +MCGeneratorWeights True + + +ElectronCollectionName None +MuonCollectionName None +JetCollectionName None +LargeJetCollectionName None +LargeJetSubstructure None +TauCollectionName None +PhotonCollectionName None + +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthDressedWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +TruthPhotonCollectionName TruthPhotons +PDFInfo True + +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + +Systematics All +JetUncertainties_NPModel GlobalReduction + +ElectronID MediumLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation Gradient +ElectronIsolationLoose None +ElectronPt 7000. + +MuonQuality Medium +MuonQualityLoose Medium +MuonIsolation Gradient +MuonIsolationLoose None +MuonPt 4000. #j/psi +TruthMuonPt 4000. #j/psi + +JetPt 25000. +JetEta 2.5 + +TruthPhotonEta 2.37 #default is 2.5 +TruthPhotonPt 15000. #default is 25000. +#PhotonID None #default is Tight +#PhotonIDLoose None #default is Loose +#PhotonIsolation None #default is FixedCutTight +#PhotonIsolationLoose None #default is FixedCutLoose + + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +UseAodMetaData False +IsAFII False + +BTaggingCaloJetWP FixedCutBEff_77 + +HLLHC True +HLLHCFakes True + + +######################## +### Muon+jets selection +######################## +SELECTION mujets_upgrade +INITIAL +MU_N 25000 >= 1 +EL_N 25000 == 0 +MU_N 25000 == 1 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +SAVE + +######################## +### Electron+jets selection +######################## +SELECTION ejets_upgrade +INITIAL +EL_N 25000 >= 1 +MU_N 25000 == 0 +EL_N 25000 == 1 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +SAVE + + +######################## +### Muon+1jet selection +######################## +SELECTION mu1jet_upgrade +INITIAL +MU_N 25000 >= 1 +EL_N 25000 == 0 +MU_N 25000 == 1 +JET_N 25000 >= 1 +SAVE + +######################## +### Electron+1jet selection +######################## +SELECTION e1jet_upgrade +INITIAL +EL_N 25000 >= 1 +MU_N 25000 == 0 +EL_N 25000 == 1 +JET_N 25000 >= 1 +SAVE + + +### ttV +#TRILEPTON + +### +### dead cone: +### +SELECTION deadcone +INITIAL +EL_N 25000 == 1 +MU_N 25000 == 0 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MET > 25000 +#JET_N_BTAG FixedCutBEff_85 >= 1 +LJET_N 200000 >= 2 +LJET_N 300000 >= 1 +#LJET_TOPTAGGED tagged_80 == 1 +#LJET_CONTAINS_LEPTON 200000 == 1 +#LJET_CONTAINS_B_AND_LEPTON FixedCutBEff_85 >= 1 +#LEPTONIC_B_LJET_DECOMPOSED ungroomed == 1 +SAVE + +SELECTION mujets_trimming_basic +INITIAL +MU_N 25000 == 1 +EL_N 25000 == 0 +TRIGMATCH +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MET > 25000 +#JET_N_BTAG FixedCutBEff_85 >= 1 +LJET_N 200000 >= 2 +LJET_N 300000 >= 1 +#LJET_TOPTAGGED tagged_80 == 1 +#LJET_CONTAINS_LEPTON 200000 == 1 +#LJET_CONTAINS_B_AND_LEPTON FixedCutBEff_85 >= 1 +#LEPTONIC_B_LJET_DECOMPOSED trimming == 1 +SAVE + +### ======== ttgamma: + +SELECTION ejets_gamma_basic +INITIAL +EL_N 25000 == 1 +MU_N 25000 == 0 +TRIGMATCH +JETCLEAN LooseBad +NOBADMUON +PH_N 10000 >= 1 +SAVE + +SELECTION mujets_gamma_basic +INITIAL +MU_N 25000 == 1 +EL_N 25000 == 0 +TRIGMATCH +JETCLEAN LooseBad +NOBADMUON +PH_N 10000 >= 1 +SAVE + +SELECTION emu_gamma_basic +INITIAL +EL_N 25000 >= 1 +MU_N 25000 >= 1 +TRIGMATCH +JETCLEAN LooseBad +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +#MLL > 15000 +NOBADMUON +PH_N 10000 >= 1 +SAVE + +SELECTION ee_gamma_basic +INITIAL +EL_N 25000 >= 2 +TRIGMATCH +JETCLEAN LooseBad +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +#MLL > 15000 +NOBADMUON +PH_N 10000 >= 1 +SAVE + +SELECTION mumu_gamma_basic +INITIAL +MU_N 25000 >= 2 +TRIGMATCH +JETCLEAN LooseBad +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +#MLL > 15000 +NOBADMUON +PH_N 10000 >= 1 +SAVE + + +###======== tZ: + +SELECTION mumumu +INITIAL +MU_N 15000 >= 3 +MU_N 15000 == 3 +EL_N 15000 == 0 +JET_N 30000 >= 1 +JET_N 30000 >= 2 +SAVE + +SELECTION eee +INITIAL +EL_N 15000 >= 3 +EL_N 15000 == 3 +MU_N 15000 == 0 +JET_N 30000 >= 1 +JET_N 30000 >= 2 +SAVE + +SELECTION eemu +INITIAL +MU_N 15000 >= 1 +EL_N 15000 >= 1 +EL_N 15000 >= 2 +MU_N 15000 == 1 +EL_N 15000 == 2 +JET_N 30000 >= 1 +JET_N 30000 >= 2 +SAVE + +SELECTION emumu +INITIAL +EL_N 15000 >= 1 +MU_N 15000 >= 1 +MU_N 15000 >= 2 +EL_N 15000 == 1 +MU_N 15000 == 2 +JET_N 30000 >= 1 +JET_N 30000 >= 2 +SAVE + +###======== Jpsi top mass: +### l+>=4 jets && all other muons (i need to go as low as 4 GeV tight muons). + +SELECTION ejets_jpsi_basic +INITIAL +EL_N 25000 == 1 +MU_N 25000 == 0 +TRIGMATCH +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +SAVE + +SELECTION mujets_jpsi_basic +INITIAL +MU_N 25000 >= 1 +EL_N 25000 == 0 +TRIGMATCH +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +SAVE + + +###======== t->Zq FCNC: +SELECTION sel1_tZq +INITIAL +EL_N 15000 == 1 +MU_N 15000 == 2 +JET_N 25000 >= 1 +SAVE + +SELECTION sel2_tZq +INITIAL +MU_N 15000 == 1 +EL_N 15000 == 2 +JET_N 25000 >= 1 +SAVE + +SELECTION sel3_tZq +INITIAL +EL_N 15000 == 3 +MU_N 15000 == 0 +JET_N 25000 >= 1 +SAVE + +SELECTION sel4_tZq +INITIAL +MU_N 15000 == 3 +EL_N 15000 == 0 +JET_N 25000 >= 1 +SAVE + +######################## +### Di-muon selection +######################## +SELECTION mumu +INITIAL +MU_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +#MLL > 15000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +SAVE + +######################## +### Di-electron selection +######################## +SELECTION ee +INITIAL +EL_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +#MLL > 15000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +SAVE + +######################## +### e-mu selection +######################## +SELECTION emu +INITIAL +MU_N 25000 >= 1 +EL_N 25000 >= 1 +MU_N 25000 == 1 +EL_N 25000 == 1 +#MLL > 15000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts-pflow.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts-pflow.txt new file mode 100644 index 000000000000..b02b1726c68f --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts-pflow.txt @@ -0,0 +1,637 @@ +LibraryNames libTopEventSelectionTools libTopEventReconstructionTools + +### Good Run List +GRLDir GoodRunsLists +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml + +### Pile-up reweighting tool - Metadata determines which to use +# MC16a configuration + +### This setup is for the CI tests +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/CI.prw.merged.root + +### Use following lines (uncomment) for your config file +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/prw.merged.root + +PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20170619/PHYS_StandardGRL_All_Good_25ns_276262-284484_OflLumi-13TeV-008.root GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root + +# MC16d configuration +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.FS.v2/CI.prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.AF.v2/CI.prw.merged.root +#PRWActualMu_FS GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +#PRWActualMu_AF GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +#PRWLumiCalcFiles GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.lumicalc.OflLumi-13TeV-010.root + +# MC16e configuration +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16e.FS.v2/prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16e.AF.v2/prw.merged.root +#PRWActualMu_FS GoodRunsLists/data18_13TeV/20190318/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +#PRWActualMu_AF GoodRunsLists/data18_13TeV/20190318/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +#PRWLumiCalcFiles GoodRunsLists/data18_13TeV/20190318/ilumicalc_histograms_None_348885-364292_OflLumi-13TeV-010.root + +#setup of TDP file, comment the following line to use the default one instead +TDPPath dev/AnalysisTop/TopDataPreparation/CI-XSection-MC16-13TeV.data + +### Object container names +ElectronCollectionName Electrons +MuonCollectionName Muons +JetCollectionName AntiKt4EMPFlowJets_BTagging201903 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets_BTagging201903 +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass +LargeRJetPt 200000 +LargeRJetEta 2 +LargeJetSubstructure None + +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration +TruthCollectionName TruthParticles +TruthJetCollectionName AntiKt4TruthDressedWZJets +TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets +TopPartonHistory ttbar +TopParticleLevel True +TruthBlockInfo False +PDFInfo True + +### Object loader/ output configuration +ObjectSelectionName top::ObjectLoaderStandardCuts +OutputFormat top::EventSaverFlatNtuple +OutputEvents SelectedEvents +OutputFilename output.root +PerfStats No + + +### Systematics configuration +Systematics Nominal +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction + +### Electron configuration +ElectronID TightLH +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation FCTight +ElectronIsolationLoose None + +### Photon configuration +PhotonPt 25000 +PhotonEta 2.5 +PhotonID Tight +PhotonIDLoose Loose +PhotonIsolation FixedCutTight +PhotonIsolationLoose FixedCutLoose +PhotonUseRadiativeZ False + +### Muon configuration +MuonQuality Medium +MuonUseMVALowPt False +MuonUse2stationHighPt True +MuonIsolation PflowTight_FixedRad +MuonQualityLoose Medium +MuonUseMVALowPtLoose False +MuonUse2stationHighPtLoose True +MuonIsolationLoose None +MuonDoExtraSmearingHighPt False +MuonDoSmearing2stationHighPt True + +### Tau configuration +TauPt 25000 +TauJetIDWP RNNMedium +TauJetIDWPLoose RNNLoose +TauEleBDTWP Loose +TauEleBDTWPLoose Loose +TauEleOLR False +TauEleOLRLoose False + +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False + +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 + +### B-tagging configuration +BTaggingCaloJetWP DL1:Continuous DL1r:FixedCutBEff_77 +BTaggingTrackJetWP DL1:Continuous DL1r:FixedCutBEff_77 +# Example of how to remove systematics from b-tag EV + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 + +#NEvents 500 + +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + +######################## +### basic selection with mandatory cuts for reco level +######################## + +SUB BASIC +INITIAL +GRL +GOODCALO +PRIVTX +RECO_LEVEL + +######################## +### definition of the data periods +######################## + +SUB period_2015 +RUN_NUMBER >= 276262 +RUN_NUMBER <= 284484 + +SUB period_2016 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + + +######################## +### lepton trigger and offline cuts for reco-level selections +######################## + +SUB EL_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N 25000 >= 1 + +SUB EL_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N 27000 >= 1 + +SUB MU_2015 +. BASIC +. period_2015 +GTRIGDEC +MU_N 25000 >= 1 + +SUB MU_2016 +. BASIC +. period_2016 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC +MU_N 27000 >= 1 + +SUB EM_2015 +. BASIC +. period_2015 +GTRIGDEC +EL_N_OR_MU_N 25000 >= 1 + +SUB EM_2016 +. BASIC +. period_2016 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +######################## +### e+jets selections +######################## + +SUB ejets_basic +EL_N 25000 == 1 +MU_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET > 30000 +MWT > 30000 +RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:DL1r:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION ejets_2015 +. EL_2015 +. ejets_basic +SAVE + +SELECTION ejets_2016 +. EL_2016 +. ejets_basic +SAVE + +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_DL1r_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_DL1r_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_DL1r_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_DL1r_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_DL1r_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_DL1r_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION ejets_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ejets_basic +SAVE + +######################## +### mu+jets selections +######################## + +SUB mujets_basic +MU_N 25000 == 1 +EL_N 25000 == 0 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +JET_N 25000 >= 1 +JET_N 25000 >= 2 +JET_N 25000 >= 3 +JET_N 25000 >= 4 +MET+MWT > 60000 +RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:DL1r:FixedCutBEff_77 +#KLFITTER > -50.0 +EXAMPLEPLOTS +#PRINT +NOBADMUON + +SELECTION mujets_2015 +. MU_2015 +. mujets_basic +SAVE + +SELECTION mujets_2016 +. MU_2016 +. mujets_basic +SAVE + +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_DL1r_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_DL1r_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_DL1r_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_DL1r_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_DL1r_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_DL1r_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG DL1r:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + +SELECTION mujets_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mujets_basic +SAVE + +######################## +### emu selections +######################## + +SUB emu_basic +EL_N 25000 >= 1 +MU_N 25000 >= 1 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +HT > 120000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 1 +MU_N 25000 == 1 +OS +MLL > 15000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +NOBADMUON + +SELECTION emu_2015 +. EM_2015 +. emu_basic +SAVE + +SELECTION emu_2016 +. EM_2016 +. emu_basic +SAVE + +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + +SELECTION emu_particle +PRIVTX +PARTICLE_LEVEL +EL_N_OR_MU_N 27000 >= 1 +. emu_basic +SAVE + +######################## +### ee selections +######################## + +SUB ee_basic +EL_N 25000 >= 2 +GTRIGMATCH +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +EL_N 25000 == 2 +MU_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION ee_2015 +. EL_2015 +. ee_basic +SAVE + +SELECTION ee_2016 +. EL_2016 +. ee_basic +SAVE + +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + +SELECTION ee_particle +PRIVTX +PARTICLE_LEVEL +EL_N 27000 >= 1 +. ee_basic +SAVE + +######################## +### mumu selections +######################## + +SUB mumu_basic +MU_N 25000 >= 2 +GTRIGMATCH +#EMU_OVERLAP +JETCLEAN LooseBad +MET > 60000 +JET_N 25000 >= 1 +JET_N 25000 >= 2 +MU_N 25000 == 2 +EL_N 25000 == 0 +OS +MLL > 15000 +MLLWIN 80000 100000 +#TRUTH_MATCH +#JET_N_BTAG FixedCutBEff_77 >= 1 +EXAMPLEPLOTS +#JET_N_BTAG FixedCutBEff_77 > 1 +NOBADMUON + +SELECTION mumu_2015 +. MU_2015 +. mumu_basic +SAVE + +SELECTION mumu_2016 +. MU_2016 +. mumu_basic +SAVE + +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + +SELECTION mumu_particle +PRIVTX +PARTICLE_LEVEL +MU_N 27000 >= 1 +. mumu_basic +SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts.txt index 1502a9b738a0..a2c0ac8a2a27 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/share/validation-cuts.txt @@ -2,28 +2,63 @@ LibraryNames libTopEventSelectionTools libTopEventReconstructionTools ### Good Run List GRLDir GoodRunsLists -GRLFile data15_13TeV/20160720/physics_25ns_20.7.xml data16_13TeV/20170215/physics_25ns_20.7.xml - -### Pile-up reweighting tool - this is now mandatory -### Now requires only PRWLumiCalcFiles -### No PRWDefaultChannel anymore -### The nominal mc15c PU distribution is now appended to PRWConfigFiles automatically -### Will hence be using mc15c_v2_defaults.NotRecommended.prw.root if nothing is provided for PRWConfigFiles -# PRWConfigFiles TopCorrections/PRW.410000.mc15c.r7725_r7676.root -PRWConfigFiles -PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20160720/physics_25ns_20.7.lumicalc.OflLumi-13TeV-005.root GoodRunsLists/data16_13TeV/20170215/physics_25ns_20.7.lumicalc.OflLumi-13TeV-008.root -# no PRWDefaultChannel anymore +GRLFile data15_13TeV/20170619/physics_25ns_21.0.19.xml data16_13TeV/20180129/physics_25ns_21.0.19.xml data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml +### Pile-up reweighting tool - Metadata determines which to use +# MC16a configuration + +### This setup is for the CI tests +PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/CI.prw.merged.root +PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/CI.prw.merged.root + +### Use following lines (uncomment) for your config file +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.FS.v2/prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16a.AF.v2/prw.merged.root + +PRWLumiCalcFiles GoodRunsLists/data15_13TeV/20170619/PHYS_StandardGRL_All_Good_25ns_276262-284484_OflLumi-13TeV-008.root GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root + +# MC16d configuration +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.FS.v2/CI.prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16d.AF.v2/CI.prw.merged.root +#PRWActualMu_FS GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +#PRWActualMu_AF GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +#PRWLumiCalcFiles GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.lumicalc.OflLumi-13TeV-010.root + +# MC16e configuration +#PRWConfigFiles_FS dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16e.FS.v2/prw.merged.root +#PRWConfigFiles_AF dev/AnalysisTop/PileupReweighting/user.iconnell.Top.PRW.MC16e.AF.v2/prw.merged.root +#PRWActualMu_FS GoodRunsLists/data18_13TeV/20190318/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +#PRWActualMu_AF GoodRunsLists/data18_13TeV/20190318/physics_25ns_Triggerno17e33prim.actualMu.OflLumi-13TeV-010.root +#PRWLumiCalcFiles GoodRunsLists/data18_13TeV/20190318/ilumicalc_histograms_None_348885-364292_OflLumi-13TeV-010.root + +#setup of TDP file, comment the following line to use the default one instead +TDPPath dev/AnalysisTop/TopDataPreparation/CI-XSection-MC16-13TeV.data + +### Object container names ElectronCollectionName Electrons MuonCollectionName Muons -JetCollectionName AntiKt4EMTopoJets -LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +JetCollectionName AntiKt4EMTopoJets_BTagging201810 +LargeJetCollectionName AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets +TauCollectionName TauJets +PhotonCollectionName Photons +TrackJetCollectionName AntiKtVR30Rmax4Rmin02TrackJets_BTagging201810 +JetGhostTrackDecoName GhostTrack + +### Large-R configuration +LargeRJESJMSConfig CombMass LargeRJetPt 200000 LargeRJetEta 2 LargeJetSubstructure None -TauCollectionName TauJets -PhotonCollectionName Photons +### Reclustered jet configuration +UseRCJets True +#UseRCJetSubstructure True +RCJetEta 2.0 +UseVarRCJets True +VarRCJetMassScale m_w,m_t +VarRCJetRho 2 + +### Truth configuration TruthCollectionName TruthParticles TruthJetCollectionName AntiKt4TruthWZJets TruthLargeRJetCollectionName AntiKt10TruthTrimmedPtFrac5SmallR20Jets @@ -32,22 +67,26 @@ TopParticleLevel True TruthBlockInfo False PDFInfo True +### Object loader/ output configuration ObjectSelectionName top::ObjectLoaderStandardCuts OutputFormat top::EventSaverFlatNtuple OutputEvents SelectedEvents OutputFilename output.root PerfStats No + +### Systematics configuration Systematics Nominal -JetUncertainties_NPModel 21NP -JetUncertainties_BunchSpacing 25ns -LargeRJESUncertaintyConfig Split23,Tau32WTA +JetUncertainties_NPModel CategoryReduction +LargeRJetUncertainties_NPModel CategoryReduction +### Electron configuration ElectronID TightLH -ElectronIDLoose MediumLH -ElectronIsolation Gradient +ElectronIDLoose LooseAndBLayerLH +ElectronIsolation FCTight ElectronIsolationLoose None +### Photon configuration PhotonPt 25000 PhotonEta 2.5 PhotonID Tight @@ -56,30 +95,56 @@ PhotonIsolation FixedCutTight PhotonIsolationLoose FixedCutLoose PhotonUseRadiativeZ False +### Muon configuration MuonQuality Medium +MuonUseMVALowPt False +MuonUse2stationHighPt True +MuonIsolation PflowTight_FixedRad MuonQualityLoose Medium -MuonIsolation Gradient +MuonUseMVALowPtLoose False +MuonUse2stationHighPtLoose True MuonIsolationLoose None +MuonDoExtraSmearingHighPt False +MuonDoSmearing2stationHighPt True +### Tau configuration TauPt 25000 -TauJetIDWP Medium -TauJetIDWPLoose Medium +TauJetIDWP RNNMedium +TauJetIDWPLoose RNNLoose TauEleBDTWP Loose TauEleBDTWPLoose Loose TauEleOLR False TauEleOLRLoose False -FakesControlRegionDoLooseMC False -OverlapRemovalLeptonDef Tight -ApplyElectronInJetSubtraction False +# DoTight/DoLoose to activate the loose and tight trees +# each should be one in: Data, MC, Both, False +DoTight Both +DoLoose Data + +# Turn on MetaData to pull IsAFII from metadata +UseAodMetaData True +#IsAFII False -UseAodMetaData False -IsAFII False +### Boosted jet taggers configuration +BoostedJetTagging JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50 JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50 JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80 -BTaggingWP FixedCutBEff_77 +### B-tagging configuration +BTaggingCaloJetWP MV2c10:FixedCutBEff_77 MV2c10:Continuous +BTaggingTrackJetWP MV2c10:FixedCutBEff_77 MV2c10:Continuous +# Example of how to remove systematics from b-tag EV +#BTaggingSystExcludedFromEV FT_EFF_JET_BJES_Response;FT_EFF_JET_EffectiveNP_1;FT_EFF_EG_RESOLUTION_ALL + +# Saving bootstrapping weights +SaveBootstrapWeights False +NumberOfBootstrapReplicas 100 #NEvents 500 +### Global lepton trigger scale factor example +UseGlobalLeptonTriggerSF True +GlobalTriggers 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 +GlobalTriggersLoose 2015@e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose,mu20_iloose_L1MU15_OR_mu50 2016@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2017@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 2018@e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0,mu26_ivarmedium_OR_mu50 + ######################## ### basic selection with mandatory cuts for reco level ######################## @@ -100,7 +165,16 @@ RUN_NUMBER >= 276262 RUN_NUMBER <= 284484 SUB period_2016 -RUN_NUMBER >= 297730 +RUN_NUMBER >= 296939 +RUN_NUMBER <= 311481 + +SUB period_2017 +RUN_NUMBER >= 324320 +RUN_NUMBER <= 341649 + +SUB period_2018 +RUN_NUMBER >= 348197 + ######################## ### lepton trigger and offline cuts for reco-level selections @@ -109,37 +183,73 @@ RUN_NUMBER >= 297730 SUB EL_2015 . BASIC . period_2015 -TRIGDEC HLT_e24_lhmedium_L1EM20VH HLT_e60_lhmedium HLT_e120_lhloose +GTRIGDEC EL_N 25000 >= 1 SUB EL_2016 . BASIC . period_2016 -TRIGDEC HLT_e26_lhtight_nod0_ivarloose HLT_e60_lhmedium_nod0 HLT_e140_lhloose_nod0 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N 27000 >= 1 + +SUB EL_2018 +. BASIC +. period_2018 +GTRIGDEC EL_N 27000 >= 1 SUB MU_2015 . BASIC . period_2015 -TRIGDEC HLT_mu20_iloose_L1MU15 HLT_mu50 +GTRIGDEC MU_N 25000 >= 1 SUB MU_2016 . BASIC . period_2016 -TRIGDEC HLT_mu26_ivarmedium HLT_mu50 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2017 +. BASIC +. period_2017 +GTRIGDEC +MU_N 27000 >= 1 + +SUB MU_2018 +. BASIC +. period_2018 +GTRIGDEC MU_N 27000 >= 1 SUB EM_2015 . BASIC . period_2015 -TRIGDEC HLT_e24_lhmedium_L1EM20VH HLT_e60_lhmedium HLT_e120_lhloose HLT_mu20_iloose_L1MU15 HLT_mu50 +GTRIGDEC EL_N_OR_MU_N 25000 >= 1 SUB EM_2016 . BASIC . period_2016 -TRIGDEC HLT_e26_lhtight_nod0_ivarloose HLT_e60_lhmedium_nod0 HLT_e140_lhloose_nod0 HLT_mu26_ivarmedium HLT_mu50 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2017 +. BASIC +. period_2017 +GTRIGDEC +EL_N_OR_MU_N 27000 >= 1 + +SUB EM_2018 +. BASIC +. period_2018 +GTRIGDEC EL_N_OR_MU_N 27000 >= 1 ######################## @@ -149,7 +259,7 @@ EL_N_OR_MU_N 27000 >= 1 SUB ejets_basic EL_N 25000 == 1 MU_N 25000 == 0 -TRIGMATCH +GTRIGMATCH #EMU_OVERLAP JETCLEAN LooseBad JET_N 25000 >= 1 @@ -158,8 +268,7 @@ JET_N 25000 >= 3 JET_N 25000 >= 4 MET > 30000 MWT > 30000 -#JET_N_BTAG FixedCutBEff_77 >= 1 -#RECO::KLFITTERRUN kElectron +RECO::KLFITTERRUN kElectron KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 #KLFITTER > -50.0 EXAMPLEPLOTS #PRINT @@ -175,6 +284,70 @@ SELECTION ejets_2016 . ejets_basic SAVE +SELECTION ejets_2017 +. EL_2017 +. ejets_basic +SAVE + +SELECTION ejets_2018 +. EL_2018 +. ejets_basic +SAVE + +SELECTION ejets_MV2c10_2015 +. EL_2015 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2016 +. EL_2016 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2017 +. EL_2017 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_MV2c10_2018 +. EL_2018 +. ejets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION ejets_tjet_MV2c10_2015 +. EL_2015 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2016 +. EL_2016 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2017 +. EL_2017 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION ejets_tjet_MV2c10_2018 +. EL_2018 +. ejets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + SELECTION ejets_particle PRIVTX PARTICLE_LEVEL @@ -189,7 +362,7 @@ SAVE SUB mujets_basic MU_N 25000 == 1 EL_N 25000 == 0 -TRIGMATCH +GTRIGMATCH #EMU_OVERLAP JETCLEAN LooseBad JET_N 25000 >= 1 @@ -197,8 +370,7 @@ JET_N 25000 >= 2 JET_N 25000 >= 3 JET_N 25000 >= 4 MET+MWT > 60000 -#JET_N_BTAG FixedCutBEff_77 >= 1 -#RECO::KLFITTERRUN kMuon +RECO::KLFITTERRUN kMuon KLFitterBTaggingWP:MV2c10:FixedCutBEff_77 #KLFITTER > -50.0 EXAMPLEPLOTS #PRINT @@ -214,6 +386,70 @@ SELECTION mujets_2016 . mujets_basic SAVE +SELECTION mujets_2017 +. MU_2017 +. mujets_basic +SAVE + +SELECTION mujets_2018 +. MU_2018 +. mujets_basic +SAVE + +SELECTION mujets_MV2c10_2015 +. MU_2015 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2016 +. MU_2016 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2017 +. MU_2017 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_MV2c10_2018 +. MU_2018 +. mujets_basic +JET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +######################################################################## +# For testing whether track jet b-tag selection works +# ONLY FOR TESTING, DOES NOT MAKE SENSE TO USE THIS FOR PHYSICS ANALYSIS +# THESE COMBINE TRACK-JET B-TAGGING WITH KLFITTER ON CALO JETS!!! + +SELECTION mujets_tjet_MV2c10_2015 +. MU_2015 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2016 +. MU_2016 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2017 +. MU_2017 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE + +SELECTION mujets_tjet_MV2c10_2018 +. MU_2018 +. mujets_basic +TJET_N_BTAG MV2c10:FixedCutBEff_77 >= 1 +SAVE +######################################################################## + SELECTION mujets_particle PRIVTX PARTICLE_LEVEL @@ -228,7 +464,7 @@ SAVE SUB emu_basic EL_N 25000 >= 1 MU_N 25000 >= 1 -TRIGMATCH +GTRIGMATCH #EMU_OVERLAP JETCLEAN LooseBad HT > 120000 @@ -253,6 +489,16 @@ SELECTION emu_2016 . emu_basic SAVE +SELECTION emu_2017 +. EM_2017 +. emu_basic +SAVE + +SELECTION emu_2018 +. EM_2018 +. emu_basic +SAVE + SELECTION emu_particle PRIVTX PARTICLE_LEVEL @@ -266,7 +512,7 @@ SAVE SUB ee_basic EL_N 25000 >= 2 -TRIGMATCH +GTRIGMATCH JETCLEAN LooseBad MET > 60000 JET_N 25000 >= 1 @@ -292,6 +538,16 @@ SELECTION ee_2016 . ee_basic SAVE +SELECTION ee_2017 +. EL_2017 +. ee_basic +SAVE + +SELECTION ee_2018 +. EL_2018 +. ee_basic +SAVE + SELECTION ee_particle PRIVTX PARTICLE_LEVEL @@ -305,7 +561,7 @@ SAVE SUB mumu_basic MU_N 25000 >= 2 -TRIGMATCH +GTRIGMATCH #EMU_OVERLAP JETCLEAN LooseBad MET > 60000 @@ -332,9 +588,51 @@ SELECTION mumu_2016 . mumu_basic SAVE +SELECTION mumu_2017 +. MU_2017 +. mumu_basic +SAVE + +SELECTION mumu_2018 +. MU_2018 +. mumu_basic +SAVE + SELECTION mumu_particle PRIVTX PARTICLE_LEVEL MU_N 27000 >= 1 . mumu_basic SAVE + +######################## +### large-r jet selections +######################## + +SELECTION large_r_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +LJET_N 350000 >=1 +SAVE + +SELECTION rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +RCJET_N 350000 >=1 +SAVE + +SELECTION var_rc_jets +INITIAL +GRL +GOODCALO +PRIVTX +JETCLEAN LooseBad +VRCJET_N 2m_w 300000 >= 1 +VRCJET_N 2m_t 350000 >= 1 +SAVE diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470afmc16a.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470afmc16a.py new file mode 100755 index 000000000000..709caa4aeb62 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470afmc16a.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# art-description: DxAOD MC16a TOPQ1 AtlFast2 410470 +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_a875_r9364_r9315_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470afmc16d.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470afmc16d.py new file mode 100755 index 000000000000..67f53542af10 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470afmc16d.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# art-description: DxAOD MC16d TOPQ1 AtlFast2 410470 +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_a875_r10201_r10210_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16a.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16a.py new file mode 100755 index 000000000000..2bdfeb96e11f --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16a.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# art-description: DxAOD MC16a TOPQ1 FullSim 410470 +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_s3126_r9364_r9315_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16apflow.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16apflow.py new file mode 100755 index 000000000000..8a694f1fd9b1 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16apflow.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# art-description: DxAOD MC16a TOPQ1 FullSim 410470 PFlow Jets +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_s3126_r9364_r9315_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16asysts.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16asysts.py new file mode 100755 index 000000000000..6141d6f5d671 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16asysts.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# art-description: DxAOD MC16a TOPQ1 FullSim 410470 with systematics +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_s3126_r9364_r9315_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16d.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16d.py new file mode 100755 index 000000000000..b849e8634246 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16d.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# art-description: DxAOD MC16d TOPQ1 FullSim 410470 +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_s3126_r10201_r10210_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dactualmurw.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dactualmurw.py new file mode 100755 index 000000000000..00323c5d4280 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dactualmurw.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# art-description: DxAOD MC16d TOPQ1 FullSim 410470 Actual Mu Pileup Reweighting +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_s3126_r10201_r10210_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dklfitter.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dklfitter.py new file mode 100755 index 000000000000..b849e8634246 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dklfitter.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# art-description: DxAOD MC16d TOPQ1 FullSim 410470 +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_s3126_r10201_r10210_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dpflow.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dpflow.py new file mode 100755 index 000000000000..00a0dd4f1b68 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dpflow.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# art-description: DxAOD MC16d TOPQ1 FullSim 410470 PFlow Jets +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_s3126_r10201_r10210_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dsysts.py b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dsysts.py new file mode 100755 index 000000000000..7d8c6fcca08b --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/test/test_410470fsmc16dsysts.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# art-description: DxAOD MC16d TOPQ1 FullSim 410470 with systematics +# art-type: grid +# art-output: output.root +# art-input: user.mvanadia.ART.mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e6337_e5984_s3126_r10201_r10210_p3980 +# art-input-nfiles: 2 +# art-include: 21.2/AnalysisTop + +import ROOT +from PathResolver import PathResolver +import subprocess, sys, shlex, random, shutil, os + +# Create empty PoolFileCatalog +os.system('art.py createpoolfile') + +# -- Settings -- +cutfilename = "artcut_"+os.path.basename( sys.argv[0] ).replace(".py",".txt") + +try: + inputfilenames=os.environ["ArtInFile"] +except KeyError: + print "Please set the environment variable ArtInFile" + sys.exit(1) + +# -- Get the validation file path from the most recent location -- +cutfilepath = ROOT.PathResolver.find_file(cutfilename, + "DATAPATH", + ROOT.PathResolver.RecursiveSearch) + +# -- Print the file location for debugging -- +print "ART Test : Using cutfile (%s) from %s"%(cutfilename, cutfilepath) +print "ART Test : Using inputfiles :",inputfilenames +print "Running on full statistics" + +# -- Copy the cutfile locally to be updated -- +shutil.copyfile(cutfilepath, cutfilename) + + # -- Write the input file path to a temporary file -- +lines = inputfilenames.split(",") +with open('input.txt', 'w') as inputfilepath: + for line in lines: + print "line : ", line + inputfilepath.write(line+'\n') + +f = open('input.txt', 'r') +print "Printing input.txt" +print f.read() +f.close() + +# -- Run top-xaod -- +cmd = "top-xaod %s input.txt"%(cutfilename) +proc = subprocess.Popen(shlex.split(cmd)) +proc.wait() + +# -- Print the art-result return code +print "art-result: " + str(proc.returncode) + +# -- Check the return code and exit this script with that -- +sys.exit( proc.returncode ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-tool-ftag.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-tool-ftag.cxx new file mode 100644 index 000000000000..10657f9b08d7 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-tool-ftag.cxx @@ -0,0 +1,132 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include <iostream> + +#include "TFile.h" +#include "TTree.h" +#include "TTreeFormula.h" +#include "TSystem.h" + +#include "xAODRootAccess/TEvent.h" +#include "xAODRootAccess/TStore.h" +#include "xAODRootAccess/TActiveStore.h" + +#include "TopConfiguration/AodMetaDataAccess.h" +#include "TopConfiguration/ConfigurationSettings.h" +#include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/SelectionConfigurationData.h" + +#include "TopAnalysis/Tools.h" +#include "TopCPTools/TopToolStore.h" + +#include "TopAnalysis/ObjectLoaderBase.h" +#include "TopAnalysis/EventSaverBase.h" +#include "TopEvent/EventTools.h" +#include "TopEvent/TopEventMaker.h" +#include "TopEvent/SystematicEvent.h" +#include "TopObjectSelectionTools/TopObjectSelection.h" +#include "TopObjectSelectionTools/EventCleaningSelection.h" + +#include "TopCorrections/BTagScaleFactorCalculator.h" + +// to disable the sending of file access statistics +#include "xAODRootAccess/tools/TFileAccessTracer.h" + +#include "TopAnalysis/MsgCategory.h" +// use ATH_MSG macros defined in the namespace TopAnalysis +using namespace TopAnalysis; + +/** + * @file The main executable. + * + * @brief Entry point code to perform object and event selection and write-out a + * few histograms and / or a tree in xAOD format. + * + * @return 0 If everything is okay. + */ + +// Prototype functions +std::shared_ptr<top::TopConfig> InitialiseTopSoftware(int, char**); +int TestFTag(std::shared_ptr<top::TopConfig>); + +std::shared_ptr<top::TopConfig> InitialiseTopSoftware(int argc, char** argv) { + if (argc != 3) { + ATH_MSG_INFO("Code to read an input file and return information on the" + << "anticipated systematics list in the b-tagging calibration" + << "Use like:\n" + << " " << argv[0] << " cuts.txt input.txt\n" + << " cuts.txt - file containing TopConfig\n" + << " input.txt - file containing list of input files\n" + << "\n" + << "For example\n" + << " " << argv[0] << + " $ROOTCOREBIN/data/TopAnalysis/nocuts.txt $ROOTCOREBIN/data/TopAnalysis/input-13TeV-fondueworld.txt\n"); + return 0; + } + + // to disable the sending of file access statistics + xAOD::TFileAccessTracer::enableDataSubmission(false); + + //magic xAOD stuff + //true = fail at even the slightest xaod issue + top::xAODInit(true); + StatusCode::enableFailure(); + + xAOD::TStore store; + + std::string settingsFilename = std::string(argv[1]); + ATH_MSG_INFO("Configuration Files:\n" + << settingsFilename << "\n" + << std::string(argv[2]) << "\n"); + + //load the settings from the input file + auto* const settings = top::ConfigurationSettings::get(); + settings->loadFromFile(settingsFilename); + ATH_MSG_INFO("Configuration:\n" << *settings << "\n"); + + const std::string libraryNames = settings->value("LibraryNames"); + top::loadLibraries(libraryNames); + + //load the event selection from the input file + std::string cutsFilename = std::string(settingsFilename); + + //open the files (to check they exist) and count how many events we have + std::vector<std::string> filenames = top::fileList(std::string(argv[2])); + + // A configuration that John can easily understand + // This is not the same as a good configuration + std::shared_ptr<top::TopConfig> topConfig(new top::TopConfig()); + + topConfig->setMapIndex(410501); + topConfig->setConfigSettings(settings); + xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); + // Setup all asg::AsgTools + top::TopToolStore topTools("top::TopToolStore"); + top::check(topTools.setProperty("config", topConfig), + "Failed to setProperty of topTools"); + top::check(topTools.initialize(), "Failed to initialize topTools"); + topConfig->fixConfiguration(); + ATH_MSG_INFO(*topConfig); + + return topConfig; +} + +int TestFTag(std::shared_ptr<top::TopConfig> topConfig) { + // Here we need to access the flavour tagging CP tool + // and get it to tell us what systematics are available + // given the configuration we setup up + + // Get TopCPTool handle + top::BTagScaleFactorCalculator* m_btagSF = new top::BTagScaleFactorCalculator("top::BTagScaleFactorCalculator"); + top::check(m_btagSF->setProperty("config", topConfig), "Failed to pass in the config"); + top::check(m_btagSF->initialize(), "Failed to init"); + top::check(m_btagSF->debug(), "Failed to debug"); + return 0; +} + +int main(int argc, char** argv) { + std::shared_ptr<top::TopConfig> topConfig = InitialiseTopSoftware(argc, argv); + TestFTag(topConfig); +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx index d8a21ef32679..35cb6370e303 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include <iostream> #include <memory> @@ -26,7 +26,7 @@ #include "TopCorrections/ScaleFactorCalculator.h" #include "TopCorrections/PDFScaleFactorCalculator.h" -#include "TopFakes/TopFakesMMWeightCalculator.h" +//#include "FakeBkgTools/AsymptMatrixTool.h" #include "TopSystematicObjectMaker/ObjectCollectionMaker.h" @@ -34,7 +34,9 @@ #include "TopConfiguration/ConfigurationSettings.h" #include "TopConfiguration/TopConfig.h" #include "TopConfiguration/SelectionConfigurationData.h" +#include "TopConfiguration/Tokenize.h" +#include "TopAnalysis/AnalysisTrackingHelper.h" #include "TopAnalysis/EventSelectionManager.h" #include "TopAnalysis/Tools.h" #include "TopCPTools/TopToolStore.h" @@ -49,18 +51,31 @@ #include "TopObjectSelectionTools/EventCleaningSelection.h" #include "TopPartons/CalcTtbarPartonHistory.h" +#include "TopPartons/CalcTtbarLightPartonHistory.h" #include "TopPartons/CalcTbbarPartonHistory.h" +#include "TopPartons/CalcWtbPartonHistory.h" +#include "TopPartons/CalcTTZPartonHistory.h" #include "TopPartons/CalcTopPartonHistory.h" +#include "TopPartons/CalcTtbarGammaPartonHistory.h" +#include "TopPartons/CalcThqPartonHistory.h" +#include "TopPartons/CalcTzqPartonHistory.h" #include "TopParticleLevel/ParticleLevelLoader.h" #include "TopDataPreparation/SampleXsection.h" -#include "TopHLUpgrade/UpgradeObjectLoader.h" +//#include "TopHLUpgrade/UpgradeObjectLoader.h" // to disable the sending of file access statistics #include "xAODRootAccess/tools/TFileAccessTracer.h" +// Path resolver +#include "PathResolver/PathResolver.h" + +#include "TopAnalysis/MsgCategory.h" +// use ATH_MSG macros defined in the namespace TopAnalysis +using namespace TopAnalysis; + /** * @file The main executable. * @@ -70,787 +85,1054 @@ * @return 0 If everything is okay. */ int main(int argc, char** argv) { - if (argc != 3) { - std::cout << "Code to perform object and event selection and write-out\n"; - std::cout << "a few histograms and / or a tree in xAOD format.\n"; - std::cout << "Use like:\n"; - std::cout << " " << argv[0] << " cuts.txt input.txt\n"; - std::cout << " cuts.txt - file containing cuts\n"; - std::cout << " input.txt - file containing list of input files\n"; - std::cout << "\n"; - std::cout << "For example\n"; - std::cout << " " << argv[0] << " $ROOTCOREBIN/data/TopAnalysis/nocuts.txt $ROOTCOREBIN/data/TopAnalysis/input-13TeV-fondueworld.txt\n"; - return 1; + if (argc != 3) { + ATH_MSG_INFO("Code to perform object and event selection and write-out\n" + << "a few histograms and / or a tree in xAOD format.\n" + << "Use like:\n" + << " " << argv[0] << " cuts.txt input.txt\n" + << " cuts.txt - file containing cuts\n" + << " input.txt - file containing list of input files\n" + << "\n" + << "For example\n" + << " " << argv[0] + << " $ROOTCOREBIN/data/TopAnalysis/nocuts.txt $ROOTCOREBIN/data/TopAnalysis/input-13TeV-fondueworld.txt\n"); + return 1; + } + + // to disable the sending of file access statistics + xAOD::TFileAccessTracer::enableDataSubmission(false); + + //magic xAOD stuff + //true = fail at even the slightest xaod issue + top::xAODInit(true); + StatusCode::enableFailure(); + + xAOD::TStore store; + + ATH_MSG_INFO("INPUT: Configuration file (argv[1]) = " + << argv[1] << "\n"); + std::string settingsFilename = PathResolver::find_file(argv[1],"DATAPATH",PathResolver::LocalSearch); + + ATH_MSG_INFO("LOCATED (using PathResolverFindFile ): Configuration file = " + << settingsFilename << "\n"); + + ATH_MSG_INFO("Configuration Files:\n" + << settingsFilename << "\n" + << argv[2] << "\n"); + + //load the settings from the input file + auto* const settings = top::ConfigurationSettings::get(); + settings->loadFromFile(settingsFilename); + ATH_MSG_INFO("Configuration:\n" << *settings << "\n"); + + const std::string libraryNames = settings->value("LibraryNames"); + top::loadLibraries(libraryNames); + + // Analysis tracking + std::unique_ptr<top::AnalysisTrackingHelper> tracker; + { + bool useTracking = true; + settings->retrieve("WriteTrackingData", useTracking); + if (useTracking) { + tracker.reset(new top::AnalysisTrackingHelper()); } - - // to disable the sending of file access statistics - xAOD::TFileAccessTracer::enableDataSubmission( false ); - - //magic xAOD stuff - //true = fail at even the slightest xaod issue - top::xAODInit(true); - StatusCode::enableFailure(); - - xAOD::TStore store; - - std::cout << "Configuration Files:\n"; - std::string settingsFilename = std::string(argv[1]); - std::cout << " " << settingsFilename << "\n"; - std::cout << " " << std::string(argv[2]) << "\n\n"; - - //load the settings from the input file - auto* const settings = top::ConfigurationSettings::get(); - settings->loadFromFile(settingsFilename); - std::cout << "Configuration:\n"; - std::cout << *settings << "\n"; - - const std::string libraryNames = settings->value("LibraryNames"); - top::loadLibraries(libraryNames); - - // I/O Performance stats? - // Summary gives a summary - // Full gives detailed info on each collection in the file - unsigned int doPerfStats(0); - if (settings->value("PerfStats") == "Summary") - doPerfStats = 1; - - if (settings->value("PerfStats") == "Full") - doPerfStats = 2; - - //load the event selection from the input file - std::string cutsFilename = std::string(settingsFilename); - - //open the files (to check they exist) and count how many events we have - std::vector<std::string> filenames = top::fileList(std::string(argv[2])); - unsigned int totalYield = top::checkFiles(filenames); - - //open output file - std::unique_ptr<TFile> outputFile(TFile::Open((settings->value("OutputFilename") + ".tmp").c_str(), "RECREATE")); - - // A configuration that John can easily understand - // This is not the same as a good configuration - std::shared_ptr<top::TopConfig> topConfig(new top::TopConfig()); - - // load AOD meta-data from all files - bool useAodMetaData = false; - settings->retrieve("UseAodMetaData", useAodMetaData); - if (useAodMetaData) { - std::cout << "Loading meta-data from input files ... " << std::flush; - topConfig->aodMetaData().loadWithFilesFrom(argv[2]); - std::cout << "OK." << std::endl; + } + + // I/O Performance stats? + // Summary gives a summary + // Full gives detailed info on each collection in the file + unsigned int doPerfStats(0); + if (settings->value("PerfStats") == "Summary") doPerfStats = 1; + + if (settings->value("PerfStats") == "Full") doPerfStats = 2; + + //load the event selection from the input file + std::string cutsFilename = std::string(settingsFilename); + + //open the files (to check they exist) and count how many events we have + std::vector<std::string> filenames = top::fileList(std::string(argv[2])); + size_t totalYield = top::checkFiles(filenames); + + //open output file + std::unique_ptr<TFile> outputFile(TFile::Open((settings->value("OutputFilename") + ".tmp").c_str(), "RECREATE")); + + // A configuration that John can easily understand + // This is not the same as a good configuration + std::shared_ptr<top::TopConfig> topConfig(new top::TopConfig()); + + // load AOD meta-data from all files + bool useAodMetaData = false; + settings->retrieve("UseAodMetaData", useAodMetaData); + if (useAodMetaData) { + ATH_MSG_INFO("Loading meta-data from input files ... "); + topConfig->aodMetaData().loadWithFilesFrom(argv[2]); + ATH_MSG_INFO("OK."); + } + + + //picking the first file was a bad idea because in the derivations it often + //has no events (no CollectionTree). Be sure to pick a file with events in + //it... + // The isMC flag needs to be taken from the xAOD metadata + // We also need something for AFII + { + std::string usethisfile = filenames[0]; + bool atLeastOneFileIsValid(false); + for (const auto& filename : filenames) { + std::unique_ptr<TFile> checkingYieldFile(TFile::Open(filename.c_str())); + + //collection tree means > 0 events + const TTree* const collectionTree = dynamic_cast<TTree* > (checkingYieldFile->Get("CollectionTree")); + if (collectionTree) { + usethisfile = filename; + atLeastOneFileIsValid = true; + break; + } } - //picking the first file was a bad idea because in the derivations it often - //has no events (no CollectionTree). Be sure to pick a file with events in - //it... - // The isMC flag needs to be taken from the xAOD metadata - // We also need something for AFII - { - std::string usethisfile = filenames[0]; - bool atLeastOneFileIsValid(false); - for (const auto& filename : filenames) { - std::unique_ptr<TFile> checkingYieldFile(TFile::Open(filename.c_str())); - - //collection tree means > 0 events - const TTree* const collectionTree = dynamic_cast<TTree* > (checkingYieldFile->Get("CollectionTree")); - if (collectionTree) { - usethisfile = filename; - atLeastOneFileIsValid = true; - break; - } - } + // If there are no valid files, let's exit cleanly + if (!(atLeastOneFileIsValid || useAodMetaData)) { + ATH_MSG_ERROR("No input file contains a CollectionTree and no metadata used. Cannot Continue."); + ATH_MSG_ERROR("If you had turned on 'UseAodMetaData' in your configuration, " + "we could overcome this limitation."); + return 1; + } - // If there are no valid files, let's exit cleanly - if (!(atLeastOneFileIsValid || useAodMetaData)) { - std::cout << "No input file contains a CollectionTree -- exiting.\n" - << "Unfortunately, we don't have enough information to prepare an output file for\n" - << "you. If you had turned on 'UseAodMetaData' in your configuration, we could\n" - << "overcome this limitation.\n" << std::endl; - return 1; - } + std::unique_ptr<TFile> testFile(TFile::Open(usethisfile.c_str())); + if (!top::readMetaData(testFile.get(), topConfig)) { + ATH_MSG_ERROR("Unable to access FileMetaData and/or TruthMetaData in this file : " << usethisfile + << "\nPlease report this message."); + } - std::unique_ptr<TFile> testFile(TFile::Open(usethisfile.c_str())); - bool const isMC = (useAodMetaData ? + const bool isOverlay = useAodMetaData ? topConfig->aodMetaData().IsEventOverlayInputSim() : false; + bool isMC(true); + if (!isOverlay) { + isMC = (useAodMetaData ? topConfig->aodMetaData().isSimulation() : top::isFileSimulation(testFile.get(), topConfig->sgKeyEventInfo()) - ); - topConfig->setIsMC(isMC); - - const bool isPrimaryxAOD = top::isFilePrimaryxAOD(testFile.get()); - topConfig->setIsPrimaryxAOD(isPrimaryxAOD); - - const std::string derivationStream = top::getDerivationStream(testFile.get()); - std::cout << "Derivation stream is -> " << derivationStream << std::endl; - topConfig->setDerivationStream(derivationStream); - - if(isMC){ - ///-- Are we using a truth derivation (no reco information)? --/// - ///-- Let's find out in the first event, this could be done better --/// - bool isTruthDxAOD = top::isTruthDxAOD(testFile.get()); - topConfig->setIsTruthDxAOD(isTruthDxAOD); - - if (!isTruthDxAOD && atLeastOneFileIsValid) { - unsigned int DSID = top::getDSID(testFile.get(), topConfig->sgKeyEventInfo()); - topConfig -> setDSID(DSID); - - // now need to get and set the parton shower generator from TopDataPrep - SampleXsection tdp; - const char* const rc = getenv("ROOTCOREBIN"); - std::string filename = std::string(rc) + "/data/TopDataPreparation/XSection-MC15-13TeV.data"; - - if (!tdp.readFromFile(filename.c_str())) { - std::cout << "ERROR::TopDataPreparation - could not read file \n"; - std::cout << filename << "\n"; - exit(1); - } - - int ShowerIndex = tdp.getShoweringIndex(DSID); - std::cout << "DSID: " << DSID << "\t" << "ShowerIndex: " << ShowerIndex << std::endl; - topConfig->setMapIndex(ShowerIndex); - } - } - } //close and delete the ptr to testFile - - // Pass the settings file to the TopConfig - topConfig->setConfigSettings(settings); - - //In rel 19 we had a function to guess Class or Branch Access. - //In rel20 just use branch (quicker) - // In rel 20.7, need to go back to class access - xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); - - // Setup all asg::AsgTools - top::TopToolStore topTools("top::TopToolStore"); - top::check(topTools.setProperty("config", topConfig), - "Failed to setProperty of topTools"); - top::check(topTools.initialize() , "Failed to initialize topTools"); - // EventCleaningSelection - // Decorates EventInfo with GRL decision (always true for MC) - // Evaluates all triggers requested from all selections - // Trigger matching - // Check for good Tile and LAr calorimeters - // Let's check this passes before running expensive calibrations - // If ANY selection does not request a trigger, we won't veto any events - - std::unique_ptr<top::EventCleaningSelection> eventCleaning( new top::EventCleaningSelection("top::EventCleaningSelection") ); - top::check(eventCleaning->setProperty("config", topConfig), - "Failed to setProperty of triggerGRLSelection" ); - top::check(eventCleaning->initialize(), - "Failed to initialize triggerGRLSelection"); - eventCleaning->setEventSelections(settings->selections()); - - - // Systematic object collection making - std::unique_ptr<top::ObjectCollectionMaker> systObjMaker( new top::ObjectCollectionMaker( "top::ObjectCollectionMaker" ) ); - top::check( systObjMaker->setProperty( "config" , topConfig ) , "Failed to setProperty of systObjMaker" ); - if (!topConfig->isTruthDxAOD()) - top::check( systObjMaker->initialize() , "Failed to initialize systObjMaker" ); - - //setup object definitions - std::unique_ptr<top::TopObjectSelection> objectSelection(top::loadObjectSelection(topConfig)); - objectSelection->print(std::cout); + ); + } - //setup event-level cuts - top::EventSelectionManager eventSelectionManager(settings->selections(), outputFile.get(), libraryNames, topConfig); + topConfig->setIsMC(isMC); + + const bool isPrimaryxAOD = top::isFilePrimaryxAOD(testFile.get()); + topConfig->setIsPrimaryxAOD(isPrimaryxAOD); + + const std::string derivationStream = top::getDerivationStream(testFile.get()); + ATH_MSG_INFO("Derivation stream is -> " << derivationStream); + topConfig->setDerivationStream(derivationStream); + + // first we need to read some metadata before we read the config + if (isMC) { + // check number of MC generator weights -- we need this before start initializing PMGTruthWeightTool later + if (atLeastOneFileIsValid) topConfig->setMCweightsVectorSize(top::MCweightsSize(testFile.get(), topConfig->sgKeyEventInfo())); + ///-- Are we using a truth derivation (no reco information)? --/// + ///-- Let's find out in the first event, this could be done better --/// + bool isTruthDxAOD = top::isTruthDxAOD(testFile.get()); + topConfig->setIsTruthDxAOD(isTruthDxAOD); + + unsigned int DSID {0}; + if (!useAodMetaData) { + if (atLeastOneFileIsValid) { + DSID = top::getDSID(testFile.get(), topConfig->sgKeyEventInfo()); + topConfig->setDSID(DSID); + } else { + ATH_MSG_ERROR("We could not determine DSID for this sample from either CollectionTree, or FileMetaData, or TruthMetaData. There is something seriously wrong with this sample."); + return 1; + } + } else { + DSID = topConfig->getDSID(); + } + } - //The loader tool for top::ParticleLevelEvent objects - top::ParticleLevelLoader particleLevelLoader( topConfig ); - // The loader tool for Upgrade objects - top::UpgradeObjectLoader upgradeLoader( topConfig ); - // Fix the configuration - it now knows about: - // * all objects collections to work with - // * all systematic variations - topConfig->fixConfiguration(); + // Pass the settings file to the TopConfig + topConfig->setConfigSettings(settings); + if (isMC && !topConfig->isTruthDxAOD()) { + // now need to get and set the parton shower generator from TopDataPrep + SampleXsection tdp; + // Package/filename - XS file we want to use (can now be configured via cutfile) + const std::string tdp_filename = settings->value("TDPPath"); + // Use the path resolver to find the first file in the list of possible paths ($CALIBPATH) + const std::string fullpath = PathResolverFindCalibFile(tdp_filename); + if (!tdp.readFromFile(fullpath.c_str())) { + ATH_MSG_ERROR("TopDataPreparation - could not read file\n" << tdp_filename); + return 1; + } + ATH_MSG_INFO("SampleXsection::Found " << fullpath); - // OK let's printout the TopConfig - std::cout << *topConfig << "\n"; + tdp.setTranslator(topConfig->GetMCMCTranslator()); - //Top parton history for MC events - // This is quite ugly and simple, it will be harmonized with in the future - // along with all other factory methods (it's not a factory method right now) - std::unique_ptr<top::CalcTopPartonHistory> topPartonHistory(nullptr); - if(settings->value("TopPartonHistory") == "ttbar"){ - topPartonHistory = std::unique_ptr<top::CalcTopPartonHistory> ( new top::CalcTtbarPartonHistory( "top::CalcTtbarPartonHistory" ) ); - top::check(topPartonHistory->setProperty( "config" , topConfig ) , "Failed to setProperty of top::CalcTtbarPartonHistory"); + int ShowerIndex = tdp.getShoweringIndex(topConfig->getDSID()); + ATH_MSG_INFO("DSID: " << topConfig->getDSID() << "\t" << "ShowerIndex: " << ShowerIndex << " PS generator: "<< tdp.getShoweringString(topConfig->getDSID())); + topConfig->setMapIndex(ShowerIndex); + topConfig->setShoweringAlgorithm(tdp.getShowering(topConfig->getDSID())); } - else if(settings->value("TopPartonHistory") == "tb"){ - topPartonHistory = std::unique_ptr<top::CalcTopPartonHistory> ( new top::CalcTbbarPartonHistory( "top::CalcTbbarPartonHistory" ) ); - top::check(topPartonHistory->setProperty( "config" , topConfig ) , "Failed to setProperty of top::CalcTbbarPartonHistory"); + // check year + { + xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); + top::check(xaodEvent.readFrom(testFile.get()), "Failed to read file in"); + const unsigned int entries = xaodEvent.getEntries(); + if (entries > 0) { + xaodEvent.getEntry(0); + const xAOD::EventInfo* eventInfo(nullptr); + top::check(xaodEvent.retrieve(eventInfo, topConfig->sgKeyEventInfo()), "Failed to retrieve EventInfo"); + const unsigned int runnumber = eventInfo->runNumber(); + const std::string thisYear = topConfig->getYear(runnumber, isMC); + topConfig->SetYear(thisYear); + } else { + topConfig->SetYear("UNKNOWN"); + } + topConfig->SetTriggersToYear(isMC); } - //LHAPDF SF calculation - std::unique_ptr<top::PDFScaleFactorCalculator> PDF_SF(nullptr); - PDF_SF = std::unique_ptr<top::PDFScaleFactorCalculator> (new top::PDFScaleFactorCalculator( "top::PDFScaleFactorCalculator" ) ); - if ( topConfig->doLHAPDF() ){ - top::check( PDF_SF->setProperty( "config", topConfig ), "Failed to set config for PDF SF Calculator" ); - top::check( PDF_SF->initialize(), "Failed to initialize PDF SF calculator" ); + } //close and delete the ptr to testFile + + + //In rel 19 we had a function to guess Class or Branch Access. + //In rel20 just use branch (quicker) + // In rel 20.7, need to go back to class access + xAOD::TEvent xaodEvent(xAOD::TEvent::kClassAccess); + + // Read metadata + std::unique_ptr<TFile> metadataInitFile(TFile::Open(filenames[0].c_str())); + top::check(xaodEvent.readFrom(metadataInitFile.get()), "xAOD::TEvent readFrom failed"); + + + // Setup all asg::AsgTools + top::TopToolStore topTools("top::TopToolStore"); + top::check(topTools.setProperty("config", topConfig), + "Failed to setProperty of topTools"); + top::check(topTools.initialize(), "Failed to initialize topTools"); + // EventCleaningSelection + // Decorates EventInfo with GRL decision (always true for MC) + // Evaluates all triggers requested from all selections + // Trigger matching + // Check for good Tile and LAr calorimeters + // Let's check this passes before running expensive calibrations + // If ANY selection does not request a trigger, we won't veto any events + + std::unique_ptr<top::EventCleaningSelection> eventCleaning(new top::EventCleaningSelection( + "top::EventCleaningSelection")); + top::check(eventCleaning->setProperty("config", topConfig), + "Failed to setProperty of triggerGRLSelection"); + top::check(eventCleaning->initialize(), + "Failed to initialize triggerGRLSelection"); + eventCleaning->setEventSelections(settings->selections()); + + + // Systematic object collection making + std::unique_ptr<top::ObjectCollectionMaker> systObjMaker(new top::ObjectCollectionMaker("top::ObjectCollectionMaker")); + top::check(systObjMaker->setProperty("config", topConfig), "Failed to setProperty of systObjMaker"); + if (!topConfig->isTruthDxAOD()) top::check(systObjMaker->initialize(), "Failed to initialize systObjMaker"); + + //setup object definitions - not used in HLUpgrade tools + std::unique_ptr<top::TopObjectSelection> objectSelection; + if (!topConfig->HLLHC()) { + objectSelection.reset(top::loadObjectSelection(topConfig)); + objectSelection->print(msg(MSG::Level::INFO)); // forward to msg stream using INFO level + } + + //setup event-level cuts + top::EventSelectionManager eventSelectionManager(settings->selections(), outputFile.get(), libraryNames, topConfig); + + //The loader tool for top::ParticleLevelEvent objects + top::ParticleLevelLoader particleLevelLoader(topConfig); + + // The loader tool for Upgrade objects +// top::UpgradeObjectLoader upgradeLoader(topConfig); + + // Fix the configuration - it now knows about: + // * all objects collections to work with + // * all systematic variations + topConfig->fixConfiguration(); + + + // OK let's printout the TopConfig + ATH_MSG_INFO(*topConfig << "\n"); + if (tracker) tracker->setTopConfig(topConfig); + + //Top parton history for MC events + // This is quite ugly and simple, it will be harmonized with in the future + // along with all other factory methods (it's not a factory method right now) + std::unique_ptr<top::CalcTopPartonHistory> topPartonHistory(nullptr); + if (settings->value("TopPartonHistory") == "ttbar") { + topPartonHistory = + std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTtbarPartonHistory("top::CalcTtbarPartonHistory")); + top::check(topPartonHistory->setProperty("config", + topConfig), "Failed to setProperty of top::CalcTtbarPartonHistory"); + } else if (settings->value("TopPartonHistory") == "ttbarlight") { + topPartonHistory = + std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTtbarLightPartonHistory( + "top::CalcTtbarLightPartonHistory")); + top::check(topPartonHistory->setProperty("config", + topConfig), "Failed to setProperty of top::CalcTtbarLightPartonHistory"); + } else if (settings->value("TopPartonHistory") == "tb") { + topPartonHistory = + std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTbbarPartonHistory("top::CalcTbbarPartonHistory")); + top::check(topPartonHistory->setProperty("config", + topConfig), "Failed to setProperty of top::CalcTbbarPartonHistory"); + } else if (settings->value("TopPartonHistory") == "Wtb") { + topPartonHistory = + std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcWtbPartonHistory("top::CalcWtbPartonHistory")); + top::check(topPartonHistory->setProperty("config", topConfig), + "Failed to setProperty of top::CalcWtbPartonHistory"); + } else if (settings->value("TopPartonHistory") == "ttz") { + topPartonHistory = + std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTTZPartonHistory("top::CalcTTZPartonHistory")); + top::check(topPartonHistory->setProperty("config", topConfig), + "Failed to setProperty of top::CalcTTZPartonHistory"); + } else if (settings->value("TopPartonHistory") == "ttgamma") { + topPartonHistory = + std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTtbarGammaPartonHistory( + "top::CalcTtbarGammaPartonHistory")); + top::check(topPartonHistory->setProperty("config", + topConfig), "Failed to setProperty of top::CalcTtbarGammaPartonHistory"); + } else if (settings->value("TopPartonHistory") == "tHq") { + topPartonHistory = + std::unique_ptr<top::CalcTopPartonHistory>(new top::CalcThqPartonHistory("top::CalcThqPartonHistory")); + top::check(topPartonHistory->setProperty("config", topConfig), + "Failed to setProperty of top::CalcThqPartonHistory"); + } else if (settings->value("TopPartonHistory") == "tZq") { + topPartonHistory = + std::unique_ptr<top::CalcTopPartonHistory>(new top::CalcTzqPartonHistory("top::CalcTzqPartonHistory")); + top::check(topPartonHistory->setProperty("config", topConfig), + "Failed to setProperty of top::CalcTzqPartonHistory"); + } + + + //LHAPDF SF calculation + std::unique_ptr<top::PDFScaleFactorCalculator> PDF_SF(nullptr); + PDF_SF = + std::unique_ptr<top::PDFScaleFactorCalculator> (new top::PDFScaleFactorCalculator("top::PDFScaleFactorCalculator")); + if (topConfig->doLHAPDF()) { + top::check(PDF_SF->setProperty("config", topConfig), "Failed to set config for PDF SF Calculator"); + top::check(PDF_SF->initialize(), "Failed to initialize PDF SF calculator"); + } + + + // make top::Event objects + std::unique_ptr<top::TopEventMaker> topEventMaker(new top::TopEventMaker("top::TopEventMaker")); + top::check(topEventMaker->setProperty("config", topConfig), "Failed to setProperty of top::TopEventMaker"); + top::check(topEventMaker->initialize(), "Failed to initialize top::TopEventMaker"); + // Debug messages? + // topEventMaker.msg().setLevel(MSG::DEBUG); + + std::unique_ptr<top::ScaleFactorCalculator> topScaleFactors(new top::ScaleFactorCalculator( + "top::ScaleFactorCalculator")); + top::check(topScaleFactors->setProperty("config", topConfig), "Failed to setProperty of top::ScaleFactorCalculator"); + top::check(topScaleFactors->initialize(), "Failed to initialize top::ScaleFactorCalculator"); + + //std::vector<std::unique_ptr<CP::AsymptMatrixTool> > topfakesMMWeightsIFF; + //std::vector<std::vector<std::string> > FakesMMConfigIFF; + //if (!topConfig->isMC() && topConfig->doLooseEvents() && topConfig->doFakesMMWeightsIFF()) { + // if (topConfig->FakesMMConfigIFF() != "") { + // std::vector<std::string> tokens; + // top::tokenize(topConfig->FakesMMConfigIFF(), tokens, ";"); + // std::reverse(tokens.begin(), tokens.end()); + // while (tokens.size()) { + // const auto& token = tokens.back(); + // std::vector<std::string> tokens2; + // top::tokenize(token, tokens2, ":"); + // top::check(tokens2.size() == 3, + // "Failed to read FakesMMConfigIFF: " + topConfig->FakesMMConfigIFF() + " has size " + + // std::to_string(tokens2.size()) + " (should be 3)"); + // FakesMMConfigIFF.push_back(tokens2); + // FakesMMConfigIFF.back()[0] = PathResolverFindCalibFile(tokens2[0]); + // tokens.pop_back(); + // } + // } + // for (unsigned int mmi = 0; mmi < FakesMMConfigIFF.size(); ++mmi) { + // topfakesMMWeightsIFF.emplace_back(std::make_unique<CP::AsymptMatrixTool>("AsymptMatrixTool_" + std::to_string (mmi))); + // top::check(topfakesMMWeightsIFF.back()->setProperty("InputFiles", + // std::vector<std::string>{FakesMMConfigIFF[mmi][0]}), + // "Failed To setProperty InputFiles of AsymptMatrixTool"); + // top::check(topfakesMMWeightsIFF.back()->setProperty("Selection", + // FakesMMConfigIFF[mmi][1]), + // "Failed to set the selection FakesMMIFFConfigs for selection " + FakesMMConfigIFF[mmi][1]); + // top::check(topfakesMMWeightsIFF.back()->setProperty("Process", + // FakesMMConfigIFF[mmi][2]), + // "Failed to set the selection FakesMMIFFConfigs for process " + FakesMMConfigIFF[mmi][2]); + // top::check(topfakesMMWeightsIFF.back()->setProperty("EnergyUnit", + // "GeV"), + // "Failed to setProperty EnergyUnit of AsymptMatrixTool"); + // top::check(topfakesMMWeightsIFF.back()->setProperty("ConvertWhenMissing", + // true), + // "Failed to setProperty ConvertWhenMissing of AsymptMatrixTool"); + // top::check(topfakesMMWeightsIFF.back()->setProperty("TightDecoration", + // "passPreORSelection,as_char"), + // "Failed to setProperty TightDecoration of AsymptMatrixTool"); + // if (topConfig->FakesMMIFFDebug()) top::check(topfakesMMWeightsIFF.back()->setProperty("OutputLevel", + // MSG::INFO), + // "Failed to setProperty of AsymptMatrixTool"); + // top::check(topfakesMMWeightsIFF.back()->initialize(), "Failed to initialize AsymptMatrixTool"); + // } + //} + + //A list of extra branches that we create in this code and want to save + std::vector<std::string> extraBranches; + eventSelectionManager.addExtraBranches(extraBranches); + + //output file format (and any user-modified code) + std::unique_ptr<top::EventSaverBase> eventSaver(top::loadEventSaver(topConfig)); + eventSaver->initialize(topConfig, outputFile.get(), extraBranches); + + // save sum of weights before derivations + outputFile->cd(); + TTree* sumWeights = new TTree("sumWeights", ""); + float totalEventsWeighted = 0; + double totalEventsWeighted_temp = 0; + std::vector<float> totalEventsWeighted_LHE3; + std::vector<double> totalEventsWeighted_LHE3_temp;// having doubles is necessary in case of re-calculation of the sum + // of weights on the fly + std::vector<std::string> names_LHE3; + bool recalc_LHE3 = false; + bool recalculateNominalWeightSum = false; + int dsid = topConfig->getDSID(); + int isAFII = topConfig->isAFII(); + std::string generators = topConfig->getGenerators(); + std::string AMITag = topConfig->getAMITag(); + ULong64_t totalEvents = 0; + ULong64_t totalEventsInFiles = 0; + sumWeights->Branch("dsid", &dsid); + sumWeights->Branch("isAFII", &isAFII); + sumWeights->Branch("generators", &generators); + sumWeights->Branch("AMITag", &AMITag); + sumWeights->Branch("totalEventsWeighted", &totalEventsWeighted); + if (topConfig->doMCGeneratorWeights()) {// the main problem is that we don't have the list of names a priori + sumWeights->Branch("totalEventsWeighted_mc_generator_weights", &totalEventsWeighted_LHE3); + sumWeights->Branch("names_mc_generator_weights", &names_LHE3); + } + sumWeights->Branch("totalEvents", &totalEvents, "totalEvents/l"); + + TTree* sumPdfWeights = 0; + std::unordered_map<std::string, std::vector<float>*> totalEventsPdfWeighted; + int dsidPdf = topConfig->getDSID(); + bool pdfMetadataExists = false; + if (topConfig->doLHAPDF()) { + sumPdfWeights = new TTree("PDFsumWeights", ""); + sumPdfWeights->Branch("dsid", &dsidPdf); + for (const auto& pdf_set : topConfig->LHAPDFSets()) { + totalEventsPdfWeighted[pdf_set] = new std::vector<float>(); + sumPdfWeights->Branch(pdf_set.c_str(), totalEventsPdfWeighted[pdf_set]); } - - - // make top::Event objects - std::unique_ptr<top::TopEventMaker> topEventMaker( new top::TopEventMaker( "top::TopEventMaker" ) ); - top::check(topEventMaker->setProperty( "config" , topConfig ) , "Failed to setProperty of top::TopEventMaker"); - // Debug messages? - // topEventMaker.msg().setLevel(MSG::DEBUG); - - std::unique_ptr<top::ScaleFactorCalculator> topScaleFactors( new top::ScaleFactorCalculator("top::ScaleFactorCalculator") ); - top::check(topScaleFactors->setProperty( "config" , topConfig ) , "Failed to setProperty of top::ScaleFactorCalculator"); - top::check(topScaleFactors->initialize(),"Failed to initialize top::ScaleFactorCalculator"); - - ///-- weights for matrix-method fakes estimate --/// - std::unique_ptr<top::TopFakesMMWeightCalculator> topfakesMMWeights(nullptr); - if (!topConfig->isMC() && topConfig->doLooseEvents() && topConfig->doFakesMMWeights()) { - topfakesMMWeights = std::unique_ptr<top::TopFakesMMWeightCalculator>( new top::TopFakesMMWeightCalculator() ); - top::check(topfakesMMWeights->setProperty( "config" , topConfig ) , "Failed to setProperty of top::TopFakesMMWeightCalculator"); - top::check(topfakesMMWeights->initialize(),"Failed to initialize top::TopFakesMMWeightCalculator"); - for (auto sel : settings->selections()) { - top::check(topfakesMMWeights->setSelectionConfigs(sel.m_name, eventSelectionManager.GetFakesMMConfigs(sel.m_name)),"Failed to set the selection FakesMMConfigs for selection"+sel.m_name); + } + + //the analysis loop + ATH_MSG_INFO("Starting event loop\n"); + + // Performance stats + if (doPerfStats > 0) xAOD::PerfStats::instance().start(); // start Perfstats timer + + unsigned int totalYieldSoFar = 0; + unsigned int skippedEventsSoFar = 0; + unsigned int eventSavedReco(0), eventSavedRecoLoose(0), eventSavedTruth(0), eventSavedParticle(0), + eventSavedUpgrade(0); + + // Close the file that we opened only for metadata + metadataInitFile->Close(); + + for (const auto& filename : filenames) { + if (topConfig->numberOfEventsToRun() != 0 && totalYieldSoFar >= topConfig->numberOfEventsToRun()) break; + ATH_MSG_INFO("Opening " << filename); + std::unique_ptr<TFile> inputFile(TFile::Open(filename.c_str())); + + // the derivation framework is making files with an empty collection tree + // which TEvent can now handle + // However, at least for data, this is causing problems with the trigger menu + // skip the file, after the meta data access above + const TTree* const collectionTree = dynamic_cast<TTree* > (inputFile->Get("CollectionTree")); + if (!collectionTree && !topConfig->isMC()) { + if (top::ConfigurationSettings::get()->feature("SkipInputFilesWithoutCollectionTree")) { + ATH_MSG_INFO("No CollectionTree found, skipping file"); + continue; } } - //A list of extra branches that we create in this code and want to save - std::vector<std::string> extraBranches; - eventSelectionManager.addExtraBranches(extraBranches); - - //output file format (and any user-modified code) - std::unique_ptr<top::EventSaverBase> eventSaver(top::loadEventSaver(topConfig)); - eventSaver->initialize(topConfig, outputFile.get(), extraBranches); - - // save sum of weights before derivations - outputFile->cd(); - TTree* sumWeights = new TTree("sumWeights", ""); - float totalEventsWeighted = 0; - std::vector<float> totalEventsWeighted_LHE3; - std::vector<double> totalEventsWeighted_LHE3_temp;// having doubles is necessary in case of re-calculation of the sum of weights on the fly - std::vector<std::string> names_LHE3; - bool recalc_LHE3 = false; - int dsid = 0; - ULong64_t totalEvents = 0; - ULong64_t totalEventsInFiles = 0; - sumWeights->Branch("dsid", &dsid); - sumWeights->Branch("totalEventsWeighted", &totalEventsWeighted); - if (topConfig->doMCGeneratorWeights()) {// the main problem is that we don't have the list of names a priori - sumWeights->Branch("totalEventsWeighted_mc_generator_weights", &totalEventsWeighted_LHE3); - sumWeights->Branch("names_mc_generator_weights", &names_LHE3); + top::check(xaodEvent.readFrom(inputFile.get()), "xAOD::TEvent readFrom failed"); + + // Sum of weights and raw number of entries before skimming in current file + double sumW_file = 0; + ULong64_t initialEvents = 0; + + // vector of MC generator weights and their names in current file + std::vector<float> LHE3_sumW_file; + std::vector<std::string> LHE3_names_file; + + // See https://twiki.cern.ch/twiki/bin/view/AtlasProtected/AnalysisMetadata#Event_Bookkeepers + const xAOD::CutBookkeeperContainer* cutBookKeepers = 0; + // Try to get the cut bookkeepers. + // <tom.neep@cern.ch> (4/4/16): Not there in DAOD_TRUTH1? + // If we can't get them and we are running on TRUTH then carry on, + // but anything else is bad! + if(topConfig->isTruthDxAOD()) + { + ATH_MSG_INFO("Bookkeepers are not read for TRUTH derivations"); } - sumWeights->Branch("totalEvents", &totalEvents, "totalEvents/l"); + else if (!xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers")) { + ATH_MSG_ERROR("Failed to retrieve cut book keepers"); + return 1; + } else { + if (topConfig->isMC()) { + // try to retrieve CutBookKeepers for LHE3Weights first + top::parseCutBookkeepers(cutBookKeepers, LHE3_names_file, LHE3_sumW_file, topConfig->HLLHC()); + + // here we attempt to name the CutBookkeepers based on the MC weight names + // but we might end up in a situation where we don't have PMGTruthWeightTool + // e.g. if TruthMetaData container is broken in derivation + // we continue without names of the MC weights, only indices will be available + ToolHandle<PMGTools::IPMGTruthWeightTool> m_pmg_weightTool("PMGTruthWeightTool"); + if (m_pmg_weightTool.retrieve()) { + const std::vector<std::string> &weight_names = m_pmg_weightTool->getWeightNames(); + // if we have MC generator weights, we rename the bookkeepers in sumWeights TTree to match the weight names from MetaData + top::renameCutBookkeepers(LHE3_names_file, weight_names); + } else { + for (std::string &name : LHE3_names_file) { + name = "?"; + } + } - TTree* sumPdfWeights = 0; - std::unordered_map<std::string, std::vector<float> *> totalEventsPdfWeighted; - int dsidPdf = 0; - bool pdfMetadataExists = false; - if (topConfig->doLHAPDF()) { - sumPdfWeights = new TTree("PDFsumWeights", ""); - sumPdfWeights->Branch("dsid", &dsidPdf); - for (const auto &pdf_set : topConfig->LHAPDFSets()) { - totalEventsPdfWeighted[pdf_set] = new std::vector<float>(); - sumPdfWeights->Branch(pdf_set.c_str(), totalEventsPdfWeighted[pdf_set]); + // raw number of events taken from "AllExecutedEvents" bookkeeper, which corresponds to 0th MC weight + // but these are raw entries, so doesn't matter if 0th MC weight is nominal or not + initialEvents = top::getRawEventsBookkeeper(cutBookKeepers, topConfig->HLLHC()); + + // determine the nominal sum of weight -- we already found the nominal weight in ScaleFactorCalculator + const size_t nominalWeightIndex = topConfig->nominalWeightIndex(); + sumW_file = LHE3_sumW_file.at(nominalWeightIndex); + } else { + initialEvents = top::getRawEventsBookkeeper(cutBookKeepers, topConfig->HLLHC()); + sumW_file = initialEvents; // this is data, it's the same number... } } - //the analysis loop - std::cout << "Starting event loop\n"; + totalEventsWeighted += sumW_file; + totalEvents += initialEvents; - // Performance stats - if (doPerfStats > 0) - xAOD::PerfStats::instance().start(); // start Perfstats timer - - unsigned int totalYieldSoFar = 0; - unsigned int skippedEventsSoFar = 0; - unsigned int eventSavedReco(0),eventSavedRecoLoose(0),eventSavedTruth(0),eventSavedParticle(0); - for (const auto& filename : filenames) { - if (topConfig->numberOfEventsToRun() != 0 && totalYieldSoFar >= topConfig->numberOfEventsToRun() ) break; - std::cout << "Opening " << filename << std::endl; - std::unique_ptr<TFile> inputFile(TFile::Open(filename.c_str())); - - // the derivation framework is making files with an empty collection tree - // which TEvent can now handle - // However, at least for data, this is causing problems with the trigger menu - // skip the file, after the meta data access above - const TTree* const collectionTree = dynamic_cast<TTree* > (inputFile->Get("CollectionTree")); - if (!collectionTree && !topConfig->isMC()) { - std::cout << "No CollectionTree found, skipping file\n"; - continue; + // now we must fill two vectors in sync for MCGeneratorWeights sum of weights + if (topConfig->doMCGeneratorWeights() && topConfig->isMC()) { + if (totalEventsWeighted_LHE3.size() != 0) { + if (totalEventsWeighted_LHE3.size() != LHE3_sumW_file.size() + || names_LHE3.size() != LHE3_names_file.size() + || names_LHE3.size() != totalEventsWeighted_LHE3.size()) { + ATH_MSG_ERROR("Strange inconsistency of vector sizes in sum of LHE3 weights calculation."); + return 1; } - - top::check(xaodEvent.readFrom(inputFile.get()), "xAOD::TEvent readFrom failed"); - - //Get some of event weights before derivation - double initialSumOfWeightsInThisFile = 0; - ULong64_t initialEvents = 0; - - // vector of LH3 weights and teir names - std::vector<float> initialSumOfWeights_mc_generator_weightsInThisFile; - std::vector<std::string> initialSumOfWeights_mc_generator_namesInThisFile; - - // vector of PDF weights and their names - std::vector<float> initialSumOfWeights_pdf_weightsInThisFile; - std::vector<std::string> initialSumOfWeights_pdf_namesInThisFile; - - // See https://twiki.cern.ch/twiki/bin/view/AtlasProtected/AnalysisMetadata#Event_Bookkeepers - const xAOD::CutBookkeeperContainer* cutBookKeepers = 0; - // Try to get the cut bookkeepers. - // <tom.neep@cern.ch> (4/4/16): Not there in DAOD_TRUTH1? - // If we can't get them and we are running on TRUTH then carry on, - // but anything else is bad! - if (!xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers")) { - top::check(topConfig->isTruthDxAOD(), - "Failed to retrieve cut book keepers"); - } else { - int maxCycle = -1; - std::vector<int> maxCycle_LH3;// for LHE3 weights - // for the sum of number of events and of mc event weights - for ( auto cbk : *cutBookKeepers ) { - // skip RDO and ESD numbers, which are nonsense; and - // skip the derivation number, which is the one after skimming - // we want the primary xAOD numbers - if (cbk->inputStream() == "StreamAOD" && cbk->name() == "AllExecutedEvents") { - double sumOfEventWeights = cbk->sumOfEventWeights(); - ULong64_t nEvents = cbk->nAcceptedEvents(); - if (cbk->cycle() > maxCycle) { - initialSumOfWeightsInThisFile = sumOfEventWeights; - initialEvents = nEvents; - maxCycle = cbk->cycle(); - } - } - else if (cbk->inputStream() == "StreamAOD" && cbk->name().find("LHE3Weight_") != std::string::npos - && topConfig->doMCGeneratorWeights()) { - double sumOfEventWeights = cbk->sumOfEventWeights(); - std::string name=cbk->name(); - name.erase(0,11); // remove the "LHE3Weight_" - // is it a new name? If yes append it to the vector of names - // if not no need, but we must check the corresponding entry for the sum of weights exist - auto pos_name = std::find(initialSumOfWeights_mc_generator_namesInThisFile.begin(), - initialSumOfWeights_mc_generator_namesInThisFile.end(),name); - if (pos_name == initialSumOfWeights_mc_generator_namesInThisFile.end()) { - initialSumOfWeights_mc_generator_namesInThisFile.push_back(name); - initialSumOfWeights_mc_generator_weightsInThisFile.push_back(sumOfEventWeights); - maxCycle_LH3.push_back(cbk->cycle()); - } - else if (cbk->cycle() > maxCycle_LH3.at(pos_name-initialSumOfWeights_mc_generator_namesInThisFile.begin())) { - initialSumOfWeights_mc_generator_weightsInThisFile.at(pos_name-initialSumOfWeights_mc_generator_namesInThisFile.begin()) = sumOfEventWeights; - maxCycle_LH3.at(pos_name-initialSumOfWeights_mc_generator_namesInThisFile.begin()) = cbk->cycle(); - } - } - else continue; + for (unsigned int i_genweights = 0; i_genweights < LHE3_names_file.size(); + i_genweights++) { + if (names_LHE3.at(i_genweights) != LHE3_names_file.at(i_genweights)) { + ATH_MSG_ERROR("Strange inconsistency in the vector of weight names in sum of LHE3 weights calculation."); + return 1; + } else { + totalEventsWeighted_LHE3.at(i_genweights) + = totalEventsWeighted_LHE3.at(i_genweights) + + LHE3_sumW_file.at(i_genweights); } } - totalEventsWeighted += initialSumOfWeightsInThisFile; - totalEvents += initialEvents; - - // now we must fill two vectors in sync - if (topConfig->doMCGeneratorWeights()) { - if (totalEventsWeighted_LHE3.size() != 0 ) { - if (totalEventsWeighted_LHE3.size() != initialSumOfWeights_mc_generator_weightsInThisFile.size() - || names_LHE3.size() != initialSumOfWeights_mc_generator_namesInThisFile.size() - || names_LHE3.size() != totalEventsWeighted_LHE3.size() ) { - std::cout << "Ouch: strange inconsistency of vector sizes in sum of LHE3 weights calculation. There is an issue somewhere." << std::endl; - std::cout << "Exiting...." << std::endl; - std::exit(1); - } - for (unsigned int i_genweights = 0; i_genweights < initialSumOfWeights_mc_generator_namesInThisFile.size(); i_genweights++) { - if (names_LHE3.at(i_genweights) != initialSumOfWeights_mc_generator_namesInThisFile.at(i_genweights)) { - std::cout << "Ouch: strange inconsistency in the vector of weight names in sum of LHE3 weights calculation. There is an issue somewhere." << std::endl; - std::cout << "Exiting...." << std::endl; - std::exit(1); - } - else { - totalEventsWeighted_LHE3.at(i_genweights) - = totalEventsWeighted_LHE3.at(i_genweights) - + initialSumOfWeights_mc_generator_weightsInThisFile.at(i_genweights); - } - } - } - else { - for (unsigned int i_genweights = 0; i_genweights < initialSumOfWeights_mc_generator_namesInThisFile.size(); i_genweights++) { - names_LHE3.push_back(initialSumOfWeights_mc_generator_namesInThisFile.at(i_genweights)); - totalEventsWeighted_LHE3.push_back(initialSumOfWeights_mc_generator_weightsInThisFile.at(i_genweights)); - } - } - if (!names_LHE3.empty()) { - std::cout << "The sum of weights for the following LHE3 weights were retrieved from the input file:"<<std::endl; - for (std::string s : names_LHE3) std::cout<<s<<" "; - std::cout<< std::endl; - } - else { - std::cout << "No sum of LHE3 weights could be found in meta-data. Will try to recompute these sums."<<std::endl; - std::cout << "It will only work on un-skimmed derivations, and it will be impossible to know the name of these weights."<<std::endl; - recalc_LHE3 = true; - } + } else { + for (unsigned int i_genweights = 0; i_genweights < LHE3_names_file.size(); + i_genweights++) { + names_LHE3.push_back(LHE3_names_file.at(i_genweights)); + totalEventsWeighted_LHE3.push_back(LHE3_sumW_file.at(i_genweights)); } + } + if (!names_LHE3.empty()) { + ATH_MSG_INFO("The sum of weights for the following LHE3 weights were retrieved from the input file:"); + for (std::string s : names_LHE3) + msg(MSG::Level::INFO) << s << " "; + msg(MSG::Level::INFO) << std::endl; + } else { + ATH_MSG_INFO("No sum of LHE3 weights could be found in meta-data. Will try to recompute these sums.\n" + "This only works on un-skimmed derivations, and the names of these weights may be unknown (but we'll try to read them from the PMG tool"); + recalc_LHE3 = true; + } + } + + if (topConfig->isTruthDxAOD()) recalculateNominalWeightSum=true; + + if (topConfig->printCDIpathWarning()) { + ATH_MSG_WARNING( + "\n*************************************************************************\n" + << "YOU ARE USING A CUSTOM PATH TO THE CDI FILE WHICH IS NOT THE DEFAULT PATH\n" + << " YOU MANY NOT BE USING THE LATEST BTAGGING RECOMMENDATIONS \n" + << "*************************************************************************\n\n"); + } - const unsigned int entries = xaodEvent.getEntries(); - totalEventsInFiles += entries; - unsigned int firstEvent = 0; - if(topConfig->numberOfEventsToSkip() > skippedEventsSoFar){ - firstEvent = topConfig->numberOfEventsToSkip()-skippedEventsSoFar; - skippedEventsSoFar += entries < firstEvent ? entries : firstEvent; - } - for (unsigned int entry = firstEvent; entry < entries; ++entry, ++totalYieldSoFar) { - - if (topConfig->numberOfEventsToRun() != 0 && totalYieldSoFar >= topConfig->numberOfEventsToRun() ) break; - - if (entry % 100 == 0) - std::cout << " Processing event " << totalYieldSoFar << " / " << totalYield << " (current file: " << entry << " / " << entries << ")" << std::endl; - - // clear the TStore - get rid of the last events objects - xAOD::TActiveStore::store()->clear(); - // increment the event - xaodEvent.getEntry(entry); - - // Pile up and MC event weight - used to normalize the cut flows - float mcEventWeight(1.),pileupWeight(1.),zvtxWeight(1.); - if (topConfig->isMC()) - mcEventWeight = topScaleFactors->mcEventWeight(); - - if (topConfig->doPileupReweighting() && !topConfig->isTruthDxAOD()) { - top::check(topScaleFactors->executePileup(), "Failed to execute pileup reweighting"); - pileupWeight = topScaleFactors->pileupWeight(); - } - - - // get mc channel number - // to save the sum of weights - if (totalYieldSoFar == 0 && topConfig->isMC()) { - const xAOD::EventInfo *ei(nullptr); - top::check(xaodEvent.retrieve(ei, topConfig->sgKeyEventInfo()), - "xAOD::TEvent retrieve failed to get EventInfo"); - - //mcChannelNumber only available in MC simulation - if (ei->eventType(xAOD::EventInfo::IS_SIMULATION)) { - dsid = ei->mcChannelNumber(); - dsidPdf = ei->mcChannelNumber(); - } - } - - ///-- Truth events --/// - if (topConfig->isMC()) { + const unsigned int entries = xaodEvent.getEntries(); + totalEventsInFiles += entries; + unsigned int firstEvent = 0; + if (topConfig->numberOfEventsToSkip() > skippedEventsSoFar) { + firstEvent = topConfig->numberOfEventsToSkip() - skippedEventsSoFar; + skippedEventsSoFar += entries < firstEvent ? entries : firstEvent; + } + unsigned int entry; + bool isFirst(true); + for (entry = firstEvent; entry < entries; ++entry, ++totalYieldSoFar) { + if (topConfig->numberOfEventsToRun() != 0 && totalYieldSoFar >= topConfig->numberOfEventsToRun()) break; + + if (entry % 100 == 0) + ATH_MSG_INFO("Processing event " << totalYieldSoFar << " / " << totalYield + << " (current file: " << entry << " / " << entries << ")"); + + // clear the TStore - get rid of the last events objects + xAOD::TActiveStore::store()->clear(); + // increment the event + xaodEvent.getEntry(entry); + + // Pile up and MC event weight - used to normalize the cut flows + float mcEventWeight(1.), pileupWeight(1.), zvtxWeight(1.); + if (topConfig->isMC()) mcEventWeight = topScaleFactors->mcEventWeight(); + + if (topConfig->doPileupReweighting() && !topConfig->isTruthDxAOD()) { + top::check(topScaleFactors->executePileup(), "Failed to execute pileup reweighting"); + pileupWeight = topScaleFactors->pileupWeight(); + } - // Save, if requested, MC truth block, PDFInfo, TopPartons - // This will be saved for every event + // perform any operation common to both reco and truth level + // currently we load the MC generator weights inside, if requested + eventSaver->execute(); - // Run topPartonHistory - if (topConfig->doTopPartonHistory()) - top::check( topPartonHistory->execute() , "Failed to execute topPartonHistory" ); + ///-- Truth events --/// + if (topConfig->isMC()) { + // Save, if requested, MC truth block, PDFInfo, TopPartons + // This will be saved for every event - // calculate PDF weights - if( topConfig->doLHAPDF() ) - top::check( PDF_SF->execute(), - "Failed to execute PDF SF"); + // Run topPartonHistory + if (topConfig->doTopPartonHistory()) top::check(topPartonHistory->execute(), "Failed to execute topPartonHistory"); - eventSaver->saveTruthEvent(); - ++eventSavedTruth; + // calculate PDF weights + if (topConfig->doLHAPDF()) top::check(PDF_SF->execute(), + "Failed to execute PDF SF"); - // Upgrade analysis - only for truth DAODs when asking to do upgrade studies - if (topConfig->isTruthDxAOD() && topConfig->HLLHC()) { - top::ParticleLevelEvent upgradeEvent = upgradeLoader.load(); + eventSaver->saveTruthEvent(); + if(topConfig->doTopPartonLevel()) ++eventSavedTruth; - //event selection - const bool saveEventInOutputFile = eventSelectionManager.applyUpgradeLevel( upgradeEvent ); + // Upgrade analysis - only for truth DAODs when asking to do upgrade studies + if (topConfig->isTruthDxAOD() && topConfig->HLLHC()) { + //top::ParticleLevelEvent upgradeEvent = upgradeLoader.load(); - if ( saveEventInOutputFile ) { - eventSaver->saveUpgradeEvent( upgradeEvent ); - } - } + ////event selection + //const bool saveEventInOutputFile = eventSelectionManager.applyUpgradeLevel(upgradeEvent); - // Particle level analysis, saved only for truth events passing fiducial selection + //if (saveEventInOutputFile) { + // eventSaver->saveUpgradeEvent(upgradeEvent); + // ++eventSavedUpgrade; + //} + } - // -------------------------------------------------- - // If the truth loader is active, perform truth loading. - if ( particleLevelLoader.active() && !topConfig->HLLHC() ){ - // -------------------------------------------------- - // Get the top::TruthEvent for the current event - top::ParticleLevelEvent particleLevelEvent = particleLevelLoader.load(); + // Particle level analysis, saved only for truth events passing fiducial selection - //event selection - const bool saveEventInOutputFile = eventSelectionManager.applyParticleLevel( particleLevelEvent ); + // -------------------------------------------------- + // If the truth loader is active, perform truth loading. + if (particleLevelLoader.active()) { + // -------------------------------------------------- + // Get the top::TruthEvent for the current event + top::ParticleLevelEvent particleLevelEvent = particleLevelLoader.load(); - if ( saveEventInOutputFile ) { - eventSaver->saveParticleLevelEvent( particleLevelEvent ); - ++eventSavedParticle; - } - } + //event selection + const bool saveEventInOutputFile = eventSelectionManager.applyParticleLevel(particleLevelEvent); + if (saveEventInOutputFile) { + eventSaver->saveParticleLevelEvent(particleLevelEvent); + ++eventSavedParticle; + } + } + } + if (totalYieldSoFar == 0 && topConfig->isMC() && topConfig->doLHAPDF()) { + const xAOD::TruthEventContainer* truthEvent(nullptr); + top::check(xaodEvent.retrieve(truthEvent, topConfig->sgKeyTruthEvent()), "Failed to retrieve TruthEvent container for LHAPDF"); + top::check(truthEvent->size() == 1, "TruthEvent container size != 1, not sure what to do with PDF reweighting"); + for (auto tePtr : *truthEvent) { + for (auto& pdf : totalEventsPdfWeighted) { + if (tePtr->isAvailable< std::vector<float> >("AnalysisTop_" + pdf.first + "_Weights")) { + pdf.second->resize(tePtr->auxdata< std::vector<float> >("AnalysisTop_" + pdf.first + "_Weights").size()); } - if (totalYieldSoFar == 0 && topConfig->isMC() && topConfig->doLHAPDF()) { - const xAOD::TruthEventContainer* truthEvent(nullptr); - top::check( xaodEvent.retrieve(truthEvent, topConfig->sgKeyTruthEvent()) , "Failed to retrieve truth PDF info" ); - for( auto tePtr : *truthEvent ) { - for (auto &pdf : totalEventsPdfWeighted) { - if( tePtr->isAvailable< std::vector<float> >("AnalysisTop_"+pdf.first+"_Weights") ) { - pdf.second->resize(tePtr->auxdata< std::vector<float> >("AnalysisTop_"+pdf.first+"_Weights").size()); - } - } - } - } - // on the first event, set the size of the vector of sum of LHE3 weights in case it needs to be calculated on the fly - if (topConfig->isMC() && topConfig->doMCGeneratorWeights()) { - const xAOD::TruthEventContainer* truthEvent(nullptr); - top::check( xaodEvent.retrieve(truthEvent, topConfig->sgKeyTruthEvent()) , "Failed to retrieve LHE3 weights from truth event" ); - unsigned int weightsSize = truthEvent->at(0)->weights().size(); - if (recalc_LHE3) { - if (totalYieldSoFar == 0) { - totalEventsWeighted_LHE3_temp.resize(weightsSize); - for (unsigned int i_LHE3 = 0; i_LHE3<weightsSize; i_LHE3++) { - totalEventsWeighted_LHE3_temp.at(i_LHE3) = truthEvent->at(0)->weights().at(i_LHE3); - } - names_LHE3.resize(weightsSize); - std::fill(names_LHE3.begin(),names_LHE3.end(),"?"); - } - else { - for (unsigned int i_LHE3 = 0; i_LHE3<weightsSize; i_LHE3++) { - totalEventsWeighted_LHE3_temp.at(i_LHE3) = totalEventsWeighted_LHE3_temp.at(i_LHE3) + truthEvent->at(0)->weights().at(i_LHE3); - } - } + } + } + } + // on the first event, set the size of the vector of sum of LHE3 weights in case it needs to be calculated on the + // fly + + if (topConfig->isMC()) { + const xAOD::EventInfo* ei(nullptr); + top::check(xaodEvent.retrieve(ei, topConfig->sgKeyEventInfo()), + "Failed to retrieve LHE3 weights from EventInfo"); + + if(recalculateNominalWeightSum) + { + if (totalYieldSoFar == 0) ATH_MSG_INFO("Trying to recalculate nominal weights sum for TRUTH derivation"); + const size_t nominalWeightIndex = topConfig->nominalWeightIndex(); + totalEventsWeighted_temp += ei->mcEventWeights().at(nominalWeightIndex); + totalEvents++; + } + + if(topConfig->doMCGeneratorWeights()) + { + unsigned int weightsSize = ei->mcEventWeights().size(); + if (recalc_LHE3) { + if (totalYieldSoFar == 0) { + totalEventsWeighted_LHE3_temp.resize(weightsSize); + for (unsigned int i_LHE3 = 0; i_LHE3 < weightsSize; i_LHE3++) { + totalEventsWeighted_LHE3_temp.at(i_LHE3) = ei->mcEventWeights().at(i_LHE3); + } + names_LHE3.resize(weightsSize); + + ToolHandle<PMGTools::IPMGTruthWeightTool> m_pmg_weightTool("PMGTruthWeightTool"); + if (m_pmg_weightTool.retrieve()) { + const std::vector<std::string> &weight_names = m_pmg_weightTool->getWeightNames(); + if(weight_names.size() != weightsSize) + { + ATH_MSG_INFO("In top-xaod, while calculating mc weights sums on the fly, names from PMG tools have different size wrt weight vector, we'll not retrieve weight names"); + std::fill(names_LHE3.begin(), names_LHE3.end(), "?"); } - else if (weightsSize != names_LHE3.size()) {// don't recalc sum of weights, but cross-check the size of the vectors - std::cout << "Ouch: strange inconsistency in the sum of LHE3 weights vectors from the meta-data and the vector of LHE3 weights in the TruthEventContainer." << std::endl; - std::cout << "It should be the same; since it's not, it's pointless to continue."; - std::cout << "Exiting...." << std::endl; - std::exit(1); + else{ + for(unsigned int i_wgt=0; i_wgt<weight_names.size(); i_wgt++) names_LHE3[i_wgt]=weight_names[i_wgt]; } - } - ///-- End of Truth events -- start of reconstruction level events --/// - if (topConfig->isTruthDxAOD()) - continue; - - - ///-- We veto events that do not pass the GRL, trigger or have bad calorimeters --/// - ///-- No point calibrating and cutting on events that fail these cuts --/// - ///-- We only apply a veto if ALL selectors request a cut --/// - ///-- And if the user selects "OutputEvents SelectedEvents" --/// - - ///-- Count initial events --/// - eventSelectionManager.countInitial(mcEventWeight,pileupWeight,zvtxWeight); - - ///-- Does event pass the GRL? (always true for MC) --/// - ///-- Only veto events when ALL user selectors request GRL --/// - bool passGRLVeto = eventCleaning->applyGRL(); - if (!passGRLVeto) - continue; - eventSelectionManager.countGRL(mcEventWeight,pileupWeight,zvtxWeight); - - ///-- Are the Tile and LAr calorimeters in a good state? (always true for MC) --/// - ///-- Only veto events when ALL user selectors request GOODCALO --/// - bool passGoodCalo = eventCleaning->applyGoodCalo(); - if (!passGoodCalo) - continue; - eventSelectionManager.countGoodCalo(mcEventWeight,pileupWeight,zvtxWeight); - - ///-- Do we have a Primary Vertex? --/// - ///-- Only veto events when ALL user selectors request PRIVTX -- /// - bool passPriVtx = eventCleaning->applyPrimaryVertex(); - if (!passPriVtx) - continue; - eventSelectionManager.countPrimaryVertex(mcEventWeight,pileupWeight,zvtxWeight); - - ///-- Wondering which triggers are available ??? --/// - ///-- Uncomment this line and get ready for a LOT of output --/// - // eventCleaning->printTriggers(); - - ///-- Does event pass any trigger ? --/// - ///-- Only veto events when ALL user selectors request TRIGDEC --/// - ///-- And all trigger fail --/// - bool passAnyTriggerVeto = eventCleaning->applyTrigger(); - if (!passAnyTriggerVeto) - continue; - - ///-- Calibrate objects and make all required systematic copies --/// - top::check( systObjMaker->execute() , "Failed to execute systObjMaker" ); - - ///-- Object selection (e.g. good electrons, muons, jets etc.). Event selection cuts comes later --/// - top::check( objectSelection->execute() , "Failed to execute objectSelection" ); - - ///-- Recalculate MissingET based on object selection --/// - top::check( systObjMaker->recalculateMET() , "Failed to recalculateMET with systObjMaker" ); - - ///-- Scale Factor calculation --/// - if (topConfig->isMC()) - top::check( topScaleFactors->execute() , "Failed to calculate scale factors" ); - - if (!topConfig->doLooseTreeOnly()) { - ///-- Loop over all systematics and make a "top::Event" for each --/// - const xAOD::SystematicEventContainer* allSystematics = topEventMaker->systematicEvents( topConfig->sgKeyTopSystematicEvents() ); - for (auto currentSystematic : *allSystematics) { - ///-- Make a top::Event --/// - top::Event topEvent = topEventMaker->makeTopEvent( *currentSystematic ); - ///-- Apply event selection --/// - const bool passAnyEventSelection = eventSelectionManager.apply(topEvent,*currentSystematic ); - currentSystematic->auxdecor<char>(topConfig->passEventSelectionDecoration()) = passAnyEventSelection ? 1 : 0; - topEvent.m_saveEvent = passAnyEventSelection; - ///-- Save event - we defer to eventSaver the decision to write or not --/// - eventSaver->saveEvent(topEvent); - - ///-- For printout at the end of job, only count nominal events --/// - if (passAnyEventSelection && currentSystematic->hashValue() == topConfig->nominalHashValue()) - ++eventSavedReco; } - ///-- End loop over all calibration systematics --/// + else{ + std::fill(names_LHE3.begin(), names_LHE3.end(), "?"); + } + } else { + for (unsigned int i_LHE3 = 0; i_LHE3 < weightsSize; i_LHE3++) { + totalEventsWeighted_LHE3_temp.at(i_LHE3) = totalEventsWeighted_LHE3_temp.at(i_LHE3) + + ei->mcEventWeights().at(i_LHE3); + } } - ///-- End of tight events --/// - - if (topConfig->doLooseEvents()) { - ///-- Loop over all Loose systematics and make a "top::Event" for each --/// - const xAOD::SystematicEventContainer* allSystematicsLoose = topEventMaker->systematicEvents( topConfig->sgKeyTopSystematicEventsLoose() ); - for (auto currentSystematic : *allSystematicsLoose) { - ///-- Make a top::Event --/// - top::Event topEvent = topEventMaker->makeTopEvent( *currentSystematic ); - ///-- Apply event selection --/// - const bool passAnyEventSelection = eventSelectionManager.apply(topEvent,*currentSystematic ); - currentSystematic->auxdecor<char>(topConfig->passEventSelectionDecoration()) = passAnyEventSelection ? 1 : 0; - topEvent.m_saveEvent = passAnyEventSelection; - ///-- weights for matrix-method fakes estimate, only for nominal --/// - if (!topConfig->isMC() && topConfig->doFakesMMWeights() && currentSystematic->hashValue() == topConfig->nominalHashValue()) { - top::check( topfakesMMWeights->execute(&topEvent) , "Failed to execute fakes mmweight calculation"); - } - ///-- Save event - we defer to eventSaver the decision to write or not --/// - eventSaver->saveEvent(topEvent); - - ///-- For printout at the end of job, only count nominal events --/// - if (passAnyEventSelection && currentSystematic->hashValue() == topConfig->nominalHashValue()) - ++eventSavedRecoLoose; + } else if (weightsSize != names_LHE3.size()) {// don't recalc sum of weights, but cross-check the size of the + // vectors + ATH_MSG_ERROR("Strange size inconsistency in the AllExecutedEvents* " + "sum of weights bookkeepers from the meta-data and the vector of " + "LHE3 weights in the EventInfo container."); + return 1; + } + } + } + ///-- End of Truth events -- start of reconstruction level events --/// + if (topConfig->isTruthDxAOD()) continue; + + + ///-- We veto events that do not pass the GRL, trigger or have bad calorimeters --/// + ///-- No point calibrating and cutting on events that fail these cuts --/// + ///-- We only apply a veto if ALL selectors request a cut --/// + ///-- And if the user selects "OutputEvents SelectedEvents" --/// + + ///-- Count initial events --/// + eventSelectionManager.countInitial(mcEventWeight, pileupWeight, zvtxWeight); + + ///-- Does event pass the GRL? (always true for MC) --/// + ///-- Only veto events when ALL user selectors request GRL --/// + bool passGRLVeto = eventCleaning->applyGRL(); + if (!passGRLVeto) continue; + eventSelectionManager.countGRL(mcEventWeight, pileupWeight, zvtxWeight); + + ///-- Are the Tile and LAr calorimeters in a good state? (always true for MC) --/// + ///-- Only veto events when ALL user selectors request GOODCALO --/// + bool passGoodCalo = eventCleaning->applyGoodCalo(); + if (!passGoodCalo) continue; + eventSelectionManager.countGoodCalo(mcEventWeight, pileupWeight, zvtxWeight); + + ///-- Do we have a Primary Vertex? --/// + ///-- Only veto events when ALL user selectors request PRIVTX -- /// + bool passPriVtx = eventCleaning->applyPrimaryVertex(); + if (!passPriVtx) continue; + eventSelectionManager.countPrimaryVertex(mcEventWeight, pileupWeight, zvtxWeight); + + ///-- Wondering which triggers are available ??? --/// + ///-- Uncomment this line and get ready for a LOT of output --/// + // eventCleaning->printTriggers(); + + ///-- Does event pass any trigger ? --/// + ///-- Only veto events when ALL user selectors request TRIGDEC --/// + ///-- And all trigger fail --/// + bool passAnyTriggerVeto = eventCleaning->applyTrigger(); + if (!passAnyTriggerVeto) continue; + + ///-- Nominal objects -- /// + ///-- Calibrate objects and make all required systematic copies --/// + top::check(systObjMaker->execute(true), "Failed to execute systObjMaker"); + + ///-- Object selection (e.g. good electrons, muons, jets etc.). Event selection cuts comes later --/// + top::check(objectSelection->execute(true), "Failed to execute objectSelection"); + + ///-- Recalculate MissingET based on object selection --/// + top::check(systObjMaker->recalculateMET(true), "Failed to recalculateMET with systObjMaker"); + + ///-- Systematic objects -- /// + ///-- Calibrate objects and make all required systematic copies --/// + top::check(systObjMaker->execute(false), "Failed to execute systObjMaker"); + + ///-- Object selection (e.g. good electrons, muons, jets etc.). Event selection cuts comes later --/// + top::check(objectSelection->execute(false), "Failed to execute objectSelection"); + + ///-- Recalculate MissingET based on object selection --/// + top::check(systObjMaker->recalculateMET(false), "Failed to recalculateMET with systObjMaker"); + + + ///-- Scale Factor calculation --/// + if (topConfig->isMC()) top::check(topScaleFactors->execute(), "Failed to calculate scale factors"); + + if (topConfig->doTightEvents()) { + ///-- Loop over all systematics and make a "top::Event" for each --/// + const xAOD::SystematicEventContainer* allSystematics = topEventMaker->systematicEvents( + topConfig->sgKeyTopSystematicEvents()); + for (auto currentSystematic : *allSystematics) { + if (!(currentSystematic->hashValue() == topConfig->nominalHashValue() || topConfig->doTightSysts())) continue; + + ///-- Make a top::Event --/// + top::Event topEvent = topEventMaker->makeTopEvent(currentSystematic); + ///-- Apply event selection --/// + const bool passAnyEventSelection = eventSelectionManager.apply(topEvent, *currentSystematic); + // check if we are using actual mu for mc16d or mc16e + if (isFirst && topConfig->isMC()) { + const int runNumber = topEvent.m_info->runNumber(); + if (runNumber >= 300000) { + if ((!topConfig->isAFII() && topConfig->PileupActualMu_FS().size() == 0) || + (topConfig->isAFII() && topConfig->PileupActualMu_AF().size() == 0)) { + ATH_MSG_WARNING("\n***************************************************************************************\nYou are running over mc16d or mc16e sample but you are not using actual mu reweighting!\nYou are strongly adviced to use it.\nCheck https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#PRW_and_Lumicalc_files\n***************************************************************************************\n"); } - ///-- End loop over all loose calibration systematics --/// } - ///-- End of loose events --/// - - ///-- Needed for xAOD output, all systematics go into the same TTree --/// - eventSaver->saveEventToxAOD(); - - } //loop over events in current file - - // do it at the end, so we can get the DS id from the first event - // notice this is different from the normal sum of weights: all entries matter, not only the highest per file - if (topConfig->doLHAPDF()) { - bool pdfInCBK = false; - if (xaodEvent.retrieveMetaInput( cutBookKeepers, "CutBookkeepers" )) { - // try to get the first entry - std::string pdf_set = totalEventsPdfWeighted.begin()->first; - std::string p = pdf_set+"_0"; - for ( auto cbk : *cutBookKeepers ) { - std::string pdfName = cbk->name(); - if (p != pdfName) continue; - pdfMetadataExists = true; - pdfInCBK = true; - // reload to set iterator back to original state - if (!xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers")) {} - break; + } + currentSystematic->auxdecor<char>(topConfig->passEventSelectionDecoration()) = passAnyEventSelection ? 1 : 0; + topEvent.m_saveEvent = passAnyEventSelection; + ///-- Save event - we defer to eventSaver the decision to write or not --/// + eventSaver->saveEvent(topEvent); + + ///-- For printout at the end of job, only count nominal events --/// + if (passAnyEventSelection && + currentSystematic->hashValue() == topConfig->nominalHashValue()) ++eventSavedReco; + } + ///-- End loop over all calibration systematics --/// + } + ///-- End of tight events --/// + + if (topConfig->doLooseEvents()) { + ///-- Loop over all Loose systematics and make a "top::Event" for each --/// + const xAOD::SystematicEventContainer* allSystematicsLoose = topEventMaker->systematicEvents( + topConfig->sgKeyTopSystematicEventsLoose()); + for (auto currentSystematic : *allSystematicsLoose) { + if (!(currentSystematic->hashValue() == topConfig->nominalHashValue() || topConfig->doLooseSysts())) continue; + + ///-- Make a top::Event --/// + top::Event topEvent = topEventMaker->makeTopEvent(currentSystematic); + ///-- Apply event selection --/// + const bool passAnyEventSelection = eventSelectionManager.apply(topEvent, *currentSystematic); + + // check if we are using actual mu for mc16d or mc16e + if (isFirst && topConfig->isMC()) { + const int runNumber = topEvent.m_info->runNumber(); + ATH_MSG_INFO("RunNumber: " << runNumber); + if (runNumber >= 300000) { + if ((!topConfig->isAFII() && topConfig->PileupActualMu_FS().size() == 0) || + (topConfig->isAFII() && topConfig->PileupActualMu_AF().size() == 0)) { + ATH_MSG_WARNING("\n***************************************************************************************\nYou are running over mc16d or mc16e sample but you are not using actual mu reweighting!\nYou are strongly adviced to use it.\nCheck https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#PRW_and_Lumicalc_files\n***************************************************************************************\n"); + } } } - // if the pdf info was in the CBK the PDFSumOfWeights retrieve never happens, - // and cutBookKeepers, will keep its reference to the main CBK - if (!pdfInCBK) { // only try this if the info is not in the CBK -- this is legacy stuff - if (!xaodEvent.retrieveMetaInput( cutBookKeepers, "PDFSumOfWeights" )) { - pdfMetadataExists = false; - } - } - if (pdfMetadataExists && topConfig->saveLHAPDFEvent() && topConfig->baseLHAPDF().empty()) { - // just make a copy of it, but not all derivations have it, so just ignore it if it is not there - for (auto &pdfentry : totalEventsPdfWeighted) { - std::string pdf_set = pdfentry.first; - for (size_t n = 0; n < totalEventsPdfWeighted[pdf_set]->size(); ++n) { - std::string p = pdf_set+"_"+std::to_string(n); - bool foundPdf = false; - for ( auto cbk : *cutBookKeepers ) { - std::string pdfName = cbk->name(); - if (p != pdfName) - continue; - totalEventsPdfWeighted[pdf_set]->at(n) = cbk->sumOfEventWeights(); - foundPdf = true; - break; - } - if (!foundPdf) { // asked for PDF weighting, the PDF metadata exists, but this particular PDF is missing - // crash hard - std::cout << "The force is not strong with us, young Padawan ..." << std::endl; - std::cout << "You want to save weights to do PDF reweighting using '" << pdf_set << "', which I figure has " << totalEventsPdfWeighted[pdf_set]->size() << " sets on it." << std::endl; - std::cout << "There is metadata information for the sum of MC*PDF weights in PDFSumOfWeights, but none seem to refer to '" << p << "' therefore I do not know how to estimate the sum of weights before acceptance for this configuration." << std::endl; - std::cout << "May the force be with you in your next attempt." << std::endl; - std::exit(1); + currentSystematic->auxdecor<char>(topConfig->passEventSelectionDecoration()) = passAnyEventSelection ? 1 : 0; + topEvent.m_saveEvent = passAnyEventSelection; + ///-- weights for matrix-method fakes estimate from IFF tools, only for nominal --/// + if (!topConfig->isMC() && topConfig->doFakesMMWeightsIFF() && + currentSystematic->hashValue() == topConfig->nominalHashValue()) { + xAOD::IParticleContainer lepton(SG::VIEW_ELEMENTS); + for (auto const& t : topEvent.m_electrons) + lepton.push_back(static_cast<xAOD::Electron*>(t)); + for (auto const& t : topEvent.m_muons) + lepton.push_back(static_cast<xAOD::Muon*>(t)); + + topEvent.m_info->auxdecor<int>("njets") = topEvent.m_jets.size(); + for (const auto& tagWP : topConfig->bTagWP_available()) { + if (tagWP.find("Continuous") != std::string::npos) continue; + int nbjets = 0; + for (const auto& jetPtr : topEvent.m_jets) { + if (jetPtr->isAvailable<char>("isbtagged_" + tagWP)) { + nbjets += jetPtr->auxdataConst<char>("isbtagged_" + tagWP); } } + topEvent.m_info->auxdecor<int>("nbjets_" + tagWP) = nbjets; } - sumPdfWeights->Fill(); - } - } //doLHAPDF - } //loop over files - - //finish - std::cout << "\n"; - - if (doPerfStats > 0) - xAOD::PerfStats::instance().stop(); // Stop the PerfStats timer + std::vector<float> mmweight; + std::vector<std::vector<float> > mmweight_var; + std::vector<std::vector<std::string> > mmweight_varname; + //for (unsigned int mmi = 0; mmi < topfakesMMWeightsIFF.size(); ++mmi) { + // top::check(topfakesMMWeightsIFF[mmi]->addEvent(lepton), + // "Failed to execute fakes mmweight IFF addEvent()"); + // float asmWgt = 0.; + // top::check(topfakesMMWeightsIFF[mmi]->applySystematicVariation( + // {}), "Failed to execute fakes mmweight IFF applySystematicVariation()"); + // top::check(topfakesMMWeightsIFF[mmi]->getEventWeight(asmWgt, FakesMMConfigIFF[mmi][1], + // FakesMMConfigIFF[mmi][2]), "Failed to execute fakes mmweight IFF getEventWeight()"); + + // std::vector<float> asmWgt_var(topfakesMMWeightsIFF[mmi]->affectingSystematics().size()); + // std::vector<std::string> asmWgt_varname(topfakesMMWeightsIFF[mmi]->affectingSystematics().size()); + // for (const auto& sysvar : topfakesMMWeightsIFF[mmi]->affectingSystematics()) { + // float mmweight_syst; + // top::check(topfakesMMWeightsIFF[mmi]->applySystematicVariation( + // {sysvar}), "Failed to execute fakes mmweight IFF applySystematicVariation()"); + // top::check(topfakesMMWeightsIFF[mmi]->getEventWeight(mmweight_syst, FakesMMConfigIFF[mmi][1], + // FakesMMConfigIFF[mmi][2]), "Failed to execute fakes mmweight IFF getEventWeight()"); + // asmWgt_var.push_back(mmweight_syst); + // asmWgt_varname.push_back(sysvar.name()); + // } + // mmweight.push_back(asmWgt); + // mmweight_var.push_back(asmWgt_var); + // mmweight_varname.push_back(asmWgt_varname); + //} + topEvent.m_info->auxdecor<std::vector<float> >("ASMWeight") = mmweight; + topEvent.m_info->auxdecor<std::vector<std::vector<float> > >("ASMWeight_Syst") = mmweight_var; + topEvent.m_info->auxdecor<std::vector<std::vector<std::string> > >("ASMWeight_Systname") = mmweight_varname; + } + ///-- Save event - we defer to eventSaver the decision to write or not --/// + eventSaver->saveEvent(topEvent); - if( topConfig->doLHAPDF() ) top::check( PDF_SF->finalize() , "Failed to finalize PDF SF" ); + ///-- For printout at the end of job, only count nominal events --/// + if (passAnyEventSelection && + currentSystematic->hashValue() == topConfig->nominalHashValue()) ++eventSavedRecoLoose; + } + ///-- End loop over all loose calibration systematics --/// + } + ///-- End of loose events --/// - // this fills the sum of weights - // if the list of input files has more than - // one type of dataset (ie: the first file is ttbar and the second one - // is W+jets), then the Fill statement below needs to come in the end of - // each file's processing instead ... but why would you do that?! - if (recalc_LHE3) {// in case the sum of LHE3 weight has been re-calculated with double (but we need floats in the end) - for (double d:totalEventsWeighted_LHE3_temp) totalEventsWeighted_LHE3.push_back(d); - } - sumWeights->Fill(); - outputFile->cd(); + ///-- Needed for xAOD output, all systematics go into the same TTree --/// + eventSaver->saveEventToxAOD(); + isFirst = false; + } //loop over events in current file + if (tracker) tracker->addInputFile(inputFile->GetName(), entry - firstEvent); + // do it at the end, so we can get the DS id from the first event + // notice this is different from the normal sum of weights: all entries matter, not only the highest per file if (topConfig->doLHAPDF()) { + bool pdfInCBK = false; + if (xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers")) { + // try to get the first entry + std::string pdf_set = totalEventsPdfWeighted.begin()->first; + std::string p = pdf_set + "_0"; + for (auto cbk : *cutBookKeepers) { + std::string pdfName = cbk->name(); + if (p != pdfName) continue; + pdfMetadataExists = true; + pdfInCBK = true; + // reload to set iterator back to original state + if (!xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers")) { + } + break; + } + } + // if the pdf info was in the CBK the PDFSumOfWeights retrieve never happens, + // and cutBookKeepers, will keep its reference to the main CBK + if (!pdfInCBK) { // only try this if the info is not in the CBK -- this is legacy stuff + if (!xaodEvent.retrieveMetaInput(cutBookKeepers, "PDFSumOfWeights")) { + pdfMetadataExists = false; + } + } + if (pdfMetadataExists && topConfig->saveLHAPDFEvent() && topConfig->baseLHAPDF().empty()) { + // just make a copy of it, but not all derivations have it, so just ignore it if it is not there + for (auto& pdfentry : totalEventsPdfWeighted) { + std::string pdf_set = pdfentry.first; + for (size_t n = 0; n < totalEventsPdfWeighted[pdf_set]->size(); ++n) { + std::string p = pdf_set + "_" + std::to_string(n); + bool foundPdf = false; + for (auto cbk : *cutBookKeepers) { + std::string pdfName = cbk->name(); + if (p != pdfName) continue; + totalEventsPdfWeighted[pdf_set]->at(n) = cbk->sumOfEventWeights(); + foundPdf = true; + break; + } + if (!foundPdf) { // asked for PDF weighting, the PDF metadata exists, but this particular PDF is missing + // crash hard + ATH_MSG_ERROR( + "The force is not strong with us, young Padawan ...\n" + "You want to save weights to do PDF reweighting using '" << pdf_set << + "', which I figure has " << totalEventsPdfWeighted[pdf_set]->size() << " sets on it.\n" + "There is metadata information for the sum of MC*PDF weights in PDFSumOfWeights, " + "but none seem to refer to '" << p << "' therefore I do not know how to estimate " + "the sum of weights before acceptance for this configuration.\n" + "May the force be with you in your next attempt."); + return 1; + } + } + } + sumPdfWeights->Fill(); + } + } //doLHAPDF + } //loop over files + + if (doPerfStats > 0) xAOD::PerfStats::instance().stop(); // Stop the PerfStats timer + + if (topConfig->doLHAPDF()) top::check(PDF_SF->finalize(), "Failed to finalize PDF SF"); + + // this fills the sum of weights + // if the list of input files has more than + // one type of dataset (ie: the first file is ttbar and the second one + // is W+jets), then the Fill statement below needs to come in the end of + // each file's processing instead ... but why would you do that?! + if (recalc_LHE3) {// in case the sum of LHE3 weight has been re-calculated with double (but we need floats in the end) + for (double d:totalEventsWeighted_LHE3_temp) totalEventsWeighted_LHE3.push_back(d); + } + if(recalculateNominalWeightSum) + { + totalEventsWeighted=totalEventsWeighted_temp; + } + sumWeights->Fill(); + outputFile->cd(); + + if (topConfig->doLHAPDF()) { // Save sum of weights of PDF variations // Only do this if the metadata is not available if (totalEventsInFiles != totalEvents && !pdfMetadataExists) { - std::cout << "These are not the droids you are looking for." << std::endl; - std::cout << "There are " << totalEventsInFiles << " events in the input files, but the metadata tells me there were " << totalEvents << "before skimming." << std::endl; - std::cout << "This means you are running on skimmed derivations. You also want me to do PDF reweighting, but no PDF metadata exists!" << std::endl; - std::cout << "I don't know how to tell you the sum of MC*PDF weights before skimming. I will explode now in 3, 2, 1 ..." << std::endl; - std::exit(1); + ATH_MSG_ERROR("These are not the droids you are looking for.\n" + "You are running over skimmed derivations. We cannot determine " + "the sum of MC*PDF weights before skimming " + "because no PDF metadata is available in the file!"); + return 1; } // save recomputed sum weights - if( (!topConfig->baseLHAPDF().empty() || !pdfMetadataExists) ) { - for( auto& pdf_result : topConfig->getLHAPDFResults() ) - *(totalEventsPdfWeighted[pdf_result.first]) = pdf_result.second; + if ((!topConfig->baseLHAPDF().empty() || !pdfMetadataExists)) { + for (auto& pdf_result : topConfig->getLHAPDFResults()) + *(totalEventsPdfWeighted[pdf_result.first]) = pdf_result.second; sumPdfWeights->Fill(); } - } //doLHAPDF - - outputFile->cd(); - eventSelectionManager.finalise(); - eventSaver->finalize(); - outputFile->Close(); - bool outputFileGood = !outputFile->TestBit(TFile::kWriteError); - if (outputFileGood) { - if (gSystem->Rename(outputFile->GetName(), settings->value("OutputFilename").c_str()) != 0) - outputFileGood = false; - } - - if (!topConfig->isTruthDxAOD()) { - std::cout << "\nEvents saved to output file nominal reconstruction tree: " << eventSavedReco << "\n"; - if (topConfig->doLooseEvents()) - std::cout << "Events saved to output file nominal Loose reconstruction tree: " << eventSavedRecoLoose << "\n"; - } - if (topConfig->isMC()) { - std::cout << "Events saved to output file truth tree : "<<eventSavedTruth << "\n"; - if (particleLevelLoader.active()) { - std::cout << "Events saved to output file particle level tree : "<<eventSavedParticle << "\n"; - } - } - std::cout << "Total sum-of-weights (for normalization) : " - << totalEventsWeighted - << std::endl; - - //print some xAOD performance info - if (doPerfStats == 1) - xAOD::IOStats::instance().stats().Print("Summary"); - if (doPerfStats == 2) - xAOD::IOStats::instance().stats().Print(); - - if (!outputFileGood) { - std::cout << "ERROR: an I/O error occured while attempting to save the output file." << std::endl; - return 1; + } //doLHAPDF + + outputFile->cd(); + eventSelectionManager.finalise(); + eventSaver->finalize(); + outputFile->cd(); + if (tracker) tracker->writeTree("AnalysisTracking"); + outputFile->Close(); + bool outputFileGood = !outputFile->TestBit(TFile::kWriteError); + if (outputFileGood) { + if (gSystem->Rename(outputFile->GetName(), settings->value("OutputFilename").c_str()) != 0) outputFileGood = false; + } + + if (!topConfig->isTruthDxAOD()) { + if (topConfig->doTightEvents()) + ATH_MSG_INFO("Events saved to output file nominal reconstruction tree: " << eventSavedReco); + if (topConfig->doLooseEvents()) + ATH_MSG_INFO("Events saved to output file nominal loose reconstruction tree: " << eventSavedRecoLoose); + } + if (topConfig->isMC()) { + ATH_MSG_INFO("Events saved to output file truth tree : " << eventSavedTruth); + if (particleLevelLoader.active()) { + ATH_MSG_INFO("Events saved to output file particle level tree : " << eventSavedParticle); } - - return 0; + //if (upgradeLoader.active()) { + // ATH_MSG_INFO("Events saved to output file upgrade tree : " << eventSavedUpgrade); + //} + } + ATH_MSG_INFO("Total sum-of-weights (for normalization) : " << totalEventsWeighted); + + //print some xAOD performance info + if (doPerfStats == 1) xAOD::IOStats::instance().stats().Print("Summary"); + if (doPerfStats == 2) xAOD::IOStats::instance().stats().Print(); + + if (!outputFileGood) { + ATH_MSG_ERROR("ERROR: an I/O error occured while attempting to save the output file."); + return 1; + } + + return 0; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt index 1b86e1641a66..fc1f64a55f9c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt @@ -10,6 +10,7 @@ atlas_depends_on_subdirs( PUBLIC AthContainers PATCore PATInterfaces + TrigBunchCrossingTool TrigConfInterfaces TrigConfxAOD TrigDecisionTool @@ -34,7 +35,6 @@ atlas_depends_on_subdirs( PUBLIC JetInterface JetMomentTools JetSelectorTools - JetResolution METInterface METUtilities IsolationSelection @@ -46,7 +46,15 @@ atlas_depends_on_subdirs( PUBLIC AssociationUtils JetJvtEfficiency PMGTools - InDetTrackSystematicsTools ) + InDetTrackSelectionTool + InDetTrackSystematicsTools + #BoostedJetTaggers + FTagAnalysisInterfaces + MuonAnalysisInterfaces + #TriggerAnalysisInterfaces + #TrigGlobalEfficiencyCorrection + PMGAnalysisInterfaces + JetAnalysisInterfaces) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) @@ -64,6 +72,7 @@ atlas_add_library( TopCPTools Root/*.cxx Root/*.h Root/*.icc AthContainers PATCoreLib PATInterfaces + TrigBunchCrossingTool TrigConfInterfaces TrigConfxAODLib TrigDecisionToolLib @@ -88,7 +97,6 @@ atlas_add_library( TopCPTools Root/*.cxx Root/*.h Root/*.icc JetInterface JetMomentToolsLib JetSelectorToolsLib - JetResolutionLib METInterface METUtilitiesLib IsolationSelectionLib @@ -100,10 +108,15 @@ atlas_add_library( TopCPTools Root/*.cxx Root/*.h Root/*.icc AssociationUtilsLib JetJvtEfficiencyLib PMGToolsLib + InDetTrackSelectionToolLib InDetTrackSystematicsToolsLib + #BoostedJetTaggersLib + FTagAnalysisInterfacesLib + MuonAnalysisInterfacesLib + #TriggerAnalysisInterfacesLib + #TrigGlobalEfficiencyCorrectionLib + PMGAnalysisInterfacesLib + JetAnalysisInterfacesLib ${ROOT_LIBRARIES} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) -# Install data files from the package: -atlas_install_data( share/* ) - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopBoostedTaggingCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopBoostedTaggingCPTools.cxx new file mode 100644 index 000000000000..66dea52ac401 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopBoostedTaggingCPTools.cxx @@ -0,0 +1,169 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopCPTools/TopBoostedTaggingCPTools.h" + +#include <map> +#include <string> +#include <algorithm> +#include <iterator> + +// Top includes +#include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/Tokenize.h" +#include "TopEvent/EventTools.h" + +// JetUncertaintiesTool for the tagger SFs +#include "JetUncertainties/JetUncertaintiesTool.h" + +// Boosted tagging includes +//#include "BoostedJetTaggers/SmoothedTopTagger.h" +//#include "BoostedJetTaggers/SmoothedWZTagger.h" +//#include "BoostedJetTaggers/JSSWTopTaggerDNN.h" + +namespace top { + BoostedTaggingCPTools::BoostedTaggingCPTools(const std::string& name) : + asg::AsgTool(name) { + declareProperty("config", m_config); + } + + StatusCode BoostedTaggingCPTools::initialize() { + ATH_MSG_INFO("top::BoostedTaggingCPTools initialize..."); + + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::BoostedTaggingCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; + } + + if (!m_config->useLargeRJets()) { + ATH_MSG_INFO("top::BoostedTaggingCPTools: no need to initialise anything since not using large-R jets"); + return StatusCode::SUCCESS; + } + + + std::vector<std::pair<std::string, std::string> > boostedJetTaggers = m_config->boostedJetTaggers(); + if (boostedJetTaggers.size() == 0) { + ATH_MSG_INFO("top::BoostedTaggingCPTools: boostedJetTagging not set. No need to initialise anything."); + return StatusCode::SUCCESS; + } + + + top::check( + m_config->sgKeyLargeRJets() == "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets" || m_config->sgKeyLargeRJets() == "AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20Jets", + "Error in BoostedTaggingCPTools: boosted jet taggers are not available for this large-R jet collection."); + + std::unordered_map<std::string, std::string > taggersConfigs; + std::unordered_map<std::string, std::string > taggerSFconfigs; + std::unordered_map<std::string, std::string > taggerSFnames; + std::unordered_map<std::string, std::string > taggersCalibAreas; + + std::vector<std::string > taggersTypes = { + "JSSWTopTaggerDNN", "SmoothedWZTagger" + }; + + taggersCalibAreas["JSSWTopTaggerDNN"] = "JSSWTopTaggerDNN/Rel21/"; + taggersCalibAreas["SmoothedWZTagger"] = "SmoothedWZTaggers/Rel21/"; + + if (m_config->sgKeyLargeRJets() == "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets") { + taggersConfigs["JSSWTopTaggerDNN:DNNTaggerTopQuarkContained50"] = + "JSSDNNTagger_AntiKt10LCTopoTrimmed_TopQuarkContained_MC16d_20190405_50Eff.dat"; + taggersConfigs["JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80"] = + "JSSDNNTagger_AntiKt10LCTopoTrimmed_TopQuarkContained_MC16d_20190827_80Eff.dat"; + taggersConfigs["JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive50"] = + "JSSDNNTagger_AntiKt10LCTopoTrimmed_TopQuarkInclusive_MC16d_20190405_50Eff.dat"; + taggersConfigs["JSSWTopTaggerDNN:DNNTaggerTopQuarkInclusive80"] = + "JSSDNNTagger_AntiKt10LCTopoTrimmed_TopQuarkInclusive_MC16d_20190405_80Eff.dat"; + + taggersConfigs["SmoothedWZTagger:SmoothWContained50"] = + "SmoothedContainedWTagger_AntiKt10LCTopoTrimmed_FixedSignalEfficiency50_MC16d_20190410.dat"; + taggersConfigs["SmoothedWZTagger:SmoothWContained80"] = + "SmoothedContainedWTagger_AntiKt10LCTopoTrimmed_FixedSignalEfficiency80_MC16d_20190410.dat"; + + taggersConfigs["SmoothedWZTagger:SmoothZContained50"] = + "SmoothedContainedZTagger_AntiKt10LCTopoTrimmed_FixedSignalEfficiency50_MC16d_20190410.dat"; + taggersConfigs["SmoothedWZTagger:SmoothZContained80"] = + "SmoothedContainedZTagger_AntiKt10LCTopoTrimmed_FixedSignalEfficiency80_MC16d_20190410.dat"; + + // tagger SF uncertainties + taggerSFconfigs["JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80"] = + "rel21/Summer2019/R10_SF_LC_DNNContained80_TopTag.config"; + taggerSFnames["JSSWTopTaggerDNN:DNNTaggerTopQuarkContained80"] = "DNNTaggerTopQuarkContained80_SF"; + } else if (m_config->sgKeyLargeRJets() == "AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20Jets") { + taggersConfigs["SmoothedWZTagger:SmoothWContained2VarMaxSig"] = + "SmoothedWTagger_AntiKt10TrackCaloClusterTrimmed_MaxSignificance_2Var_MC16d_20190809.dat"; + taggersConfigs["SmoothedWZTagger:SmoothZContained2VarMaxSig"] = + "SmoothedZTagger_AntiKt10TrackCaloClusterTrimmed_MaxSignificance_2Var_MC16d_20190809.dat"; + + taggersConfigs["SmoothedWZTagger:SmoothW3VarMaxSig"] = + "SmoothedContainedWTagger_AntiKt10TrackCaloClusterTrimmed_MaxSignificance_3Var_MC16d_20190410.dat"; + taggersConfigs["SmoothedWZTagger:SmoothZ3VarMaxSig"] = + "SmoothedContainedZTagger_AntiKt10TrackCaloClusterTrimmed_MaxSignificance_3Var_MC16d_20190410.dat"; + + // tagger SF uncertainties + taggerSFconfigs["SmoothedWZTagger:SmoothWContained2VarMaxSig"] = + "rel21/Summer2019/R10_SF_TCC_2VarSmooth_WTag.config"; + taggerSFnames["SmoothedWZTagger:SmoothWContained2VarMaxSig"] = "SmoothWContained2VarMaxSig_SF"; + taggerSFconfigs["SmoothedWZTagger:SmoothZContained2VarMaxSig"] = + "rel21/Summer2019/R10_SF_TCC_2VarSmooth_ZTag.config"; + taggerSFnames["SmoothedWZTagger:SmoothZContained2VarMaxSig"] = "SmoothZContained2VarMaxSig_SF"; + } + + for (const std::pair<std::string, std::string>& name : boostedJetTaggers) { + const std::string& taggerType = name.first; + const std::string& shortName = name.second; + const std::string fullName = taggerType + "_" + shortName; // Name to idendify tagger + const std::string origName = taggerType + ":" + shortName; // Original name set in the top config + + top::check(taggersConfigs.find(origName) != taggersConfigs.end(), + ("Error in BoostedTaggingCPTools: Unknown tagger in the config file: " + origName).c_str()); + + top::check(std::find(taggersTypes.begin(), taggersTypes.end(), + taggerType) != taggersTypes.end(), "Error in BoostedTaggingCPTools: Unknown TAGGER_TYPE."); +// if (taggerType == "JSSWTopTaggerDNN") top::check(ASG_MAKE_ANA_TOOL(m_taggers[fullName], +// JSSWTopTaggerDNN), +// "Failed to make " + origName); +// else if (taggerType == "SmoothedWZTagger") top::check(ASG_MAKE_ANA_TOOL(m_taggers[fullName], +// SmoothedWZTagger), +// "Failed to make " + origName); + + m_taggers[fullName].setName(fullName); + top::check(m_taggers[fullName].setProperty("ConfigFile", + taggersConfigs[origName]), "Failed to set ConfigFile for " + origName); + top::check(m_taggers[fullName].setProperty("CalibArea", + taggersCalibAreas[taggerType]), + "Failed to set CalibArea for " + origName); + // not all BJT taggers implement IsMC property -- only those that have calibration SFs + // so we have to check here that we try to set this property only where applicable + if (taggerType == "JSSWTopTaggerDNN" || taggerType == "SmoothedWZTagger") { + top::check(m_taggers[fullName].setProperty("IsMC", m_config->isMC()), "Failed to set IsMC for " + origName); + } + top::check(m_taggers[fullName].initialize(), "Failed to initialize " + origName); + + // initialize SF uncertainty tools for supported WPs + if (m_config->isMC()) { + std::string jet_def = m_config->sgKeyLargeRJets(); + jet_def.erase(jet_def.length() - 4); // jet collection name sans 'Jets' suffix + + const std::string name = "JetSFuncert_" + fullName; + try { + const std::string& cfg = taggerSFconfigs.at(origName); + JetUncertaintiesTool* jet_SF_tmp = new JetUncertaintiesTool(name); + + top::check(jet_SF_tmp->setProperty("JetDefinition", jet_def), "Failed to set JetDefinition for " + name); + top::check(jet_SF_tmp->setProperty("MCType", "MC16"), "Failed to set MCType for " + name); + top::check(jet_SF_tmp->setProperty("ConfigFile", cfg), "Failed to set MCType for " + name); + top::check(jet_SF_tmp->setProperty("IsData", false), "Failed to set IsData for " + name); + top::check(jet_SF_tmp->initialize(), "Failed to initialize " + name); + m_tagSFuncertTool[fullName] = jet_SF_tmp; + m_config->setCalibBoostedJetTagger(fullName, taggerSFnames[origName]); + } catch (std::out_of_range& e) { + // skip taggers which do not yet have SFs available + ATH_MSG_WARNING("Boosted jet tagger " + fullName + " is not yet calibrated! No SFs are available."); + } + } + } + + return StatusCode::SUCCESS; + } +} // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopEgammaCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopEgammaCPTools.cxx index 47cdda921fea..77f0c5fc7122 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopEgammaCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopEgammaCPTools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopEgammaCPTools.h" @@ -19,14 +19,13 @@ #include "ElectronPhotonSelectorTools/AsgElectronLikelihoodTool.h" #include "ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h" #include "ElectronEfficiencyCorrection/ElectronChargeEfficiencyCorrectionTool.h" -#include "ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h" #include "ElectronPhotonSelectorTools/AsgPhotonIsEMSelector.h" #include "ElectronPhotonShowerShapeFudgeTool/ElectronPhotonShowerShapeFudgeTool.h" #include "PhotonEfficiencyCorrection/AsgPhotonEfficiencyCorrectionTool.h" +#include "Root/EGSelectorConfigurationMapping.h" namespace top { - -EgammaCPTools::EgammaCPTools(const std::string& name) : + EgammaCPTools::EgammaCPTools(const std::string& name) : asg::AsgTool(name), m_electronEffTriggerFile("SetMe"), m_electronEffTriggerLooseFile("SetMe"), @@ -37,405 +36,719 @@ EgammaCPTools::EgammaCPTools(const std::string& name) : m_electronEffSFIDLooseFile("SetMe"), m_electronEffSFIsoFile("SetMe"), m_electronEffSFIsoLooseFile("SetMe"), - m_electronEffSFChargeIDFile("SetMe") { - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); - - declareProperty( "EgammaCalibrationAndSmearingTool" , m_egammaCalibrationAndSmearingTool ); - declareProperty( "ElectronEffTrigger" , m_electronEffTrigger ); - declareProperty( "ElectronEffTriggerLoose" , m_electronEffTriggerLoose ); - declareProperty( "ElectronEffSFTrigger" , m_electronEffSFTrigger ); - declareProperty( "ElectronEffSFTriggerLoose" , m_electronEffSFTriggerLoose ); - declareProperty( "ElectronEffReco" , m_electronEffSFReco ); - declareProperty( "ElectronEffID" , m_electronEffSFID ); - declareProperty( "ElectronEffIDLoose" , m_electronEffSFIDLoose ); - declareProperty( "ElectronEffIso" , m_electronEffSFIso ); - declareProperty( "ElectronEffIsoLoose" , m_electronEffSFIsoLoose ); - declareProperty( "ElectronEffChargeID" , m_electronEffSFChargeID ); - - declareProperty( "PhotonIsEMSelectorLoose" , m_photonLooseIsEMSelector); - declareProperty( "PhotonIsEMSelectorMedium" , m_photonMediumIsEMSelector); - declareProperty( "PhotonIsEMSelectorTight" , m_photonTightIsEMSelector); -} - -StatusCode EgammaCPTools::initialize() { - ATH_MSG_INFO("top::EgammaCPTools initialize..."); - - if (m_config->isTruthDxAOD()) { - ATH_MSG_INFO("top::EgammaCPTools: no need to initialise anything on truth DxAOD"); - return StatusCode::SUCCESS; + m_electronEffSFChargeIDFile("SetMe"), + m_electronEffSFChargeIDLooseFile("SetMe"), + m_electronEffSFChargeMisIDFile("SetMe"), + m_electronEffSFChargeMisIDLooseFile("SetMe") { +// m_fwdElectronEffSFIDFile("SetMe"), +// m_fwdElectronEffSFIDLooseFile("SetMe") { + declareProperty("config", m_config); + + declareProperty("EgammaCalibrationAndSmearingTool", m_egammaCalibrationAndSmearingTool); + declareProperty("ElectronEffTrigger", m_electronEffTrigger); + declareProperty("ElectronEffTriggerLoose", m_electronEffTriggerLoose); + declareProperty("ElectronEffSFTrigger", m_electronEffSFTrigger); + declareProperty("ElectronEffSFTriggerLoose", m_electronEffSFTriggerLoose); + declareProperty("ElectronEffReco", m_electronEffSFReco); + declareProperty("ElectronEffID", m_electronEffSFID); + declareProperty("ElectronEffIDLoose", m_electronEffSFIDLoose); + declareProperty("ElectronEffIso", m_electronEffSFIso); + declareProperty("ElectronEffIsoLoose", m_electronEffSFIsoLoose); + declareProperty("ElectronEffChargeID", m_electronEffSFChargeID); + declareProperty("ElectronEffChargeIDLoose", m_electronEffSFChargeIDLoose); + + declareProperty("ElectronEffTriggerCorrModel", m_electronEffTriggerCorrModel); + declareProperty("ElectronEffTriggerLooseCorrModel", m_electronEffTriggerLooseCorrModel); + declareProperty("ElectronEffSFTriggerCorrModel", m_electronEffSFTriggerCorrModel); + declareProperty("ElectronEffSFTriggerLooseCorrModel", m_electronEffSFTriggerLooseCorrModel); + declareProperty("ElectronEffRecoCorrModel", m_electronEffSFRecoCorrModel); + declareProperty("ElectronEffIDCorrModel", m_electronEffSFIDCorrModel); + declareProperty("ElectronEffIDLooseCorrModel", m_electronEffSFIDLooseCorrModel); + declareProperty("ElectronEffIsoCorrModel", m_electronEffSFIsoCorrModel); + declareProperty("ElectronEffIsoLooseCorrModel", m_electronEffSFIsoLooseCorrModel); + + declareProperty("PhotonIsEMSelectorLoose", m_photonLooseIsEMSelector); + declareProperty("PhotonIsEMSelectorMedium", m_photonMediumIsEMSelector); + declareProperty("PhotonIsEMSelectorTight", m_photonTightIsEMSelector); + +// declareProperty("FwdElectronSelector", m_fwdElectronSelector); +// declareProperty("FwdElectronSelectorLoose", m_fwdElectronSelectorLoose); +// declareProperty("FwdElectronEffIDLoose", m_fwdElectronEffSFIDLoose); +// declareProperty("WebBunchCrossingTool", m_webBunchCrossingTool); } - if (m_config->usePhotons() || m_config->useElectrons()) { - if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs - top::check(setupCalibration(), "Failed to setup Egamma calibration tools"); + StatusCode EgammaCPTools::initialize() { + ATH_MSG_INFO("top::EgammaCPTools initialize..."); + + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::EgammaCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; } - if (m_config->isMC()) {// scale-factors are only for MC - top::check(setupScaleFactors(), "Failed to setup Egamma scale-factor tools"); + + if (m_config->usePhotons() || m_config->useElectrons() || m_config->useFwdElectrons()) { + if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs + top::check(setupCalibration(), "Failed to setup Egamma calibration tools"); + } + if (m_config->useFwdElectrons() && m_config->makeAllCPTools()) { + top::check(setupSelectors(), "Failed to setup Fwd electrons selectors tools"); + } + if (m_config->isMC()) {// scale-factors are only for MC + top::check(setupScaleFactors(), "Failed to setup Egamma scale-factor tools"); + } + } else { + ATH_MSG_INFO( + "top::EgammaCPTools: no need to initialise anything since using neither electrons nor fwd electrons nor photons"); } - } - else { - ATH_MSG_INFO("top::EgammaCPTools: no need to initialise anything since using neither electrons nor photons"); - } - return StatusCode::SUCCESS; -} - - -StatusCode EgammaCPTools::setupCalibration() { - // Setup electron and photon calibration tools - // List of tools include: - // - EgammaCalibrationAndSmearingTool - // - Electron Charge ID Selector tool - // - Photon shower shape fudge tool - // - Photon efficiency correction tool - using IEgammaCalibTool = CP::IEgammaCalibrationAndSmearingTool; - const std::string egamma_calib_name = "CP::EgammaCalibrationAndSmearingTool"; - if (asg::ToolStore::contains<IEgammaCalibTool>(egamma_calib_name)) { - m_egammaCalibrationAndSmearingTool = asg::ToolStore::get<IEgammaCalibTool>(egamma_calib_name); - } else { - IEgammaCalibTool* egammaCalibrationAndSmearingTool = new CP::EgammaCalibrationAndSmearingTool(egamma_calib_name); - top::check(asg::setProperty(egammaCalibrationAndSmearingTool, - "ESModel", "es2016data_mc15c"), - "Failed to set ESModel for " + egamma_calib_name); - top::check(asg::setProperty(egammaCalibrationAndSmearingTool, - "decorrelationModel", - m_config->egammaSystematicModel()), - "Failed to set decorrelationModel for " + egamma_calib_name); - - if(m_config->isAFII()) - top::check(asg::setProperty(egammaCalibrationAndSmearingTool, - "useAFII", 1), - "Failed to useAFII to true for" + egamma_calib_name); - top::check(egammaCalibrationAndSmearingTool->initialize(), - "Failed to initialize " + egamma_calib_name); - m_egammaCalibrationAndSmearingTool = egammaCalibrationAndSmearingTool; + return StatusCode::SUCCESS; } - // - Electron Charge ID Selector Tool - // The only supported working point is Medium with 97% integrated efficiency - // Note: this working point is to be applied on top of MediumLLH + d0z0 cuts + isolFixedCutTight - // https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/ElectronChargeFlipTaggerTool - std::string toolName="ECIDS_medium"; - AsgElectronChargeIDSelectorTool* electronChargeIDSelectorTool = new AsgElectronChargeIDSelectorTool(toolName); - std::string trainingfile="ElectronPhotonSelectorTools/ChargeID/ECIDS_20161125for2017Moriond.root"; - float BDT_OP=-0.28087; //Set your operating point with the table above. - top::check( electronChargeIDSelectorTool->setProperty("TrainingFile",trainingfile) , "Failed to setProperty" ); - top::check( electronChargeIDSelectorTool->setProperty("CutOnBDT",BDT_OP) , "Failed to setProperty" ); - top::check( electronChargeIDSelectorTool->initialize() , "Failed to initialize" ); - - // The terribly named ElectronPhotonShowerShapeFudgeTool... - // We apply this only to photons to correct the shower shape - // This should only be applied on MC - using IFudgeTool = IElectronPhotonShowerShapeFudgeTool; - const std::string fudgeName = "PhotonFudgeTool"; - if (asg::ToolStore::contains<IFudgeTool>(fudgeName)) { - m_photonFudgeTool = asg::ToolStore::get<IFudgeTool>(fudgeName); - } else { - IFudgeTool* fudge_tool = new ElectronPhotonShowerShapeFudgeTool(fudgeName); - // Set Preselection to 21 (was 16) according to http://cern.ch/go/trk9 - // for MC15 samples, which are based on a geometry derived from GEO-21 from 2015+2016 data - top::check(asg::setProperty(fudge_tool, "Preselection", 21), - "Failed to set " + fudgeName + " property: Preselection"); - top::check(fudge_tool->initialize(), - "Failed to initialize PhotonFudgeTool"); - m_photonFudgeTool = fudge_tool; + StatusCode EgammaCPTools::setupSelectors() { + ATH_MSG_INFO("top::EgammaCPTools setupSelectors.."); + if (m_config->useFwdElectrons()) { +// m_fwdElectronSelector = new AsgForwardElectronLikelihoodTool("CP::FwdElectronSelector"); +// top::check(m_fwdElectronSelector->setProperty("ConfigFile", +// EgammaSelectors::ForwardLHPointToConfFile.at( +// m_config->fwdElectronID() + "LHForwardElectron")), +// "Failed to set config for AsgElectronFwdLikelihoodTool"); +// top::check(m_fwdElectronSelector->initialize(), "Couldn't initialise Forward Electron LH ID Tool"); +// +// m_fwdElectronSelectorLoose = new AsgForwardElectronLikelihoodTool("CP::FwdElectronSelectorLoose"); +// top::check(m_fwdElectronSelectorLoose->setProperty("ConfigFile", +// EgammaSelectors::ForwardLHPointToConfFile.at( +// m_config->fwdElectronIDLoose() + "LHForwardElectron")), +// "Failed to set config for AsgElectronFwdLikelihoodTool"); +// top::check(m_fwdElectronSelectorLoose->initialize(), "Couldn't initialise Forward Electron LH ID Loose Tool"); + + if (!m_config->isMC()) { + ATH_MSG_INFO("top::EgammaCPTools setting up web bunch crossing tool"); +// m_webBunchCrossingTool = new Trig::WebBunchCrossingTool("CP::WebBunchCrossingTool"); +// top::check(m_webBunchCrossingTool->setProperty("OutputLevel", +// MSG::INFO), "failed to set propert for WebBunchCrossingTool"); +// top::check(m_webBunchCrossingTool->setProperty("ServerAddress", +// "atlas-trigconf.cern.ch"), +// "failed to set propert for WebBunchCrossingTool"); + } + } + return StatusCode::SUCCESS; } - // The photon efficiency SF tool - bool af2 = m_config->isAFII(); - int data_type = 0; // Data - if (m_config->isMC()) { - data_type = 1; // Full sim - if (af2) { - data_type = 3; // AF2 + StatusCode EgammaCPTools::setupCalibration() { + // Setup electron and photon calibration tools + // List of tools include: + // - EgammaCalibrationAndSmearingTool + // - Electron Charge ID Selector tool + // - Photon shower shape fudge tool + // - Photon efficiency correction tool + using IEgammaCalibTool = CP::IEgammaCalibrationAndSmearingTool; + const std::string egamma_calib_name = "CP::EgammaCalibrationAndSmearingTool"; + if (asg::ToolStore::contains<IEgammaCalibTool>(egamma_calib_name)) { + m_egammaCalibrationAndSmearingTool = asg::ToolStore::get<IEgammaCalibTool>(egamma_calib_name); + } else { + IEgammaCalibTool* egammaCalibrationAndSmearingTool = new CP::EgammaCalibrationAndSmearingTool(egamma_calib_name); + top::check(asg::setProperty(egammaCalibrationAndSmearingTool, + "ESModel", "es2018_R21_v0"), + "Failed to set ESModel for " + egamma_calib_name); + top::check(asg::setProperty(egammaCalibrationAndSmearingTool, + "decorrelationModel", + m_config->egammaSystematicModel()), + "Failed to set decorrelationModel for " + egamma_calib_name); + + if (m_config->isAFII()) { + top::check(asg::setProperty(egammaCalibrationAndSmearingTool, + "useAFII", 1), + "Failed to useAFII to true for" + egamma_calib_name); + } + top::check(egammaCalibrationAndSmearingTool->initialize(), + "Failed to initialize " + egamma_calib_name); + m_egammaCalibrationAndSmearingTool = egammaCalibrationAndSmearingTool; } - } - // The file to make the tool with. - std::string file_base = "PhotonEfficiencyCorrection/"; - std::string file_map = file_base + "2015_2016/rel20.7/Moriond2017_v1/map0.txt"; - file_map = PathResolverFindCalibFile(file_map); - std::string file_con = ""; - std::string file_unc = ""; - if (af2) { - // for AFII we keep using the previous recommendations - file_base += "v1/efficiencySF.offline.Tight.2015.13TeV.rel20.AFII."; - file_con = file_base; // Conv file - file_unc = file_base; // Unconv file - file_con += "con.v01.root"; - file_con = PathResolverFindCalibFile(file_con); - file_unc += "unc.v01.root"; - file_unc = PathResolverFindCalibFile(file_unc); - } + // The terribly named ElectronPhotonShowerShapeFudgeTool... + // We apply this only to photons to correct the shower shape + // This should only be applied on MC + using IFudgeTool = IElectronPhotonShowerShapeFudgeTool; + const std::string fudgeName = "PhotonFudgeTool"; + if (asg::ToolStore::contains<IFudgeTool>(fudgeName)) { + m_photonFudgeTool = asg::ToolStore::get<IFudgeTool>(fudgeName); + } else { + IFudgeTool* fudge_tool = new ElectronPhotonShowerShapeFudgeTool(fudgeName); + // Set Preselection to 22 + // for MC15 samples, which are based on a geometry derived from GEO-21 from 2015+2016 data + top::check(asg::setProperty(fudge_tool, "Preselection", 22), + "Failed to set " + fudgeName + " property: Preselection"); + top::check(asg::setProperty(fudge_tool, "FFCalibFile", + "ElectronPhotonShowerShapeFudgeTool/v2/PhotonFudgeFactors.root"), + "Failed to set ElectronPhotonShowerShapeFudgeTool"); + top::check(fudge_tool->initialize(), + "Failed to initialize PhotonFudgeTool"); + m_photonFudgeTool = fudge_tool; + } - using IPhotonEffTool = IAsgPhotonEfficiencyCorrectionTool; - const std::string photonSFName = "AsgPhotonEfficiencyCorrectionTool"; // to retrieve ID Eff scale factors - if (asg::ToolStore::contains<IPhotonEffTool>(photonSFName)) { - m_photonEffSF = asg::ToolStore::get<IPhotonEffTool>(photonSFName); - } else { - if (m_config->isMC()) { // Seem to only be able to setup the tool for MC - IPhotonEffTool* photonEffSF = new AsgPhotonEfficiencyCorrectionTool(photonSFName); - if (!af2) { - top::check(asg::setProperty(photonEffSF, - "MapFilePath", - file_map), - "Failed to set MapFilePath for " + photonSFName); + // The photon efficiency SF tool + bool af2 = m_config->isAFII(); + int data_type = 0; // Data + if (m_config->isMC()) { + if (af2) { + ATH_MSG_WARNING("PhotonEfficiencies - Currently there are no recommendations for FastSimulation photons"); + ATH_MSG_WARNING("PhotonEfficiencies - Therefore we are advised to treat FastSim as FullSim for configuration"); + //data_type = 3; // AF2 + data_type = 1; // AF2 masquerading as full sim } else { - top::check(asg::setProperty(photonEffSF, - "CorrectionFileNameConv", - file_con), - "Failed to set CorrectionFileNameConv for " + photonSFName); - top::check(asg::setProperty(photonEffSF, - "CorrectionFileNameUnconv", - file_unc), - "Failed to set CorrectionFileNameUnconv for " + photonSFName); + data_type = 1; // Full sim } - top::check(asg::setProperty(photonEffSF, "ForceDataType", data_type), - "Failed to set ForceDataType for " + photonSFName); - top::check(photonEffSF->initialize(), - "Failed to initialize " + photonSFName); - m_photonEffSF = photonEffSF; } - } - // https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/IsolationSF2016Moriond#Radiative_Z_low_ET - // To retrieve Isolation Eff scale factors - // N.B. Naming for isolation working points for AsgPhotonEfficiencyCorrectionTool isolation scale factors - // are different than those for the IsolationCorrectionTool (preceded by FixedCut) - std::set<std::string> photon_isolations = {"TightCaloOnly", - "Tight", - "Loose"}; - for (const std::string& isoWP : photon_isolations) { - std::string photonIsoSFName = "AsgPhotonEfficiencyCorrectionTool_IsoSF" + isoWP; - if (!asg::ToolStore::contains<IPhotonEffTool>(photonIsoSFName)) { - if (m_config->isMC() && !af2) { // only available for full simulation - IPhotonEffTool* photonIsoSFTool = new AsgPhotonEfficiencyCorrectionTool(photonIsoSFName); - top::check(asg::setProperty(photonIsoSFTool, - "MapFilePath", - file_map), - "Failed to set MapFilePath for " + photonIsoSFName); - top::check(asg::setProperty(photonIsoSFTool, "ForceDataType", data_type), - "Failed to set ForceDataType for " + photonIsoSFName); - top::check(asg::setProperty(photonIsoSFTool, "UseRadiativeZSF_mediumPT", m_config->photonUseRadiativeZ()), - "Failed to set useRadiativeZSF_mediumPT for " + photonIsoSFName); - top::check(asg::setProperty(photonIsoSFTool, "IsoWP", isoWP), - "Failed to set IsoWP for " + photonIsoSFName); - top::check(photonIsoSFTool->initialize(), - "Failed to initialize " + photonIsoSFName); - m_photonIsoSFTools.push_back(photonIsoSFTool); + using IPhotonEffTool = IAsgPhotonEfficiencyCorrectionTool; + const std::string photonSFName = "AsgPhotonEfficiencyCorrectionTool"; // to retrieve ID Eff scale factors + if (asg::ToolStore::contains<IPhotonEffTool>(photonSFName)) { + m_photonEffSF = asg::ToolStore::get<IPhotonEffTool>(photonSFName); + } else { + if (m_config->isMC()) { // Seem to only be able to setup the tool for MC + IPhotonEffTool* photonEffSF = new AsgPhotonEfficiencyCorrectionTool(photonSFName); + top::check(asg::setProperty(photonEffSF, "ForceDataType", data_type), + "Failed to set ForceDataType for " + photonSFName); + top::check(photonEffSF->initialize(), + "Failed to initialize " + photonSFName); + m_photonEffSF = photonEffSF; } } - } - return StatusCode::SUCCESS; -} - -StatusCode EgammaCPTools::setupScaleFactors() { - // Don't need for data, return SUCCESS straight away - if (!m_config->isMC()) return StatusCode::SUCCESS; - ///-- Scale factors --/// - - std::string electron_data_dir = "ElectronEfficiencyCorrection/"; - ///-- Reco SFs doesn't depend on WP --/// - std::string electronID = m_config->electronID(); - electronID.replace(electronID.find("LH"), 2, "LLH"); // that way people do not have to change their cuts file - std::string electronIDLoose = m_config->electronIDLoose(); - electronIDLoose.replace(electronIDLoose.find("LH"), 2, "LLH"); // that way people do not have to change their cuts file - - m_electronEffSFRecoFile = electronSFFilePath("reco"); - m_electronEffSFIDFile = electronSFFilePath("ID", electronID); - m_electronEffSFTriggerFile = electronSFFilePath("triggerSF", electronID, - m_config->electronIsolation()); - if (m_electronEffSFTriggerFile.empty()) { - m_electronEffSFTriggerFile = electronSFFilePath("triggerSF", electronID, - "None"); - } - m_electronEffTriggerFile = electronSFFilePath("triggerEff", electronID, - m_config->electronIsolation()); - if (m_electronEffTriggerFile.empty()) { - m_electronEffTriggerFile = electronSFFilePath("triggerEff", electronID, - "None"); - } - if (m_config->electronIsolation() != "None") { - m_electronEffSFIsoFile = electronSFFilePath("isolation", electronID, - m_config->electronIsolation()); - } - // Loose SFs - m_electronEffSFIDLooseFile = electronSFFilePath("ID", electronIDLoose); - m_electronEffSFTriggerLooseFile = electronSFFilePath("triggerSF", electronIDLoose, - m_config->electronIsolationLoose()); - if (m_electronEffSFTriggerLooseFile.empty()) { - m_electronEffSFTriggerLooseFile = electronSFFilePath("triggerSF", electronIDLoose, - "None"); - } - m_electronEffTriggerLooseFile = electronSFFilePath("triggerEff", electronIDLoose, - m_config->electronIsolationLoose()); - if (m_electronEffTriggerLooseFile.empty()) { - m_electronEffTriggerLooseFile = electronSFFilePath("triggerEff", electronIDLoose, - "None"); - } - if (m_config->electronIsolationLoose() != "None") { - m_electronEffSFIsoLooseFile = electronSFFilePath("isolation", electronIDLoose, - m_config->electronIsolationLoose()); - } - // for the moment only for MediumLH and FixedCutTight isolation - // either at Tight or Loose level - if ( ( electronIDLoose == "MediumLLH" && m_config->electronIsolationLoose() == "FixedCutTight" ) - || ( electronID == "MediumLLH" && m_config->electronIsolation() == "FixedCutTight" ) ) { - m_electronEffSFChargeIDFile = electronSFFilePath("ChargeID", "MediumLLH", - "FixedCutTight"); - } - // The tools want the files in vectors: remove this with function - std::vector<std::string> inRecoSF {m_electronEffSFRecoFile}; - std::vector<std::string> inIDSF {m_electronEffSFIDFile}; - std::vector<std::string> inTriggerSF {m_electronEffSFTriggerFile}; - std::vector<std::string> inTrigger {m_electronEffTriggerFile}; - - std::vector<std::string> inIDSFLoose {m_electronEffSFIDLooseFile}; - std::vector<std::string> inTriggerSFLoose {m_electronEffSFTriggerLooseFile}; - std::vector<std::string> inTriggerLoose {m_electronEffTriggerLooseFile}; - std::vector<std::string> inChargeID {m_electronEffSFChargeIDFile}; - - /********************************************************************** - * Electron Isolation - * Some WPs aren't supported at the moment... - * As people want to use e.g. LooseLH electrons, we will allow - * everything to procede without the isolation SFs, although they - * should be careful and have to set ElectronIsoSFs False in their config - **********************************************************************/ - std::vector< std::string > inIso; - std::vector< std::string > inIsoLoose; - - if (m_config->electronIsolation() != "None") { - if (m_electronEffSFIsoFile.empty()) { - ATH_MSG_WARNING("Electron isolation configuration not found"); - if (m_config->electronIsoSFs()) { - ATH_MSG_WARNING("If you really want to run with this electron " - "ID/Isolation setup then you can add:" - "\tElectronIsoSFs False\tto your config file"); - return StatusCode::FAILURE; + // https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/IsolationSF2016Moriond#Radiative_Z_low_ET + // To retrieve Isolation Eff scale factors + // N.B. Naming for isolation working points for AsgPhotonEfficiencyCorrectionTool isolation scale factors + // are different than those for the IsolationCorrectionTool (preceded by FixedCut) + std::set<std::string> photon_isolations = { + "Tight", + "Loose", + "TightCaloOnly" + }; + for (const std::string& isoWP : photon_isolations) { + std::string photonIsoSFName = "AsgPhotonEfficiencyCorrectionTool_IsoSF" + isoWP; + if (!asg::ToolStore::contains<IPhotonEffTool>(photonIsoSFName)) { + if (m_config->isMC()) { + IPhotonEffTool* photonIsoSFTool = new AsgPhotonEfficiencyCorrectionTool(photonIsoSFName); + top::check(asg::setProperty(photonIsoSFTool, "ForceDataType", data_type), + "Failed to set ForceDataType for " + photonIsoSFName); + top::check(asg::setProperty(photonIsoSFTool, "IsoKey", isoWP), + "Failed to set IsoKey for " + photonIsoSFName); + top::check(photonIsoSFTool->initialize(), + "Failed to initialize " + photonIsoSFName); + m_photonIsoSFTools.push_back(photonIsoSFTool); + } } - ATH_MSG_INFO("Isolation SFs will be set to 1.0"); - } else { - inIso.push_back( m_electronEffSFIsoFile ); } + return StatusCode::SUCCESS; } - if (m_config->electronIsolationLoose() != "None") { - if (m_electronEffSFIsoLooseFile.empty()) { - ATH_MSG_WARNING("Loose Electron isolation configuration not found"); - if (m_config->electronIsoSFs()) { - ATH_MSG_WARNING("If you really want to run with this (loose) " - "electron ID/Isolation setup then you can add:" - "\tElectronIsoSFs False\tto your config file"); - return StatusCode::FAILURE; + + StatusCode EgammaCPTools::setupScaleFactors() { + // Don't need for data, return SUCCESS straight away + if (!m_config->isMC()) return StatusCode::SUCCESS; + + ///-- Scale factors --/// + std::string electron_data_dir = "ElectronEfficiencyCorrection/"; + + // Define the data type variable - 0 : Data, 1 : MC FullSim, 3 : MC AFII + int dataType(0); + if (m_config->isMC()) { + dataType = (m_config->isAFII()) ? 3 : 1; + } + + ///-- Reco SFs doesn't depend on WP --/// + std::string electronID = m_config->electronID(); + if (electronID.find("LH") != std::string::npos) electronID.replace(electronID.find("LH"), 2, "LLH"); // that way + // people do + // not have to + // change their + // cuts file + std::string electronIDLoose = m_config->electronIDLoose(); + if (electronIDLoose.find("LH") != std::string::npos) electronIDLoose.replace(electronIDLoose.find("LH"), 2, "LLH"); // that + // way + // people + // do + // not + // have + // to + // change + // their + // cuts + // file + std::string electronIsolation = mapWorkingPoints(m_config->electronIsolationSF()); // temporary fix: we can + // hopefully remove the map soon! + std::string electronIsolationLoose = mapWorkingPoints(m_config->electronIsolationSFLoose()); + + // Retrieve full path to maps for different types of tool + m_electronEffSFRecoFile = electronSFMapFilePath("reco"); + // - Tight + m_electronEffSFIDFile = electronSFMapFilePath("ID"); + m_electronEffSFTriggerFile = electronSFMapFilePath("trigger"); + m_electronEffTriggerFile = electronSFMapFilePath("trigger"); + std::vector<std::string> inPLViso; + if (electronIsolation == "PLVTight" || + electronIsolation == "PLVLoose") { + m_electronEffSFIsoFile = electronSFFilePath("PLV", electronID, electronIsolation); + inPLViso.push_back(m_electronEffSFIsoFile); + } + else { + m_electronEffSFIsoFile = electronSFMapFilePath("isolation"); + } + // - Loose + m_electronEffSFIDLooseFile = electronSFMapFilePath("ID"); + m_electronEffSFTriggerLooseFile = electronSFMapFilePath("trigger"); + m_electronEffTriggerLooseFile = electronSFMapFilePath("trigger"); + std::vector<std::string> inPLVisoLoose; + if (electronIsolationLoose == "PLVTight" || + electronIsolationLoose == "PLVLoose") { + m_electronEffSFIsoLooseFile = electronSFFilePath("PLV", electronID, electronIsolationLoose); + inPLVisoLoose.push_back(m_electronEffSFIsoLooseFile); + } + else { + m_electronEffSFIsoLooseFile = electronSFMapFilePath("isolation"); + } + + // Define the trigger string for scale factors + const std::string trigger_string = "SINGLE_E_2015_e24_lhmedium_L1EM20VH_" + "OR_e60_lhmedium_" + "OR_e120_lhloose_" + "2016_2018_e26_lhtight_nod0_ivarloose_" + "OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"; + + + + // Define the tool prefix name + const std::string elSFPrefix = "AsgElectronEfficiencyCorrectionTool_"; + + ATH_MSG_INFO("Setting up Electrons SF tool for TOTAL correlation model"); + // Configure the tools with the maps - Name, map, reco_key, ID_key, iso_key, trigger_key, data_type, for the TOTAL + // correlation model + // Reco SFs + m_electronEffSFReco = setupElectronSFToolWithMap(elSFPrefix + "Reco", m_electronEffSFRecoFile, "Reconstruction", "", + "", "", dataType, "TOTAL", "", ""); + // ID SFs + m_electronEffSFID = setupElectronSFToolWithMap(elSFPrefix + "ID", m_electronEffSFIDFile, "", electronID, "", "", + dataType, "TOTAL", "", ""); + m_electronEffSFIDLoose = setupElectronSFToolWithMap(elSFPrefix + "IDLoose", m_electronEffSFIDLooseFile, "", + electronIDLoose, "", "", dataType, "TOTAL", "", ""); + // Trigger SFs + m_electronEffSFTrigger = setupElectronSFToolWithMap(elSFPrefix + "TriggerSF", m_electronEffSFTriggerFile, "", + electronID, electronIsolation, trigger_string, dataType, + "TOTAL", "", ""); + m_electronEffSFTriggerLoose = setupElectronSFToolWithMap(elSFPrefix + "TriggerSFLoose", + m_electronEffSFTriggerLooseFile, "", electronIDLoose, + electronIsolationLoose, trigger_string, dataType, "TOTAL", + "", ""); + // Trigger Efficiencies + m_electronEffTrigger = setupElectronSFToolWithMap(elSFPrefix + "Trigger", m_electronEffTriggerFile, "", electronID, + electronIsolation, "Eff_" + trigger_string, dataType, "TOTAL", "", + ""); + m_electronEffTriggerLoose = setupElectronSFToolWithMap(elSFPrefix + "TriggerLoose", m_electronEffTriggerLooseFile, + "", electronIDLoose, electronIsolationLoose, + "Eff_" + trigger_string, dataType, "TOTAL", "", ""); + // Isolation SFs + if (electronIsolation == "PLVTight" || + electronIsolation == "PLVLoose") { + m_electronEffSFIso = setupElectronSFTool(elSFPrefix + "Iso", inPLViso, dataType); + } + else { + m_electronEffSFIso = setupElectronSFToolWithMap(elSFPrefix + "Iso", m_electronEffSFIsoFile, "", electronID, + electronIsolation, "", dataType, "TOTAL", "", ""); + } + if (electronIsolationLoose == "PLVTight" || + electronIsolationLoose == "PLVLoose") { + m_electronEffSFIsoLoose = setupElectronSFTool(elSFPrefix + "IsoLoose", inPLVisoLoose, dataType); + } + else { + m_electronEffSFIsoLoose = setupElectronSFToolWithMap(elSFPrefix + "IsoLoose", m_electronEffSFIsoLooseFile, "", + electronIDLoose, electronIsolationLoose, "", dataType, "TOTAL", "", + ""); + } + + ATH_MSG_INFO( + "Requested Electrons SF tool for " << m_config->electronEfficiencySystematicModel() << " correlation model"); + + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + ATH_MSG_INFO( + "Setting up Electrons SF tool for " << m_config->electronEfficiencySystematicModel() << " correlation model"); + const std::string elSFPrefixCorrModel = elSFPrefix + "CorrModel_"; + // Reco SFs + m_electronEffSFRecoCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "Reco", m_electronEffSFRecoFile, + "Reconstruction", "", "", "", dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + // ID SFs + m_electronEffSFIDCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "ID", m_electronEffSFIDFile, "", + electronID, "", "", dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + m_electronEffSFIDLooseCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "IDLoose", + m_electronEffSFIDLooseFile, "", electronIDLoose, "", + "", dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + // Trigger SFs + m_electronEffSFTriggerCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "TriggerSF", + m_electronEffSFTriggerFile, "", electronID, + electronIsolation, trigger_string, dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + m_electronEffSFTriggerLooseCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "TriggerSFLoose", + m_electronEffSFTriggerLooseFile, "", + electronIDLoose, electronIsolationLoose, + trigger_string, dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + // Trigger Efficiencies + m_electronEffTriggerCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "Trigger", + m_electronEffTriggerFile, "", electronID, + electronIsolation, "Eff_" + trigger_string, dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + m_electronEffTriggerLooseCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "TriggerLoose", + m_electronEffTriggerLooseFile, "", + electronIDLoose, electronIsolationLoose, + "Eff_" + trigger_string, dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + // Isolation SFs + if (electronIsolation == "PLVTight" || + electronIsolation == "PLVLoose") { + m_electronEffSFIsoCorrModel = setupElectronSFTool(elSFPrefixCorrModel + "Iso", inPLViso, dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + } + else { + m_electronEffSFIsoCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "Iso", m_electronEffSFIsoFile, "", + electronID, electronIsolation, "", dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + } + if (electronIsolationLoose == "PLVTight" || + electronIsolationLoose == "PLVLoose") { + m_electronEffSFIsoLooseCorrModel = setupElectronSFTool(elSFPrefixCorrModel + "IsoLoose", inPLVisoLoose, dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); + + } + else { + m_electronEffSFIsoLooseCorrModel = setupElectronSFToolWithMap(elSFPrefixCorrModel + "IsoLoose", + m_electronEffSFIsoLooseFile, "", electronIDLoose, + electronIsolationLoose, "", dataType, + m_config->electronEfficiencySystematicModel(), + m_config->electronEfficiencySystematicModelEtaBinning(), + m_config->electronEfficiencySystematicModelEtBinning()); } - ATH_MSG_INFO("Loose Isolation SFs will be set to 1.0"); - } else { - inIsoLoose.push_back( m_electronEffSFIsoLooseFile ); } - } - // data type - // 0 : Data - // 1 : MC FullSim - // 3 : MC AFII - int dataType(0); - if (m_config->isMC()) { - dataType = (m_config->isAFII()) ? 3 : 1; - } - - const std::string elSFPrefix = "AsgElectronEfficiencyCorrectionTool_"; - - // Reco SFs - m_electronEffSFReco = setupElectronSFTool(elSFPrefix + "Reco", inRecoSF, dataType); - // Trigger SFs - m_electronEffSFTrigger = setupElectronSFTool(elSFPrefix + "TriggerSF", inTriggerSF, dataType); - m_electronEffSFTriggerLoose = setupElectronSFTool(elSFPrefix + "TriggerSFLoose", inTriggerSFLoose, dataType); - // Trigger Efficiencies (wow- this is bad naming!) - m_electronEffTrigger = setupElectronSFTool(elSFPrefix + "Trigger", inTrigger, dataType); - m_electronEffTriggerLoose = setupElectronSFTool(elSFPrefix + "TriggerLoose", inTriggerLoose, dataType); - // ID SFs - m_electronEffSFID = setupElectronSFTool(elSFPrefix + "ID", inIDSF, dataType); - m_electronEffSFIDLoose = setupElectronSFTool(elSFPrefix + "IDLoose", inIDSFLoose, dataType); - // Isolation SFs - m_electronEffSFIso = setupElectronSFTool(elSFPrefix + "Iso", inIso, dataType); - m_electronEffSFIsoLoose = setupElectronSFTool(elSFPrefix + "IsoLoose", inIsoLoose, dataType); - - // ChargeID SFs (if using Electron Charge ID Selector Tool) - // for the moment only for MediumLH and FixedCutTight isolation - // either at Tight or Loose level - if ( ( electronIDLoose == "MediumLLH" && m_config->electronIsolationLoose() == "FixedCutTight" ) - || ( electronID == "MediumLLH" && m_config->electronIsolation() == "FixedCutTight" ) ) { - // Charge Id efficiency scale factor - m_electronEffSFChargeID = setupElectronSFTool(elSFPrefix + "ChargeID", inChargeID, dataType); + if (m_config->useFwdElectrons()) { + ATH_MSG_INFO("Setting up forward Electrons SF tool"); + +// m_fwdElectronEffSFIDFile = electronSFMapFilePath("FWDID"); +// m_fwdElectronEffSFIDLooseFile = electronSFMapFilePath("FWDID"); +// m_fwdElectronEffSFID = setupElectronSFToolWithMap("AsgFwdElectronEfficiencyCorrectionTool_ID", +// m_fwdElectronEffSFIDFile, "", +// "Fwd" + m_config->fwdElectronID(), "", "", dataType, "TOTAL", "", +// ""); +// m_fwdElectronEffSFIDLoose = setupElectronSFToolWithMap("AsgFwdElectronEfficiencyCorrectionTool_IDLoose", +// m_fwdElectronEffSFIDLooseFile, "", +// "Fwd" + m_config->fwdElectronIDLoose(), "", "", dataType, "TOTAL", "", +// ""); + + ATH_MSG_INFO("Finished setting up forward Electrons SF tool"); + } + + // Charge ID cannot use maps at the moment so we default to the old method + if (m_config->useElectronChargeIDSelection() + && electronIsolation != "PLVTight" + && electronIsolation != "PLVLoose" + && electronIsolationLoose != "PLVTight" + && electronIsolationLoose != "PLVLoose" ) { // We need to update the implementation according to new + // recommendations + ATH_MSG_INFO("Setting up Electrons ChargeID SF tool"); + // Charge ID file (no maps) + m_electronEffSFChargeIDFile = electronSFFilePath("ChargeID", electronID, electronIsolation); + if (m_config->applyTightSFsInLooseTree()) // prevent crash on-supported loose electron WPs with ECIDS + m_electronEffSFChargeIDLooseFile = electronSFFilePath("ChargeID", electronID, electronIsolation); + else m_electronEffSFChargeIDLooseFile = electronSFFilePath("ChargeID", electronIDLoose, electronIsolationLoose); + // The tools want the files in vectors: remove this with function + std::vector<std::string> inChargeID { + m_electronEffSFChargeIDFile + }; + std::vector<std::string> inChargeIDLoose { + m_electronEffSFChargeIDLooseFile + }; + // Charge Id efficiency scale factor + m_electronEffSFChargeID = setupElectronSFTool(elSFPrefix + "ChargeID", inChargeID, dataType); + m_electronEffSFChargeIDLoose = setupElectronSFTool(elSFPrefix + "ChargeIDLoose", inChargeIDLoose, dataType); + } // Charge flip correction: https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EgammaChargeMisIdentificationTool - CP::ElectronChargeEfficiencyCorrectionTool* ChargeMisIDCorrections = new CP::ElectronChargeEfficiencyCorrectionTool("ElectronChargeEfficiencyCorrection"); - //top::check( ChargeMisIDCorrections->setProperty("OutputLevel", MSG::VERBOSE ) , "Failed to setProperty" ); - top::check( ChargeMisIDCorrections->setProperty("CorrectionFileName", "ElectronEfficiencyCorrection/2015_2016/rel20.7/Moriond_February2017_v1/charge_misID/ChargeCorrectionSF.Medium_FixedCutTightIso_CFTMedium.root") , "Failed to setProperty" ); - top::check( ChargeMisIDCorrections->initialize() , "Failed to setProperty" ); + CP::ElectronChargeEfficiencyCorrectionTool* ChargeMisIDCorrections = new CP::ElectronChargeEfficiencyCorrectionTool( + "ElectronChargeEfficiencyCorrection"); + CP::ElectronChargeEfficiencyCorrectionTool* ChargeMisIDCorrectionsLoose = + new CP::ElectronChargeEfficiencyCorrectionTool("ElectronChargeEfficiencyCorrectionLoose"); + m_electronEffSFChargeMisIDFile = electronSFFilePath("ChargeMisID", electronID, electronIsolation); + m_electronEffSFChargeMisIDLooseFile = electronSFFilePath("ChargeMisID", electronIDLoose, electronIsolationLoose); + top::check(ChargeMisIDCorrections->setProperty("CorrectionFileName", + m_electronEffSFChargeMisIDFile), "Failed to setProperty"); + top::check(ChargeMisIDCorrections->initialize(), "Failed to setProperty"); + top::check(ChargeMisIDCorrectionsLoose->setProperty("CorrectionFileName", + m_electronEffSFChargeMisIDLooseFile), "Failed to setProperty"); + top::check(ChargeMisIDCorrectionsLoose->initialize(), "Failed to setProperty"); + + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} + IAsgElectronEfficiencyCorrectionTool* + EgammaCPTools::setupElectronSFTool(const std::string& name, const std::vector<std::string>& file_list, + const int& data_type, + const std::string& correlation_model, + const std::string& correlationModelEtaBinning, + const std::string& correlationModelEtBinning) { + IAsgElectronEfficiencyCorrectionTool* tool = nullptr; + + if (asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool>(name)) { + tool = asg::ToolStore::get<IAsgElectronEfficiencyCorrectionTool>(name); + } else { + if (!file_list.empty()) { // If the file list is empty do nothing + tool = new AsgElectronEfficiencyCorrectionTool(name); + top::check(asg::setProperty(tool, "CorrectionFileNameList", file_list), + "Failed to set CorrectionFileNameList to " + name); + top::check(asg::setProperty(tool, "ForceDataType", data_type), + "Failed to set ForceDataType to " + name); + top::check(asg::setProperty(tool, "CorrelationModel", correlation_model), + "Failed to set CorrelationModel to " + name); + if (correlationModelEtaBinning != "" && correlationModelEtaBinning != "default") this->setCorrelationModelBinning(tool, "UncorrEtaBinsUser", correlationModelEtaBinning); + if (correlationModelEtBinning != "" && correlationModelEtBinning != "default") this->setCorrelationModelBinning(tool, "UncorrEtBinsUser", correlationModelEtBinning); + top::check(tool->initialize(), "Failed to initialize " + name); + } + } + return tool; + } + + void EgammaCPTools::setCorrelationModelBinning(IAsgElectronEfficiencyCorrectionTool* tool, + const std::string& binningName, const std::string& binning) { + std::vector<std::string> tokens; + top::tokenize(binning, tokens, ":"); + if (tokens.size() < 1) { + ATH_MSG_ERROR( + "EgammaCPTools::setupElectronSFToolWithMap, correlation model " << binningName << + " binning must be in the form XXX:YYY:WWW:ZZZ..."); + } + std::vector<float> bins; + for (unsigned int i = 0; i < tokens.size(); i++) { + std::string token = tokens[i]; + float value = 0.; + try{ + value = std::stof(token); + } + catch (...) { + throw std::invalid_argument { + "EgammaCPTools::setupElectronSFToolWithMap, correlation model " + binningName + + " binning must be in the for XXX:YYY:WWW:ZZZ, couldn't convert correctly to float" + }; + } + bins.push_back(value); + } + ATH_MSG_INFO(" ---> electron SF tools will use " << binningName << " bins:"); + for (unsigned int i = 0; i < bins.size(); i++) ATH_MSG_INFO(" " << bins[i]); + top::check(asg::setProperty(tool, binningName, + bins), "Failed to set correlation model " + binningName + " binning to " + binning); + } -IAsgElectronEfficiencyCorrectionTool* -EgammaCPTools::setupElectronSFTool(const std::string& name, const std::vector<std::string>& file_list, int data_type) { - IAsgElectronEfficiencyCorrectionTool* tool = nullptr; - if (asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool>(name)) { - tool = asg::ToolStore::get<IAsgElectronEfficiencyCorrectionTool>(name); - } else { - if (!file_list.empty()) { // If the file list is empty do nothing + IAsgElectronEfficiencyCorrectionTool* + EgammaCPTools::setupElectronSFToolWithMap(const std::string& name, const std::string& map_path, + const std::string& reco_key, const std::string& ID_key, + const std::string& ISO_key, const std::string& trigger_key, + const int& data_type, const std::string& correlation_model, + const std::string& correlationModelEtaBinning, + const std::string& correlationModelEtBinning) { + std::string iso_key = ISO_key; + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/LatestRecommendationsElectronIDRun2#PLV_scale_factors_for_central_el + // If isolation WP is PLVTight or PLVLoose, switch to no isolation to trick this function. + if (iso_key == "PLVTight" || iso_key == "PLVLoose") iso_key = ""; + + std::string infoStr = "Configuring : name=" + name + " map=" + map_path + " reco_key=" + reco_key + " ID_key=" + + ID_key + " iso_key=" + iso_key + " trigger_key=" + trigger_key + "data_type=" + + std::to_string(data_type) + + " correlation_model=" + correlation_model + " etaBinning=" + correlationModelEtaBinning + + " etBinning=" + + correlationModelEtBinning; + ATH_MSG_INFO(infoStr); + IAsgElectronEfficiencyCorrectionTool* tool = nullptr; + if (asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool>(name)) { + tool = asg::ToolStore::get<IAsgElectronEfficiencyCorrectionTool>(name); + } else { tool = new AsgElectronEfficiencyCorrectionTool(name); - top::check(asg::setProperty(tool, "CorrectionFileNameList", file_list), - "Failed to set CorrectionFileNameList to " + name); - top::check(asg::setProperty(tool, "ForceDataType", data_type), - "Failed to set ForceDataType to " + name); - top::check(asg::setProperty(tool, "CorrelationModel", "TOTAL"), - "Failed to set CorrelationModel to " + name); + // Give the full map path + top::check(asg::setProperty(tool, "MapFilePath", map_path), "Failed to set MapFilePath to " + name); + // Set the data type for all tools + top::check(asg::setProperty(tool, "ForceDataType", data_type), "Failed to set ForceDataType to " + name); + // Set the correlation model for all tools + top::check(asg::setProperty(tool, "CorrelationModel", + correlation_model), "Failed to set CorrelationModel to " + name); + + if (correlationModelEtaBinning != "" && correlationModelEtaBinning != "default") this->setCorrelationModelBinning( + tool, "UncorrEtaBinsUser", correlationModelEtaBinning); + if (correlationModelEtBinning != "" && correlationModelEtBinning != "default") this->setCorrelationModelBinning( + tool, "UncorrEtBinsUser", correlationModelEtBinning); + + // Set the keys which configure the tool options (empty string means we do not include this key) + if (reco_key != "" && reco_key != "None") { + ATH_MSG_INFO(" Adding RecoKey : " + reco_key); + top::check(asg::setProperty(tool, "RecoKey", reco_key), "Failed to set RecoKey to " + name); + } + if (ID_key != "" && ID_key != "None") { + std::string id_key = mapWorkingPoints(ID_key); + ATH_MSG_INFO(" Adding IDKey : " + id_key); + top::check(asg::setProperty(tool, "IdKey", id_key), "Failed to set IdKey to " + name); + } + if (iso_key != "" && iso_key != "None") { + ATH_MSG_INFO(" Adding IsoKey : " + iso_key); + top::check(asg::setProperty(tool, "IsoKey", iso_key), "Failed to set IsoKey to " + name); + } + if (trigger_key != "" && trigger_key != "None") { + ATH_MSG_INFO(" Adding TriggerKey : " + trigger_key); + top::check(asg::setProperty(tool, "TriggerKey", trigger_key), "Failed to set TriggerKey to " + name); + } + // Initialise this tool top::check(tool->initialize(), "Failed to initialize " + name); } + return tool; } - return tool; -} - -std::string EgammaCPTools::electronSFFilePath(const std::string& type, const std::string& ID, const std::string& isolation) { - const std::string el_calib_path - = "ElectronEfficiencyCorrection/" - "2015_2016/rel20.7/Moriond_February2017_v1/"; - - const std::string ridiculous_trigger_string - = "SINGLE_E_2015_e24_lhmedium_L1EM20VH_" - "OR_e60_lhmedium_" - "OR_e120_lhloose_" - "2016_e26_lhtight_nod0_ivarloose_" - "OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"; - - std::string new_iso = (isolation == "None") ? "" : "_isol" + isolation; - - std::string file_path; - - if (type == "reco") { - file_path = "offline/efficiencySF.offline.RecoTrk.root"; - } else if (type == "ID") { - file_path = "offline/efficiencySF.offline." + ID + "_d0z0_v11.root"; - } else if (type == "isolation") { - file_path = "isolation/efficiencySF.Isolation." - + ID + "_d0z0_v11" + new_iso + ".root"; - } else if (type == "triggerSF") { - file_path = "trigger/efficiencySF." + ridiculous_trigger_string - + "." + ID + "_d0z0_v11" + new_iso + ".root"; - } else if (type == "triggerEff") { - file_path = "trigger/efficiency." + ridiculous_trigger_string - + "." + ID + "_d0z0_v11" + new_iso + ".root"; - } else if (type == "ChargeID") { - if (ID != "MediumLLH") ATH_MSG_WARNING("Only Medium WP available at the moment " + ID); - file_path = "charge_misID/efficiencySF.ChargeID.MediumLLH_d0z0_v11_isolFixedCutTight_MediumCFT.root"; - } else { - ATH_MSG_ERROR("Unknown electron SF type"); + + std::string EgammaCPTools::electronSFFilePath(const std::string& type, const std::string& ID, + const std::string& ISO) { + const std::string el_calib_path = "ElectronEfficiencyCorrection/2015_2017/rel21.2/Consolidation_September2018_v1/"; + + std::string file_path; + + if (type == "reco") { + ATH_MSG_ERROR("Moved to using egamma maps for configuring scale factor tools - electronSFMapFilePath"); + } else if (type == "ID") { + ATH_MSG_ERROR("Moved to using egamma maps for configuring scale factor tools - electronSFMapFilePath"); + } else if (type == "triggerSF") { + ATH_MSG_ERROR("Moved to using egamma maps for configuring scale factor tools - electronSFMapFilePath"); + } else if (type == "triggerEff") { + ATH_MSG_ERROR("Moved to using egamma maps for configuring scale factor tools - electronSFMapFilePath"); + } else if (type == "ChargeID") { + if (ID != "MediumLLH" && ID != "TightLLH") ATH_MSG_ERROR( + "The requested ID WP (" + ID + + ") is not supported for electron ChargeID SFs! Try TightLH or MediumLH instead."); + if (ISO != "FCTight" && ISO != "Gradient") ATH_MSG_ERROR("The requested ISO WP (" + ISO + ") is not supported for electron ChargeID SFs! Try FCTight or Gradient instead."); + file_path += "additional/efficiencySF.ChargeID."; + file_path += ID; + file_path += "_d0z0_v13_"; + file_path += ISO; + file_path += "_ECIDSloose.root"; + file_path = el_calib_path + file_path; + } else if (type == "PLV") { + if (ID != "MediumLLH" && ID != "TightLLH") + ATH_MSG_ERROR( + "The requested ID WP (" + ID + + ") is not supported for PLV SFs! try TightLH or MediumLH instead." + ); + file_path = "/ElectronEfficiencyCorrection/2015_2018/rel21.2/Precision_Summer2020_v1/isolation/"; + file_path += "efficiencySF.Isolation.MediumLHorTightLH_d0z0_v13_isol"; + file_path += ISO; + if (ISO == "PLVTight" && m_config->useElectronChargeIDSelection()) { + ATH_MSG_INFO( + "ECIDS tool and PLVTight isolation detected, switching to combined isolation SFs." + ); + file_path += "ECIDS"; + } + file_path += ".root"; + } else if (type == "ChargeMisID") { + // Protect against "None" Iso key + std::string iso = ISO; + if (iso == "None") iso = ""; + // Protect against Loose ID + any Iso + if (ID == "LooseAndBLayerLLH") iso = ""; + file_path = "charge_misID/"; + file_path += "chargeEfficiencySF."; + file_path += ID; + file_path += "_d0z0_v13"; + if (iso != "" && iso != "PLVTight" && iso != "PLVLoose") file_path += "_" + iso; + if (m_config->useElectronChargeIDSelection()) { + if (ID != "MediumLLH" && ID != "TightLLH") ATH_MSG_WARNING("The requested ID WP (" + ID + ") is not supported for electron ECIDS+ChargeMisID SFs! Try TightLH or MediumLH instead. Will now switch to regular ChargeMisID SFs."); + else if (iso != "FCTight" && iso != "Gradient") ATH_MSG_WARNING("The requested ISO WP (" + iso + ") is not supported for electron ECIDS+ChargeMisID SFs! Try FCTight or Gradient instead. Will now switch to regular ChargeMisID SFs."); + else file_path += "_ECIDSloose"; + } + file_path += ".root"; + file_path = el_calib_path + file_path; + } else { + ATH_MSG_ERROR("Unknown electron SF type"); + } + return PathResolverFindCalibFile(file_path); + } + + std::string EgammaCPTools::electronSFMapFilePath(const std::string& type) { + // Store here the paths to maps which may be updated with new recommendations + // Currently can use maps for reco, id, iso, trigger but not ChargeID + const std::string el_calib_path = "ElectronEfficiencyCorrection/2015_2017/rel21.2/Consolidation_September2018_v1/"; + + std::string file_path; + if (type == "reco") { + file_path = "map3.txt"; + } else if (type == "ID") { + file_path = "map3.txt"; + } else if (type == "FWDID") { + file_path = "map3.txt"; + } else if (type == "isolation") { + file_path = "map3.txt"; + } else if (type == "trigger") { + file_path = "map3.txt"; + } else if (type == "ChargeID") { + ATH_MSG_ERROR("Use electronSFFilePath method until ChargeID is supported by maps"); + } else if (type == "ChargeMisID") { + ATH_MSG_ERROR("Use electronSFFilePath method until ChargeMisID is supported by maps"); + } else { + ATH_MSG_ERROR("Unknown electron SF type"); + } + return PathResolverFindCalibFile(el_calib_path + file_path); } - return PathResolverFindCalibFile(el_calib_path + file_path); -} + std::string EgammaCPTools::mapWorkingPoints(const std::string& type) { + // Ian Connelly - 27 Sept 2017 + // When moving to the maps, the working points are converted to a nicer format + // We will provide a mapping from the names used by analysers and the map WP names to prevent cutfiles breaking + // See : + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/XAODElectronEfficiencyCorrectionTool#Configuration_of_the_tool_using + std::string working_point = ""; + // ID + if (type == "LooseAndBLayerLLH" || type == "LooseBLayer") { + working_point = "LooseBLayer"; + } + if (type == "MediumLLH" || type == "Medium") { + working_point = "Medium"; + } + if (type == "TightLLH" || type == "Tight") { + working_point = "Tight"; + } + if (type == "FwdLoose" || type == "FwdMedium" || type == "FwdTight") working_point = type; + + // Temporary ISO map to handle the mess that is EGamma+IFF right now... + if (type.find("Pflow") != std::string::npos) { + ATH_MSG_WARNING("You selected a Pflow isolation WP for at least one of your electron collections - BE WARNED THAT THESE ARE NOT YET READY TO BE RELEASED FOR USE IN PHYSICS ANALYSES AND OF COURSE DON'T HAVE ASSOCIATED SCALE FACTORS YET!!!"); + if (type == "PflowLoose") working_point = "FCLoose"; + if (type == "PflowTight") working_point = "FCTight"; + } + if (type == "Tight") working_point = "FCTight"; + if (type == "Loose") working_point = "FCLoose"; + if (type == "HighPtCaloOnly") working_point = "FCHighPtCaloOnly"; + if (type == "TightTrackOnly") working_point = "Gradient"; + if (type == "TightTrackOnly_FixedRad") working_point = "Gradient"; + if (type == "FCTight" || type == "FCLoose" || type == "FCHighPtCaloOnly" || type == "Gradient" || type == "PLVTight" || type == "PLVLoose") working_point = type; + + return working_point; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopFlavorTaggingCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopFlavorTaggingCPTools.cxx index b15c3df0a5f6..407ba89f7bf1 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopFlavorTaggingCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopFlavorTaggingCPTools.cxx @@ -1,14 +1,17 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopFlavorTaggingCPTools.h" #include <map> #include <string> +#include <algorithm> +#include <iterator> // Top includes #include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/Tokenize.h" #include "TopEvent/EventTools.h" // PathResolver include(s): @@ -18,254 +21,411 @@ #include "xAODBTaggingEfficiency/BTaggingSelectionTool.h" namespace top { - -FlavorTaggingCPTools::FlavorTaggingCPTools(const std::string& name) : + FlavorTaggingCPTools::FlavorTaggingCPTools(const std::string& name) : asg::AsgTool(name) { - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); -} - -StatusCode FlavorTaggingCPTools::initialize() { - ATH_MSG_INFO("top::FlavorTaggingCPTools initialize..."); - - if (m_config->isTruthDxAOD()) { - ATH_MSG_INFO("top::FlavorTaggingCPTools: no need to initialise anything on truth DxAOD"); - return StatusCode::SUCCESS; + declareProperty("config", m_config); } - if (!m_config->useJets()) { - ATH_MSG_INFO("top::FlavorTaggingCPTools: no need to initialise anything since not using jets"); - return StatusCode::SUCCESS; - } + StatusCode FlavorTaggingCPTools::initialize() { + ATH_MSG_INFO("top::FlavorTaggingCPTools initialize..."); - m_tagger = "MV2c10"; - m_cdi_file = "xAODBTaggingEfficiency/13TeV/2016-20_7-13TeV-MC15-CDI-2017-04-24_v1.root"; - m_efficiency_maps = "410000;410004;410500;410187;410021"; - - // working points for calo jets - m_calo_WPs_calib = {"FixedCutBEff_60", - "FixedCutBEff_70", - "FixedCutBEff_77", - "FixedCutBEff_85", - "Continuous" }; - m_calo_WPs = m_calo_WPs_calib; - m_calo_WPs.push_back("FlatBEff_30");// some other WPs are defined in addition to the calibrated ones - m_calo_WPs.push_back("FlatBEff_40"); - m_calo_WPs.push_back("FlatBEff_50"); - m_calo_WPs.push_back("FlatBEff_60"); - m_calo_WPs.push_back("FlatBEff_70"); - m_calo_WPs.push_back("FlatBEff_77"); - m_calo_WPs.push_back("FlatBEff_85"); - m_calo_WPs.push_back("FixedCutBEff_30"); - m_calo_WPs.push_back("FixedCutBEff_50"); - m_calo_WPs.push_back("FixedCutBEff_80"); - m_calo_WPs.push_back("FixedCutBEff_90"); - - // working points for track jets (AntiKt2) - m_trackAntiKt2_WPs_calib = {"FixedCutBEff_60", - "FixedCutBEff_70", - "FixedCutBEff_77", - "FixedCutBEff_85", - "Continuous" }; - m_trackAntiKt2_WPs = m_trackAntiKt2_WPs_calib; - m_trackAntiKt2_WPs.push_back("FixedCutBEff_30");// some other WPs are defined in addition to the calibrated ones - m_trackAntiKt2_WPs.push_back("FixedCutBEff_50"); - m_trackAntiKt2_WPs.push_back("FixedCutBEff_80"); - m_trackAntiKt2_WPs.push_back("FixedCutBEff_90"); - - // working points for track jets (AntiKt4) - m_trackAntiKt4_WPs_calib = {"FixedCutBEff_70", - "FixedCutBEff_77" }; - m_trackAntiKt4_WPs = m_trackAntiKt4_WPs_calib; - m_trackAntiKt4_WPs.push_back("FixedCutBEff_60");// some other WPs are defined in addition to the calibrated ones - m_trackAntiKt4_WPs.push_back("FixedCutBEff_85"); - m_trackAntiKt4_WPs.push_back("FixedCutBEff_30"); - m_trackAntiKt4_WPs.push_back("FixedCutBEff_50"); - m_trackAntiKt4_WPs.push_back("FixedCutBEff_80"); - m_trackAntiKt4_WPs.push_back("FixedCutBEff_90"); - - const std::string calib_file_path = PathResolverFindCalibFile(m_cdi_file); - const std::string excludedSysts = m_config->bTagSystsExcludedFromEV()=="none"?"":m_config->bTagSystsExcludedFromEV(); - - //------------------------------------------------------------ - // Loop through all the different working points we have and create a - // BTaggingSelectionTool and corresponding BTaggingEfficiencyTool if the working point is calibrated. - //------------------------------------------------------------ - - // special stuff to use AntiKt4EMTopoJets scale-factors and tagger WPs when using AntiKt4EMPFlowJets or AntiKt4LCTopoJets, for which no SF is yet available - std::string caloJets_collection = m_config->sgKeyJets(); - if (caloJets_collection == "AntiKt4EMPFlowJets" || caloJets_collection == "AntiKt4LCTopoJets" || caloJets_collection == "AntiKt4EMTopoNoElJets") { - ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize" ); - std::cout << " No b-tagging calibration available for jet collection " << caloJets_collection << std::endl; - std::cout << " We'll use the calibration for AntiKt4EMTopoJets instead" << std::endl; - std::cout << " Be carefull!!" << std::endl; - caloJets_collection = "AntiKt4EMTopoJets"; - } - // check if the WP requested by the user are available, and if yes, initialize the tools - // loop through all btagging WPs requested - for (auto btagWP : m_config->bTagWP()) { - if(std::find(m_calo_WPs.begin(), m_calo_WPs.end(), btagWP) == m_calo_WPs.end()) { - ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize" ); - std::cerr << " b-tagging WP: " << btagWP << " not supported for jet collection " << m_config->sgKeyJets() << std::endl; - std::cerr << " it will therefore be ignored" << std::endl; + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::FlavorTaggingCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; } - else { - //------------------------------------------------------------ - // Setup BTaggingSelectionTool - //------------------------------------------------------------ - std::string btagsel_tool_name = "BTaggingSelectionTool_"+btagWP+"_"+m_config->sgKeyJets(); - BTaggingSelectionTool* btagsel = new BTaggingSelectionTool(btagsel_tool_name); - top::check(btagsel->setProperty("TaggerName", m_tagger), - "Failed to set b-tagging selecton tool TaggerName"); - top::check(btagsel->setProperty("JetAuthor", caloJets_collection), - "Failed to set b-tagging selection JetAuthor"); - top::check(btagsel->setProperty("FlvTagCutDefinitionsFileName", - m_cdi_file), - "Failed to set b-tagging selection tool CDI file"); - top::check(btagsel->setProperty("OperatingPoint", btagWP), - "Failed to set b-tagging selection tool OperatingPoint"); - top::check(btagsel->setProperty("MinPt", - static_cast<double>(m_config->jetPtcut())), - "Failed to set b-tagging selection tool MinPt"); - top::check(btagsel->setProperty("MaxEta", - static_cast<double>(m_config->jetEtacut())), - "Failed to set b-tagging selection tool MaxEta"); - top::check(btagsel->initialize(), - "Failed to initialize b-tagging selection tool"); - m_btagging_selection_tools.push_back(btagsel); - - if(std::find( m_calo_WPs_calib.begin(), - m_calo_WPs_calib.end(), btagWP) == m_calo_WPs_calib.end()) { - ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize" ); - std::cerr << " b-tagging WP: " << btagWP << " is not calibrated for jet collection " << m_config->sgKeyJets() << std::endl; - std::cerr << " it will therefore be ignored for the scale-factors, although the tagging decisions will be saved" << std::endl; - } - else { - //------------------------------------------------------------ - // Setup BTaggingEfficiencyTool - //------------------------------------------------------------ - std::string btageff_tool_name = "BTaggingEfficiencyTool_"+btagWP+"_"+m_config->sgKeyJets(); - BTaggingEfficiencyTool* btageff = new BTaggingEfficiencyTool(btageff_tool_name); - top::check(btageff->setProperty("TaggerName", m_tagger), - "Failed to set b-tagging TaggerName"); - top::check(btageff->setProperty("OperatingPoint", btagWP), - "Failed to set b-tagging OperatingPoint"); - top::check(btageff->setProperty("JetAuthor", caloJets_collection), - "Failed to set b-tagging JetAuthor"); - top::check(btageff->setProperty("EfficiencyFileName", calib_file_path), - "Failed to set path to b-tagging CDI file"); - top::check(btageff->setProperty("ScaleFactorFileName", calib_file_path), - "Failed to set path to b-tagging CDI file"); - top::check(btageff->setProperty("ScaleFactorBCalibration", m_config->bTaggingCalibration_B()), - "Failed to set b-tagging calibration (B): "+m_config->bTaggingCalibration_B()); - top::check(btageff->setProperty("ScaleFactorCCalibration", m_config->bTaggingCalibration_C()), - "Failed to set b-tagging calibration (C): "+m_config->bTaggingCalibration_C()); - // using same calibration for T as for C - top::check(btageff->setProperty("ScaleFactorTCalibration", m_config->bTaggingCalibration_C()), - "Failed to set b-tagging calibration (T): "+m_config->bTaggingCalibration_C()); - top::check(btageff->setProperty("ScaleFactorLightCalibration", m_config->bTaggingCalibration_Light()), - "Failed to set b-tagging calibration (Light): "+m_config->bTaggingCalibration_Light()); - for (auto jet_flav : m_jet_flavors) { - top::check(btageff->setProperty("Efficiency"+jet_flav+"Calibrations", m_efficiency_maps), - "Failed to set "+jet_flav+"-calibrations efficiency maps"); - } - top::check(btageff->setProperty("ExcludeFromEigenVectorTreatment", excludedSysts), - "Failed to set b-tagging systematics to exclude from EV treatment"); - top::check(btageff->initialize(), "Failed to initialize "+btagWP); - m_btagging_efficiency_tools.push_back(btageff); - m_config->setBTagWP_calibrated(btagWP); - } - m_config->setBTagWP_available(btagWP); + + if (!m_config->useJets()) { + ATH_MSG_INFO("top::FlavorTaggingCPTools: no need to initialise anything since not using jets"); + return StatusCode::SUCCESS; } - if (m_config->useTrackJets()) { - std::vector<std::string> track_WPs = {}; - std::vector<std::string> track_WPs_calib = {}; - if (m_config->sgKeyTrackJets() == "AntiKt2PV0TrackJets") { - track_WPs = m_trackAntiKt2_WPs; - track_WPs_calib = m_trackAntiKt2_WPs_calib; - } - else if (m_config->sgKeyTrackJets() == "AntiKt4PV0TrackJets") { - track_WPs = m_trackAntiKt4_WPs; - track_WPs_calib = m_trackAntiKt4_WPs_calib; - } - - if(std::find(track_WPs.begin(), track_WPs.end(), btagWP) == track_WPs.end()) { - ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize" ); - std::cerr << " b-tagging WP: " << btagWP << " not supported for jet collection " << m_config->sgKeyTrackJets() << std::endl; - std::cerr << " it will therefore be ignored" << std::endl; + static const std::string cdi_file_default = + "xAODBTaggingEfficiency/13TeV/2020-21-13TeV-MC16-CDI-2020-03-11_Sh228_v3.root"; + + m_tagger = ""; // Extract in the loop + if (m_config->bTaggingCDIPath() != "Default") { + if (m_config->bTaggingCDIPath() != cdi_file_default) { + m_config->setPrintCDIpathWarning(true); } - else { + m_cdi_file = m_config->bTaggingCDIPath(); + } else { + m_cdi_file = cdi_file_default; + } + // This ordering needs to match the indexing in TDP (for missing cases, we use default which gives a MC/MC of 1 as + // its the same as the eff used in the calibration + // Pythia6;Herwigpp;Pythia8;Sherpa(2.2);Sherpa(2.1);aMC@NLO+Pythia8;Herwig7.1.3;Sherpa228 + // Default changed from 410501 to 410470 in the CDI release of October 2018 + m_efficiency_maps = "default;410558;410470;410250;default;410464;411233;421152"; + + // Configure all tagger/WP/calibration with helper function touching member variables + // Calibrated and uncalibrated working points for EMTopo jets for all algorithms + top::check(setTaggerWorkingPoints("AntiKt4EMTopoJets", true, "MV2c10", + {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", + "Continuous"}), + "Error setting AntiKt4EMTopoJets WP"); + top::check(setTaggerWorkingPoints("AntiKt4EMTopoJets", true, "DL1", + {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", + "Continuous"}), "Error setting AntiKt4EMTopoJets WP"); + top::check(setTaggerWorkingPoints("AntiKt4EMTopoJets", false, "DL1r", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt4EMTopoJets WP"); + top::check(setTaggerWorkingPoints("AntiKt4EMTopoJets", false, "DL1rmu", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "CTag_Loose", "CTag_Tight", "Continuous"}), "Error setting AntiKt4EMTopoJets WP"); + top::check(setTaggerWorkingPoints("AntiKt4EMTopoJets", false, "DL1", {"CTag_Loose", "CTag_Tight"}), "Error setting AntiKt4EMTopoJets WP"); + + // Calibrated and uncalibrated working points for EMPflow jets for all algorithms + top::check(setTaggerWorkingPoints("AntiKt4EMPFlowJets", false, "MV2c10", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt4EMPFlowJets WP"); + top::check(setTaggerWorkingPoints("AntiKt4EMPFlowJets", true, "DL1", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt4EMPFlowJets WP"); + top::check(setTaggerWorkingPoints("AntiKt4EMPFlowJets", true, "DL1r", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt4EMPFlowJets WP"); + top::check(setTaggerWorkingPoints("AntiKt4EMPFlowJets", false, "DL1rmu", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt4EMPFlowJets WP"); + + // Calibrated and uncalibrated working points for R=0.2 track jets for all algorithms + top::check(setTaggerWorkingPoints("AntiKt2PV0TrackJets", true, "MV2c10", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt2PV0TrackJets WP"); + top::check(setTaggerWorkingPoints("AntiKt2PV0TrackJets", true, "DL1", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt2PV0TrackJets WP"); + top::check(setTaggerWorkingPoints("AntiKt2PV0TrackJets", false, "DL1r", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt2PV0TrackJets WP"); + top::check(setTaggerWorkingPoints("AntiKt2PV0TrackJets", false, "DL1rmu", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKt2PV0TrackJets WP"); + + // Calibrated and uncalibrated working points for VR track jets for all algorithms + top::check(setTaggerWorkingPoints("AntiKtVR30Rmax4Rmin02TrackJets", true, "MV2c10", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKtVR30Rmax4Rmin02TrackJets WP"); + top::check(setTaggerWorkingPoints("AntiKtVR30Rmax4Rmin02TrackJets", true, "DL1", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKtVR30Rmax4Rmin02TrackJets WP"); + top::check(setTaggerWorkingPoints("AntiKtVR30Rmax4Rmin02TrackJets", false, "DL1r", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKtVR30Rmax4Rmin02TrackJets WP"); + top::check(setTaggerWorkingPoints("AntiKtVR30Rmax4Rmin02TrackJets", false, "DL1rmu", {"FixedCutBEff_60", "FixedCutBEff_70", "FixedCutBEff_77", "FixedCutBEff_85", "Continuous"}), "Error setting AntiKtVR30Rmax4Rmin02TrackJets WP"); + + + std::string caloJets_type = m_config->sgKeyJetsType(); + std::string caloJets_collection = m_config->sgKeyJets(); + + std::string trackJets_type = m_config->sgKeyTrackJetsType(); + std::string trackJets_collection = m_config->sgKeyTrackJets(); + + const std::string calib_file_path = PathResolverFindCalibFile(m_cdi_file); + const std::string excludedSysts = m_config->bTagSystsExcludedFromEV() == "none" ? "" : m_config->bTagSystsExcludedFromEV(); + + //------------------------------------------------------------ + // Loop through all the different working points we have and create a + // BTaggingSelectionTool and corresponding BTaggingEfficiencyTool if the working point is calibrated. + //------------------------------------------------------------ + + // check if the WP requested by the user are available, and if yes, initialize the tools + // loop through all btagging WPs requested + for (auto TaggerBtagWP : m_config->bTagWP()) { + // Overwrite m_tagger anyway (default has to be mv2c10 for R20.7 + m_tagger = TaggerBtagWP.first; + std::string btagWP = TaggerBtagWP.second; + std::string bTagWPName = m_tagger + "_" + btagWP; + if ((caloJets_type == "AntiKt4EMTopoJets" && std::find(m_calo_WPs.begin(), m_calo_WPs.end(), bTagWPName) == m_calo_WPs.end()) || + (caloJets_type == "AntiKt4EMPFlowJets" && std::find(m_pflow_WPs.begin(), m_pflow_WPs.end(), bTagWPName) == m_pflow_WPs.end())) { + ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize"); + ATH_MSG_WARNING(" b-tagging WP: " + bTagWPName + " not supported for jet collection " + caloJets_collection + " with algorithm " + m_tagger); + ATH_MSG_WARNING(" it will therefore be ignored"); + } else { //------------------------------------------------------------ // Setup BTaggingSelectionTool //------------------------------------------------------------ - std::string btagsel_tool_name = "BTaggingSelectionTool_"+btagWP+"_"+m_config->sgKeyTrackJets(); + // Updated name to use m_tagger + std::string btagsel_tool_name = "BTaggingSelectionTool_" + bTagWPName + "_" + caloJets_collection; BTaggingSelectionTool* btagsel = new BTaggingSelectionTool(btagsel_tool_name); top::check(btagsel->setProperty("TaggerName", m_tagger), - "Failed to set b-tagging selecton tool TaggerName"); - top::check(btagsel->setProperty("JetAuthor", m_config->sgKeyTrackJets()), - "Failed to set b-tagging selection JetAuthor"); + "Failed to set b-tagging selecton tool TaggerName"); + top::check(btagsel->setProperty("JetAuthor", caloJets_collection), + "Failed to set b-tagging selection JetAuthor"); top::check(btagsel->setProperty("FlvTagCutDefinitionsFileName", m_cdi_file), - "Failed to set b-tagging selection tool CDI file"); + "Failed to set b-tagging selection tool CDI file"); top::check(btagsel->setProperty("OperatingPoint", btagWP), - "Failed to set b-tagging selection tool OperatingPoint"); + "Failed to set b-tagging selection tool OperatingPoint"); top::check(btagsel->setProperty("MinPt", static_cast<double>(m_config->jetPtcut())), - "Failed to set b-tagging selection tool MinPt"); + "Failed to set b-tagging selection tool MinPt"); top::check(btagsel->setProperty("MaxEta", static_cast<double>(m_config->jetEtacut())), - "Failed to set b-tagging selection tool MaxEta"); + "Failed to set b-tagging selection tool MaxEta"); top::check(btagsel->initialize(), - "Failed to initialize b-tagging selection tool"); + "Failed to initialize b-tagging selection tool"); m_btagging_selection_tools.push_back(btagsel); - - if(std::find( track_WPs_calib.begin(), - track_WPs_calib.end(), btagWP) == track_WPs_calib.end()) { - ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize" ); - std::cerr << " b-tagging WP: " << btagWP << " is not calibrated for jet collection " << m_config->sgKeyTrackJets() << std::endl; - std::cerr << " it will therefore be ignored for the scale-factors, although the tagging decisions will be saved" << std::endl; - } - else { + m_config->setBTagAlgo_available(m_tagger, btagsel_tool_name); + + if ((caloJets_type == "AntiKt4EMTopoJets" && std::find(m_calo_WPs_calib.begin(), m_calo_WPs_calib.end(), bTagWPName) == m_calo_WPs_calib.end()) || + (caloJets_type == "AntiKt4EMPFlowJets" && std::find(m_pflow_WPs_calib.begin(), m_pflow_WPs_calib.end(), bTagWPName) == m_pflow_WPs_calib.end())) { + ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize"); + ATH_MSG_WARNING(" b-tagging WP: " + bTagWPName + " is not calibrated for jet collection " + caloJets_collection); + ATH_MSG_WARNING(" it will therefore be ignored for the scale-factors, although the tagging decisions will be saved"); + } else { //------------------------------------------------------------ // Setup BTaggingEfficiencyTool //------------------------------------------------------------ - std::string btageff_tool_name = "BTaggingEfficiencyTool_"+btagWP+"_"+m_config->sgKeyTrackJets(); + std::string btageff_tool_name = "BTaggingEfficiencyTool_" + bTagWPName + "_" + caloJets_collection; BTaggingEfficiencyTool* btageff = new BTaggingEfficiencyTool(btageff_tool_name); top::check(btageff->setProperty("TaggerName", m_tagger), - "Failed to set b-tagging TaggerName"); + "Failed to set b-tagging TaggerName"); top::check(btageff->setProperty("OperatingPoint", btagWP), - "Failed to set b-tagging OperatingPoint"); - top::check(btageff->setProperty("JetAuthor", m_config->sgKeyTrackJets()), - "Failed to set b-tagging JetAuthor"); + "Failed to set b-tagging OperatingPoint"); + top::check(btageff->setProperty("JetAuthor", caloJets_collection), + "Failed to set b-tagging JetAuthor"); + top::check(btageff->setProperty("MinPt", + static_cast<double>(m_config->jetPtcut())), + "Failed to set b-tagging selection tool MinPt"); top::check(btageff->setProperty("EfficiencyFileName", calib_file_path), - "Failed to set path to b-tagging CDI file"); + "Failed to set path to b-tagging CDI file"); top::check(btageff->setProperty("ScaleFactorFileName", calib_file_path), - "Failed to set path to b-tagging CDI file"); + "Failed to set path to b-tagging CDI file"); top::check(btageff->setProperty("ScaleFactorBCalibration", m_config->bTaggingCalibration_B()), - "Failed to set b-tagging calibration (B): "+m_config->bTaggingCalibration_B()); + "Failed to set b-tagging calibration (B): " + m_config->bTaggingCalibration_B()); top::check(btageff->setProperty("ScaleFactorCCalibration", m_config->bTaggingCalibration_C()), - "Failed to set b-tagging calibration (C): "+m_config->bTaggingCalibration_C()); + "Failed to set b-tagging calibration (C): " + m_config->bTaggingCalibration_C()); // using same calibration for T as for C top::check(btageff->setProperty("ScaleFactorTCalibration", m_config->bTaggingCalibration_C()), - "Failed to set b-tagging calibration (T): "+m_config->bTaggingCalibration_C()); + "Failed to set b-tagging calibration (T): " + m_config->bTaggingCalibration_C()); top::check(btageff->setProperty("ScaleFactorLightCalibration", m_config->bTaggingCalibration_Light()), - "Failed to set b-tagging calibration (Light): "+m_config->bTaggingCalibration_Light()); + "Failed to set b-tagging calibration (Light): " + m_config->bTaggingCalibration_Light()); for (auto jet_flav : m_jet_flavors) { - top::check(btageff->setProperty("Efficiency"+jet_flav+"Calibrations", m_efficiency_maps), - "Failed to set "+jet_flav+"-calibrations efficiency maps"); + // 09/02/18 IC: The pseudo-continuous does not have MC/MC SF so we need to only apply default for this case + // 08/05/18 Francesco La Ruffa: The pseudo-continuous has now its own MC/MC SFs, no needed to set default + top::check(btageff->setProperty("Efficiency" + jet_flav + "Calibrations", m_efficiency_maps), + "Failed to set " + jet_flav + "-calibrations efficiency maps"); } top::check(btageff->setProperty("ExcludeFromEigenVectorTreatment", excludedSysts), - "Failed to set b-tagging systematics to exclude from EV treatment"); - top::check(btageff->initialize(), "Failed to initialize "+btagWP); + "Failed to set b-tagging systematics to exclude from EV treatment"); + top::check(btageff->initialize(), "Failed to initialize " + bTagWPName); + // Check the excludedSysts - Cannot check before the tool is initialised + top::check(this->checkExcludedSysts(btageff, excludedSysts), + "Incorrect excluded systematics have been provided."); m_btagging_efficiency_tools.push_back(btageff); - m_config->setBTagWP_calibrated_trkJet(btagWP); + m_config->setBTagWP_calibrated(bTagWPName); } - m_config->setBTagWP_available_trkJet(btagWP); + m_config->setBTagWP_available(bTagWPName); } } + if (m_config->useTrackJets()) { + for (auto TaggerBtagWP : m_config->bTagWP_trkJet()) { + m_tagger = TaggerBtagWP.first; + std::string btagWP = TaggerBtagWP.second; + std::string bTagWPName = m_tagger + "_" + btagWP; + std::vector<std::string> track_WPs = {}; + std::vector<std::string> track_WPs_calib = {}; + if (trackJets_type == "AntiKtVR30Rmax4Rmin02TrackJets") { + track_WPs = m_trackAntiKtVR_WPs; + track_WPs_calib = m_trackAntiKtVR_WPs_calib; + } else if (trackJets_type == "AntiKt2PV0TrackJets") { + track_WPs = m_trackAntiKt2_WPs; + track_WPs_calib = m_trackAntiKt2_WPs_calib; + } else if (trackJets_type == "AntiKt4PV0TrackJets") { + track_WPs = m_trackAntiKt4_WPs; + track_WPs_calib = m_trackAntiKt4_WPs_calib; + } + + if (std::find(track_WPs.begin(), track_WPs.end(), bTagWPName) == track_WPs.end()) { + ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize"); + ATH_MSG_WARNING(" b-tagging WP: " + bTagWPName + " not supported for jet collection " + trackJets_collection); + ATH_MSG_WARNING(" it will therefore be ignored"); + } else { + //------------------------------------------------------------ + // Setup BTaggingSelectionTool + //------------------------------------------------------------ + std::string btagsel_tool_name = "BTaggingSelectionTool_" + bTagWPName + "_" + trackJets_collection; + BTaggingSelectionTool* btagsel = new BTaggingSelectionTool(btagsel_tool_name); + top::check(btagsel->setProperty("TaggerName", m_tagger), + "Failed to set b-tagging selecton tool TaggerName"); + top::check(btagsel->setProperty("JetAuthor", trackJets_collection), + "Failed to set b-tagging selection JetAuthor"); + top::check(btagsel->setProperty("FlvTagCutDefinitionsFileName", + m_cdi_file), + "Failed to set b-tagging selection tool CDI file"); + top::check(btagsel->setProperty("OperatingPoint", btagWP), + "Failed to set b-tagging selection tool OperatingPoint"); + top::check(btagsel->setProperty("MinPt", + static_cast<double>(m_config->trackJetPtcut())), + "Failed to set b-tagging selection tool MinPt"); + top::check(btagsel->setProperty("MaxEta", + static_cast<double>(m_config->trackJetEtacut())), + "Failed to set b-tagging selection tool MaxEta"); + top::check(btagsel->initialize(), + "Failed to initialize b-tagging selection tool"); + m_btagging_selection_tools.push_back(btagsel); + m_config->setBTagAlgo_available_trkJet(m_tagger, btagsel_tool_name); + + if (std::find(track_WPs_calib.begin(), + track_WPs_calib.end(), bTagWPName) == track_WPs_calib.end()) { + ATH_MSG_WARNING("top::FlavorTaggingCPTools::initialize"); + ATH_MSG_WARNING(" b-tagging WP: " + bTagWPName + " is not calibrated for jet collection " + trackJets_collection); + ATH_MSG_WARNING(" it will therefore be ignored for the scale-factors, although the tagging decisions will be saved"); + } else { + //------------------------------------------------------------ + // Setup BTaggingEfficiencyTool + //------------------------------------------------------------ + std::string btageff_tool_name = "BTaggingEfficiencyTool_" + bTagWPName + "_" + trackJets_collection; + BTaggingEfficiencyTool* btageff = new BTaggingEfficiencyTool(btageff_tool_name); + top::check(btageff->setProperty("TaggerName", m_tagger), + "Failed to set b-tagging TaggerName"); + top::check(btageff->setProperty("OperatingPoint", btagWP), + "Failed to set b-tagging OperatingPoint"); + top::check(btageff->setProperty("JetAuthor", trackJets_collection), + "Failed to set b-tagging JetAuthor"); + top::check(btageff->setProperty("MinPt", + static_cast<double>(m_config->trackJetPtcut())), + "Failed to set b-tagging selection tool MinPt"); + top::check(btageff->setProperty("EfficiencyFileName", calib_file_path), + "Failed to set path to b-tagging CDI file"); + top::check(btageff->setProperty("ScaleFactorFileName", calib_file_path), + "Failed to set path to b-tagging CDI file"); + top::check(btageff->setProperty("ScaleFactorBCalibration", m_config->bTaggingCalibration_B()), + "Failed to set b-tagging calibration (B): " + m_config->bTaggingCalibration_B()); + top::check(btageff->setProperty("ScaleFactorCCalibration", m_config->bTaggingCalibration_C()), + "Failed to set b-tagging calibration (C): " + m_config->bTaggingCalibration_C()); + // using same calibration for T as for C + top::check(btageff->setProperty("ScaleFactorTCalibration", m_config->bTaggingCalibration_C()), + "Failed to set b-tagging calibration (T): " + m_config->bTaggingCalibration_C()); + top::check(btageff->setProperty("ScaleFactorLightCalibration", m_config->bTaggingCalibration_Light()), + "Failed to set b-tagging calibration (Light): " + m_config->bTaggingCalibration_Light()); + for (auto jet_flav : m_jet_flavors) { + top::check(btageff->setProperty("Efficiency" + jet_flav + "Calibrations", m_efficiency_maps), + "Failed to set " + jet_flav + "-calibrations efficiency maps"); + } + + top::check(btageff->setProperty("ExcludeFromEigenVectorTreatment", excludedSysts), + "Failed to set b-tagging systematics to exclude from EV treatment"); + top::check(btageff->initialize(), "Failed to initialize " + bTagWPName); + // Check the excludedSysts - Cannot check before the tool is initialised + top::check(this->checkExcludedSysts(btageff, excludedSysts), + "Incorrect excluded systematics have been provided."); + m_btagging_efficiency_tools.push_back(btageff); + m_config->setBTagWP_calibrated_trkJet(bTagWPName); + } + m_config->setBTagWP_available_trkJet(bTagWPName); + } + } + } + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} + StatusCode FlavorTaggingCPTools::checkExcludedSysts(BTaggingEfficiencyTool* btageff, std::string excludedSysts) { + // We pass the pointer to the btagging efficiency tool which is being created and also the excludedSysts string + // which will be used + // If the string is empty, then nothing to check + if (excludedSysts == "") return StatusCode::SUCCESS; + + // Split by a semi-colon delimiter and then check the individual syst strings against the list from the CDI + std::vector<std::string> listOfExcludedSysts; + top::tokenize(excludedSysts, listOfExcludedSysts, ";"); + ATH_MSG_INFO(" ------------------------------------------------ "); + ATH_MSG_INFO(" ------------- EXPERIMENTAL FEATURE ------------- "); + ATH_MSG_INFO(" ------ Please provide feedback to TopReco ------ "); + ATH_MSG_INFO(" ------------- EXPERIMENTAL FEATURE ------------- "); + ATH_MSG_INFO(" ------------------------------------------------ "); + ATH_MSG_INFO(" AnalysisTop - Checking excludedSysts for flavour tagging EV"); + ATH_MSG_INFO(" This has been split on the semi-colon delimiter to find..."); + for (auto s : listOfExcludedSysts) ATH_MSG_INFO("... " + s); + // Get the map(string, vector<string>) from the CDI tool + // Don't care about the flavours (this will be handled in the CDI) + std::vector<std::string> listOfScaleFactorSystematics; + for (auto flavour : btageff->listScaleFactorSystematics(false)) { + for (auto sys : flavour.second) { + listOfScaleFactorSystematics.push_back(sys); + } + } + // Make this a unique set and then we need to check that all systematics provided by the user are expected by the + // CDI + std::set<std::string> setOfExcludedSysts, setOfScaleFactorSystematics; + + for (auto sys : listOfExcludedSysts) { + if (setOfExcludedSysts.find(sys) == setOfExcludedSysts.end()) setOfExcludedSysts.insert(sys); + } + + for (auto sys : listOfScaleFactorSystematics) { + if (setOfScaleFactorSystematics.find(sys) == setOfScaleFactorSystematics.end()) setOfScaleFactorSystematics.insert(sys); + } + + // + std::vector<std::string> unionOfSystematics; + std::set_intersection(setOfExcludedSysts.begin(), setOfExcludedSysts.end(), + setOfScaleFactorSystematics.begin(), setOfScaleFactorSystematics.end(), + std::back_inserter(unionOfSystematics)); + // Check we have the same systematics listed in unionOfSystematics + if (unionOfSystematics.size() != listOfExcludedSysts.size()) { + ATH_MSG_WARNING("Have not found all systematics listed to be excluded from b-tagging eigenvector method"); + ATH_MSG_INFO("Permitted values are..."); + for (auto sys : setOfScaleFactorSystematics) { + ATH_MSG_INFO(" ... " + sys); + } + return StatusCode::FAILURE; + } else { + ATH_MSG_INFO(" Summary of EV impact "); + for (auto sysRemove : listOfExcludedSysts) { + std::string flavourAffected = ""; + for (auto flavour : btageff->listScaleFactorSystematics(false)) { + for (auto sysCDI : flavour.second) { + if (sysRemove == sysCDI) flavourAffected += flavour.first; + } + } + ATH_MSG_INFO(" ... " + sysRemove + " -> Removed from calibration(s) : [" + flavourAffected + "]"); + } + ATH_MSG_INFO(" These will be dynamically matched to systematic tree names (if available)"); + ATH_MSG_INFO(" All systematics are accepted by CDI file "); + } + // We have passed all the tests so now we store the systematics removed from the EV method and use a mapping to + // ASG/AT naming and return + ATH_MSG_INFO(" ------------------------------------------------ "); + return StatusCode::SUCCESS; + } + + StatusCode FlavorTaggingCPTools::setTaggerWorkingPoints(std::string jetcollection, bool isCalibrated, std::string tagger, std::vector<std::string> list_of_WP) { + // To try to reduce errors, make a helper function for setting the lists of tagger_WP which are required + if (jetcollection == "AntiKt4EMTopoJets" && isCalibrated) { + // use m_calo_WPs_calib + for (auto s : list_of_WP) { + m_calo_WPs_calib.push_back(tagger + "_" + s); + m_calo_WPs.push_back(tagger + "_" + s); + } + } else if (jetcollection == "AntiKt4EMTopoJets" && !isCalibrated) { + // use m_calo_WPs + for (auto s : list_of_WP) m_calo_WPs.push_back(tagger + "_" + s); + } else if (jetcollection == "AntiKt4EMPFlowJets" && isCalibrated) { + // use m_pflow_WPs_calib + for (auto s : list_of_WP) { + m_pflow_WPs_calib.push_back(tagger + "_" + s); + m_pflow_WPs.push_back(tagger + "_" + s); + } + } else if (jetcollection == "AntiKt4EMPFlowJets" && !isCalibrated) { + // use m_pflow_WPs + for (auto s : list_of_WP) m_pflow_WPs.push_back(tagger + "_" + s); + } else if (jetcollection == "AntiKtVR30Rmax4Rmin02TrackJets" && isCalibrated) { + // use m_trackAntiKt2_WPs_calib + for (auto s : list_of_WP) { + m_trackAntiKtVR_WPs_calib.push_back(tagger + "_" + s); + m_trackAntiKtVR_WPs.push_back(tagger + "_" + s); + } + } else if (jetcollection == "AntiKtVR30Rmax4Rmin02TrackJets" && !isCalibrated) { + // use m_trackAntiKt2_WPs + for (auto s : list_of_WP) m_trackAntiKtVR_WPs.push_back(tagger + "_" + s); + } else if (jetcollection == "AntiKt2PV0TrackJets" && isCalibrated) { + // use m_trackAntiKt2_WPs_calib + for (auto s : list_of_WP) { + m_trackAntiKt2_WPs_calib.push_back(tagger + "_" + s); + m_trackAntiKt2_WPs.push_back(tagger + "_" + s); + } + } else if (jetcollection == "AntiKt2PV0TrackJets" && !isCalibrated) { + // use m_trackAntiKt2_WPs + for (auto s : list_of_WP) m_trackAntiKt2_WPs.push_back(tagger + "_" + s); + } else if (jetcollection == "AntiKt4PV0TrackJets" && isCalibrated) { + // use m_trackAntiKt4_WPs_calib + for (auto s : list_of_WP) { + m_trackAntiKt4_WPs_calib.push_back(tagger + "_" + s); + m_trackAntiKt4_WPs.push_back(tagger + "_" + s); + } + } else if (jetcollection == "AntiKt4PV0TrackJets" && !isCalibrated) { + // use m_trackAntiKt2_WPs_calib + for (auto s : list_of_WP) m_trackAntiKt4_WPs.push_back(tagger + "_" + s); + } else { + ATH_MSG_ERROR("Unknown jet collection and calibration options"); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } + + void FlavorTaggingCPTools::printConfigurations() { + // Debugging function, not used in release + ATH_MSG_INFO("AntiKt4EMTopoJets - Calibrated WP"); + for (auto s : m_calo_WPs_calib) ATH_MSG_INFO(" -> " << s); + ATH_MSG_INFO("AntiKt4EMTopoJets - Available selection WP"); + for (auto s : m_calo_WPs) ATH_MSG_INFO(" -> " << s); + + return; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopGhostTrackCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopGhostTrackCPTools.cxx index 65b026849d93..c6175c32e983 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopGhostTrackCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopGhostTrackCPTools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopGhostTrackCPTools.h" @@ -17,158 +17,189 @@ namespace top { - -GhostTrackCPTools::GhostTrackCPTools(const std::string& name) : + GhostTrackCPTools::GhostTrackCPTools(const std::string& name) : asg::AsgTool(name) { - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); -} + declareProperty("config", m_config); + } -StatusCode GhostTrackCPTools::initialize() { - ATH_MSG_INFO("top::GhostTrackCPTools initialize..."); + StatusCode GhostTrackCPTools::initialize() { + ATH_MSG_INFO("top::GhostTrackCPTools initialize..."); - if (m_config->isTruthDxAOD()) { - ATH_MSG_INFO("top::GhostTrackCPTools: no need to initialise anything on truth DxAOD"); - return StatusCode::SUCCESS; - } + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::GhostTrackCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; + } + + if (!m_config->useJets() || !m_config->useJetGhostTrack()) { + ATH_MSG_INFO( + "top::GhostTrackCPTools: no need to initialise anything since not using jets or tracks ghost-matched to jets"); + return StatusCode::SUCCESS; + } + + if (!m_config->makeAllCPTools()) { + ATH_MSG_INFO("top::GhostTrackCPTools: no need to initialise for mini-xAOD"); + return StatusCode::SUCCESS; + } + + + // This defines the run period (ranges) that are used by the + // InDet::InDetTrackBiasingTool. The following inputs are possible: + // - No / empty input: Use the maximum range, that is [0; + // UInt32_t::max) as allowed run number value range. Initialise + // the tool with run number 0 (which will use 2015 precriptions). + // - A single run number: Configure the tool with this run number + // and to not apply checks / selection on the random run number of + // the actual events. + // - At least two values: Use this to define adjacent ranges, each + // of which is processed using a unique instance of the tool which + // was initialised using the lower bound of the range. From an + // input of size n, n-1 ranges are formed. The i-th element is the + // lower bound (incl) of the i-th range; the (i+1)-th element is + // the upper bound (excl) of the i-th range. + m_runPeriods = { + 276262, 297730, 300909, 311482, 334738, 341650, 364486 + }; + + m_config->runPeriodJetGhostTrack(m_runPeriods); + + top::check(setupSmearingTool(), "Failed to setup track smearing tools"); + top::check(setupBiasingTools(), "Failed to setup track biasing tools"); + top::check(setupTruthFilterTool(), "Failed to setup truth filter tools"); + top::check(setupJetTrackFilterTool(), "Failed to setup track filter tools"); + top::check(setupSelectionTool(), "Failed to setup track selection tools"); - if (!m_config->useJets() || !m_config->useJetGhostTrack()) { - ATH_MSG_INFO("top::GhostTrackCPTools: no need to initialise anything since not using jets or tracks ghost-matched to jets"); return StatusCode::SUCCESS; } - if (!m_config->makeAllCPTools()) { - ATH_MSG_INFO("top::GhostTrackCPTools: no need to initialise for mini-xAOD"); + StatusCode GhostTrackCPTools::setupSelectionTool() { + + if (asg::ToolStore::contains<InDet::InDetTrackSelectionTool>(m_TrkSelName)) { + m_trackseltool = asg::ToolStore::get<InDet::InDetTrackSelectionTool>(m_TrkSelName); + } else { + auto selTool = std::make_unique<InDet::InDetTrackSelectionTool>( m_TrkSelName ,m_config->ghostTracksQuality()); + top::check(selTool -> initialize(), "Failed to initialize InDetTrackSelectionTool for GA tracks"); + m_trackseltool = selTool.release(); + ATH_MSG_INFO("Creating selection tool " + m_TrkSelName); + } + return StatusCode::SUCCESS; + } - // This defines the run period (ranges) that are used by the - // InDet::InDetTrackBiasingTool. The following inputs are possible: - // - No / empty input: Use the maximum range, that is [0; - // UInt32_t::max) as allowed run number value range. Initialise - // the tool with run number 0 (which will use 2015 precriptions). - // - A single run number: Configure the tool with this run number - // and to not apply checks / selection on the random run number of - // the actual events. - // - At least two values: Use this to define adjacent ranges, each - // of which is processed using a unique instance of the tool which - // was initialised using the lower bound of the range. From an - // input of size n, n-1 ranges are formed. The i-th element is the - // lower bound (incl) of the i-th range; the (i+1)-th element is - // the upper bound (excl) of the i-th range. - m_runPeriods = {276262, 297730, 300909, 999999}; - - m_config->runPeriodJetGhostTrack(m_runPeriods); - - top::check(setupSmearingTool(), "Failed to setup track smearing tools"); - top::check(setupBiasingTools(), "Failed to setup track biasing tools"); - top::check(setupTruthFilterTool(), "Failed to setup truth filter tools"); - top::check(setupJetTrackFilterTool(), "Failed to setup track filter tools"); - - return StatusCode::SUCCESS; -} - -StatusCode GhostTrackCPTools::setupSmearingTool(){ - - if (asg::ToolStore::contains<InDet::InDetTrackSmearingTool>(m_smearingToolName)){ - m_smearingTool = asg::ToolStore::get<InDet::InDetTrackSmearingTool>(m_smearingToolName); - } else { - auto tool = new InDet::InDetTrackSmearingTool(m_smearingToolName); - top::check(tool->initialize(), "Failure to initialize InDetTrackSmearingTool"); - m_smearingTool = tool; - ATH_MSG_INFO(" Creating smearing tool "+m_smearingToolName ); + StatusCode GhostTrackCPTools::setupSmearingTool() { + if (asg::ToolStore::contains<InDet::InDetTrackSmearingTool>(m_smearingToolName)) { + m_smearingTool = asg::ToolStore::get<InDet::InDetTrackSmearingTool>(m_smearingToolName); + } else { + auto tool = new InDet::InDetTrackSmearingTool(m_smearingToolName); + top::check(tool->initialize(), "Failure to initialize InDetTrackSmearingTool"); + m_smearingTool = tool; + ATH_MSG_INFO(" Creating smearing tool " + m_smearingToolName); + } + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} - -StatusCode GhostTrackCPTools::setupBiasingTools() { - top::check(not m_runPeriods.empty(), "Assertion failed"); + StatusCode GhostTrackCPTools::setupBiasingTools() { + top::check(not m_runPeriods.empty(), "Assertion failed"); - // Two cases are possible: - // - Either a single run number was specified to the runPeriods - // parameter in which case we'll use exactly that run number, or - // - at least two numbers have been specified, which then define - // (potentially multiple) run number ranges. + // Two cases are possible: + // - Either a single run number was specified to the runPeriods + // parameter in which case we'll use exactly that run number, or + // - at least two numbers have been specified, which then define + // (potentially multiple) run number ranges. - if (m_runPeriods.size() == 1){ - m_runPeriods.resize(1); + if (m_runPeriods.size() == 1) { + m_runPeriods.resize(1); - const std::string biasToolName{m_biasToolPrefix + "_" + std::to_string(m_runPeriods[0])}; + const std::string biasToolName { + m_biasToolPrefix + "_" + std::to_string(m_runPeriods[0]) + }; - if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)){ - m_biasingTool[0] = asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); + if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)) { + m_biasingTool[0] = asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); + } else { + auto tool = new InDet::InDetTrackBiasingTool(biasToolName); + top::check(tool->setProperty("runNumber", m_runPeriods[0]), + "Failure to setProperty runNumber of InDetTrackBiasingTool " + biasToolName); + top::check(tool->initialize(), + "Failure to initialize InDetTrackBiasingTool " + biasToolName); + m_biasingTool[0] = tool; + } + ATH_MSG_INFO(" Creating biasing tool to calibrate for run#=" << m_runPeriods[0] << ": " + biasToolName); } else { - auto tool = new InDet::InDetTrackBiasingTool(biasToolName); - top::check(tool->setProperty("runNumber", m_runPeriods[0]), - "Failure to setProperty runNumber of InDetTrackBiasingTool "+biasToolName); - top::check(tool->initialize(), - "Failure to initialize InDetTrackBiasingTool "+biasToolName); - m_biasingTool[0] = tool; - } - ATH_MSG_INFO(" Creating biasing tool to calibrate for run#=" << m_runPeriods[0] <<": "+biasToolName ); - - } else { - m_biasingTool.resize(m_runPeriods.size() - 1); - for (std::size_t i=0; i<m_runPeriods.size() - 1; ++i){ - const std::string biasToolName{m_biasToolPrefix - + "_" + std::to_string(m_runPeriods[i]) - + "_" + std::to_string(m_runPeriods[i + 1])}; - ATH_MSG_INFO(" Creating biasing tool to calibrate for period [" << m_runPeriods[i] << ", " << m_runPeriods[i + 1] << "): "<<biasToolName ); - if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)){ + m_biasingTool.resize(m_runPeriods.size() - 1); + for (std::size_t i = 0; i < m_runPeriods.size() - 1; ++i) { + const std::string biasToolName { + m_biasToolPrefix + + "_" + std::to_string(m_runPeriods[i]) + + "_" + std::to_string(m_runPeriods[i + 1]) + }; + ATH_MSG_INFO( + " Creating biasing tool to calibrate for period [" << m_runPeriods[i] << ", " << m_runPeriods[i + 1] << "): " << + biasToolName); + if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)) { m_biasingTool[i] = - asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); - } else { + asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); + } else { auto tool = new InDet::InDetTrackBiasingTool(biasToolName); top::check(tool->setProperty("runNumber", m_runPeriods[i]), - "Failure to setProperty runNumber of InDetTrackBiasingTool "+biasToolName); + "Failure to setProperty runNumber of InDetTrackBiasingTool " + biasToolName); top::check(tool->initialize(), - "Failure to initialize InDetTrackBiasingTool "+biasToolName); + "Failure to initialize InDetTrackBiasingTool " + biasToolName); m_biasingTool[i] = tool; + } } } - } - return StatusCode::SUCCESS; -} - -StatusCode GhostTrackCPTools::setupTruthFilterTool(){ - - if (asg::ToolStore::contains<InDet::InDetTrackTruthOriginTool>(m_truthOriginToolName)){ - m_truthOriginTool = asg::ToolStore::get<InDet::InDetTrackTruthOriginTool>(m_truthOriginToolName); - } else { - auto tool = new InDet::InDetTrackTruthOriginTool(m_truthOriginToolName); - top::check(tool->initialize(), - "Failure to initialize InDetTrackTruthOriginTool "+m_truthOriginToolName); - m_truthOriginTool = tool; - ATH_MSG_INFO(" Creating truth origin tool "+m_truthOriginToolName ); + return StatusCode::SUCCESS; } - if (asg::ToolStore::contains<InDet::InDetTrackTruthFilterTool>(m_truthFilterToolName)){ - m_truthFilterTool = asg::ToolStore::get<InDet::InDetTrackTruthFilterTool>(m_truthFilterToolName); - } else { - auto tool = new InDet::InDetTrackTruthFilterTool(m_truthFilterToolName); - top::check(tool->setProperty("trackOriginTool", - ToolHandle<InDet::IInDetTrackTruthOriginTool>{&(* m_truthOriginTool)}), - "Failed to setProperty trackOriginTool of InDetTrackTruthFilterTool "+m_truthFilterToolName); - top::check(tool->initialize(), - "Failure to initialize InDetTrackTruthFilterTool "+m_truthFilterToolName); - m_truthFilterTool = tool; - ATH_MSG_INFO(" Creating truth filter tool "+m_truthFilterToolName ); - } - return StatusCode::SUCCESS; -} - -StatusCode GhostTrackCPTools::setupJetTrackFilterTool(){ - - if (asg::ToolStore::contains<InDet::JetTrackFilterTool>(m_jetTrackFilterToolName)){ - m_jetTrackFilterTool = asg::ToolStore::get<InDet::JetTrackFilterTool>(m_jetTrackFilterToolName); - } else { - auto tool = new InDet::JetTrackFilterTool(m_jetTrackFilterToolName); - top::check(tool->initialize(), "Failure to initialize JetTrackFilterTool"); - m_jetTrackFilterTool = tool; - ATH_MSG_INFO(" Creating jet track filter tool" ); + StatusCode GhostTrackCPTools::setupTruthFilterTool() { + if (asg::ToolStore::contains<InDet::InDetTrackTruthOriginTool>(m_truthOriginToolName)) { + m_truthOriginTool = asg::ToolStore::get<InDet::InDetTrackTruthOriginTool>(m_truthOriginToolName); + } else { + auto tool = new InDet::InDetTrackTruthOriginTool(m_truthOriginToolName); + top::check(tool->initialize(), + "Failure to initialize InDetTrackTruthOriginTool " + m_truthOriginToolName); + m_truthOriginTool = tool; + ATH_MSG_INFO(" Creating truth origin tool " + m_truthOriginToolName); + } + + if (asg::ToolStore::contains<InDet::InDetTrackTruthFilterTool>(m_truthFilterToolName)) { + m_truthFilterTool = asg::ToolStore::get<InDet::InDetTrackTruthFilterTool>(m_truthFilterToolName); + } else { + auto tool = new InDet::InDetTrackTruthFilterTool(m_truthFilterToolName); + top::check(tool->setProperty("trackOriginTool", + ToolHandle<InDet::IInDetTrackTruthOriginTool>{&(*m_truthOriginTool)}), + "Failed to setProperty trackOriginTool of InDetTrackTruthFilterTool " + m_truthFilterToolName); + top::check(tool->initialize(), + "Failure to initialize InDetTrackTruthFilterTool " + m_truthFilterToolName); + m_truthFilterTool = tool; + ATH_MSG_INFO(" Creating truth filter tool " + m_truthFilterToolName); + } + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} + StatusCode GhostTrackCPTools::setupJetTrackFilterTool() { + if (asg::ToolStore::contains<InDet::InDetTrackTruthOriginTool>(m_truthOriginToolName)) { + m_truthOriginTool = asg::ToolStore::get<InDet::InDetTrackTruthOriginTool>(m_truthOriginToolName); + } else { + auto tool = new InDet::InDetTrackTruthOriginTool(m_truthOriginToolName); + top::check(tool->initialize(), + "Failure to initialize InDetTrackTruthOriginTool " + m_truthOriginToolName); + m_truthOriginTool = tool; + ATH_MSG_INFO(" Creating truth origin tool " + m_truthOriginToolName); + } + + if (asg::ToolStore::contains<InDet::JetTrackFilterTool>(m_jetTrackFilterToolName)) { + m_jetTrackFilterTool = asg::ToolStore::get<InDet::JetTrackFilterTool>(m_jetTrackFilterToolName); + } else { + auto tool = new InDet::JetTrackFilterTool(m_jetTrackFilterToolName); + top::check(tool->setProperty("trackOriginTool", + ToolHandle<InDet::IInDetTrackTruthOriginTool>{&(*m_truthOriginTool)}), + "Failed to setProperty trackOriginTool of InDetTrackTruthFilterTool " + m_truthFilterToolName); + top::check(tool->initialize(), "Failure to initialize JetTrackFilterTool"); + m_jetTrackFilterTool = tool; + ATH_MSG_INFO(" Creating jet track filter tool"); + } + return StatusCode::SUCCESS; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopIsolationCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopIsolationCPTools.cxx index 7d9bc98441bb..4528701ee5e7 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopIsolationCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopIsolationCPTools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopIsolationCPTools.h" @@ -16,90 +16,149 @@ // Isolation include(s): #include "IsolationSelection/IsolationSelectionTool.h" +//#include "IsolationSelection/IsolationLowPtPLVTool.h" #include "IsolationCorrections/IsolationCorrectionTool.h" namespace top { - -IsolationCPTools::IsolationCPTools(const std::string& name) : + IsolationCPTools::IsolationCPTools(const std::string& name) : asg::AsgTool(name), - m_isolationCalibFile("IsolationSelection/v1/MC15_Z_Jpsi_cutMap.root"){ - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); + m_isolationCalibFile("IsolationSelection/v1/MC15_Z_Jpsi_cutMap.root") { + declareProperty("config", m_config); - declareProperty( "IsolationCorrectionTool" , m_isolationCorr); -} + declareProperty("IsolationCorrectionTool", m_isolationCorr); + } -StatusCode IsolationCPTools::initialize() { - ATH_MSG_INFO("top::IsolationCPTools initialize..."); + StatusCode IsolationCPTools::initialize() { + ATH_MSG_INFO("top::IsolationCPTools initialize..."); - if (!m_config->makeAllCPTools()) { - ATH_MSG_INFO("top::IsolationCPTools: no need to initialise for mini-xAOD"); - return StatusCode::SUCCESS; - } + if (!m_config->makeAllCPTools()) { + ATH_MSG_INFO("top::IsolationCPTools: no need to initialise for mini-xAOD"); + return StatusCode::SUCCESS; + } - if (!m_config->useElectrons() && m_config->useMuons()) { - ATH_MSG_INFO("top::IsolationCPTools: no need to initialise since neither using electrons nor muons"); + if (!m_config->useElectrons() && !m_config->useMuons()) { + ATH_MSG_INFO("top::IsolationCPTools: no need to initialise since neither using electrons nor muons"); + return StatusCode::SUCCESS; + } + top::check(setupIsolation(), "Failed to setup Isolation tools"); return StatusCode::SUCCESS; } - top::check(setupIsolation(), "Failed to setup Isolation tools"); - return StatusCode::SUCCESS; -} - -StatusCode IsolationCPTools::setupIsolation() { - // needed both for electrons and photons to apply the leakage correction, - // [http://cern.ch/go/j6Lx] - std::string iso_corr_tool_name = "CP::IsolationCorrectionTool"; - if (asg::ToolStore::contains<CP::IIsolationCorrectionTool>(iso_corr_tool_name)) { - m_isolationCorr = asg::ToolStore::get<CP::IIsolationCorrectionTool>(iso_corr_tool_name); - } else { - CP::IIsolationCorrectionTool* isolationCorr = new CP::IsolationCorrectionTool(iso_corr_tool_name); - top::check(asg::setProperty(isolationCorr, "IsMC", m_config->isMC()), - "Failed to setProperty"); // if MC, else false - top::check(isolationCorr->initialize(), "Failed to initialize"); - - m_isolationCorr = isolationCorr; - } - // Muon Isolation WPs - std::set<std::string> muon_isolations = {"LooseTrackOnly", "Loose", - "Gradient", "GradientLoose", - "FixedCutTightTrackOnly", - "FixedCutLoose"}; - // Electron Isolation WPs include all of those defined for - // muons + FixedCutTight - std::set<std::string> electron_isolations; - electron_isolations.insert(muon_isolations.begin(), muon_isolations.end()); - electron_isolations.insert("FixedCutTight"); - // Photon Isolation WPs - std::set<std::string> photon_isolations = {"FixedCutTightCaloOnly", - "FixedCutTight", - "FixedCutLoose"}; - - std::set<std::string> all_isolations; - all_isolations.insert(muon_isolations.begin(), muon_isolations.end()); - all_isolations.insert(electron_isolations.begin(), electron_isolations.end()); - all_isolations.insert(photon_isolations.begin(), photon_isolations.end()); - - for (const std::string& isoWP : all_isolations) { - std::string tool_name = "CP::IsolationTool_"+isoWP; - if (!asg::ToolStore::contains<CP::IIsolationSelectionTool>(tool_name)) { - CP::IIsolationSelectionTool* iso_tool = new CP::IsolationSelectionTool(tool_name); - top::check(asg::setProperty(iso_tool, "CalibFileName", m_isolationCalibFile), - "Failed to set CalibFileName for " + tool_name); - if (electron_isolations.find(isoWP) != electron_isolations.end()) - top::check(asg::setProperty(iso_tool, "ElectronWP", isoWP), - "Failed to set electron WP for " + tool_name); - if (muon_isolations.find(isoWP) != muon_isolations.end()) - top::check(asg::setProperty(iso_tool, "MuonWP", isoWP), - "Failed to set muon WP for " + tool_name); - if (photon_isolations.find(isoWP) != photon_isolations.end()) - top::check(asg::setProperty(iso_tool, "PhotonWP", isoWP), - "Failed to set photon WP for " + tool_name); - top::check(iso_tool->initialize(), "Failed to initialize " + tool_name); - m_isolationTools.push_back(iso_tool); + StatusCode IsolationCPTools::setupIsolation() { + // needed both for electrons and photons to apply the leakage correction, + // [http://cern.ch/go/j6Lx] + std::string iso_corr_tool_name = "CP::IsolationCorrectionTool"; + if (asg::ToolStore::contains<CP::IIsolationCorrectionTool>(iso_corr_tool_name)) { + m_isolationCorr = asg::ToolStore::get<CP::IIsolationCorrectionTool>(iso_corr_tool_name); + } else { + CP::IIsolationCorrectionTool* isolationCorr = new CP::IsolationCorrectionTool(iso_corr_tool_name); + top::check(asg::setProperty(isolationCorr, "IsMC", m_config->isMC()), + "Failed to setProperty IsMC"); // if MC, else false + top::check(asg::setProperty(isolationCorr, "AFII_corr", m_config->isAFII()), + "Failed to setProperty AFII_corr"); // if AFII, else false + if (m_config->useEgammaLeakageCorrection()) { + top::check(asg::setProperty(isolationCorr, "Apply_SC_leakcorr", true), + "Failed to setProperty Apply_SC_leakcorr"); // super cluster based core correction + top::check(asg::setProperty(isolationCorr, "Apply_etaEDParPU_correction", true), + "Failed to setProperty Apply_etaEDParPU_correction"); // improved energy density based pileup + // correction with eta variations + top::check(asg::setProperty(isolationCorr, "Apply_etaEDPar_mc_correction", m_config->isMC()), + "Failed to setProperty Apply_etaEDPar_mc_correction"); // pileup dependent correction to MC + } + top::check(isolationCorr->initialize(), "Failed to initialize"); + + m_isolationCorr = isolationCorr; } - } - return StatusCode::SUCCESS; -} + // Muon Isolation WPs + std::set<std::string> muon_isolations {{ + "FCTight", + "FCLoose", + "FCTightTrackOnly", + "FCTightTrackOnly_FixedRad", + "FCLoose_FixedRad", + "FCTight_FixedRad", + "FixedCutPflowTight", + "FixedCutPflowLoose", + "PflowTight_FixedRad", + "PflowLoose_FixedRad", + "PflowTight_VarRad", + "PflowLoose_VarRad", + "HighPtTrackOnly", + "TightTrackOnly_VarRad", + "TightTrackOnly_FixedRad", + "PLVTight", + "PLVLoose", + "Tight_VarRad", + "Tight_FixedRad", + "Loose_VarRad", + "Loose_FixedRad", + }}; + + // Electron Isolation WPs + std::set<std::string> electron_isolations {{ + "Gradient", + "FCHighPtCaloOnly", + "FCTight", + "FCLoose", + "HighPtCaloOnly", + "Loose", + "Tight", + "TightTrackOnly", + "TightTrackOnly_FixedRad", + "PflowTight", + "PflowLoose", + "PLVTight", + "PLVLoose", + }}; + + // Photon Isolation WPs + std::set<std::string> photon_isolations {{ + "FixedCutTightCaloOnly", + "FixedCutTight", + "FixedCutLoose", + "TightCaloOnly", + "Tight", + "Loose", + }}; + + std::set<std::string> all_isolations; + all_isolations.insert(muon_isolations.begin(), muon_isolations.end()); + all_isolations.insert(electron_isolations.begin(), electron_isolations.end()); + all_isolations.insert(photon_isolations.begin(), photon_isolations.end()); + + for (const std::string& isoWP : all_isolations) { + std::string tool_name; +// if (isoWP.find("PLV") != std::string::npos){ +// tool_name = "CP::IsolationTool_LowPtPLV"; +// if(!asg::ToolStore::contains<CP::IIsolationLowPtPLVTool>(tool_name)) { +// CP::IIsolationLowPtPLVTool* iso_tool = new CP::IsolationLowPtPLVTool(tool_name); +// top::check(iso_tool->initialize(), "Failed to initialize " + tool_name); +// m_isolationToolsLowPtPLV.push_back(iso_tool); +// } +// } + tool_name = "CP::IsolationTool_" + isoWP; + if (!asg::ToolStore::contains<CP::IIsolationSelectionTool>(tool_name)) { + CP::IIsolationSelectionTool* iso_tool = new CP::IsolationSelectionTool(tool_name); + top::check(asg::setProperty(iso_tool, "CalibFileName", m_isolationCalibFile), + "Failed to set CalibFileName for " + tool_name); + if (electron_isolations.find(isoWP) != + electron_isolations.end()) top::check(asg::setProperty(iso_tool, "ElectronWP", + isoWP), + "Failed to set electron WP for " + + tool_name); + if (muon_isolations.find(isoWP) != muon_isolations.end()) top::check(asg::setProperty(iso_tool, "MuonWP", + isoWP), + "Failed to set muon WP for " + tool_name); + if (photon_isolations.find(isoWP) != + photon_isolations.end()) top::check(asg::setProperty(iso_tool, "PhotonWP", + isoWP), + "Failed to set photon WP for " + + tool_name); + top::check(iso_tool->initialize(), "Failed to initialize " + tool_name); + m_isolationTools.push_back(iso_tool); + } + } + return StatusCode::SUCCESS; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopJetMETCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopJetMETCPTools.cxx index 80ccb2b80393..bb3e3d380abb 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopJetMETCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopJetMETCPTools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopJetMETCPTools.h" @@ -20,480 +20,667 @@ #include "JetMomentTools/JetVertexTaggerTool.h" #include "JetMomentTools/JetForwardJvtTool.h" #include "JetSelectorTools/JetCleaningTool.h" -#include "JetResolution/JERTool.h" -#include "JetResolution/JERSmearingTool.h" #include "JetJvtEfficiency/JetJvtEfficiency.h" +#include "JetSelectorTools/EventCleaningTool.h" // MET include(s): #include "METUtilities/METMaker.h" #include "METUtilities/METSystematicsTool.h" namespace top { - -JetMETCPTools::JetMETCPTools(const std::string& name) : + JetMETCPTools::JetMETCPTools(const std::string& name) : asg::AsgTool(name), m_jetJVT_ConfigFile("JVTlikelihood_20140805.root"), - // Updated to December 2016 recommendations - // config names are the same for Data and FS, for EM or LC jets - m_jetAntiKt4_Data_ConfigFile("JES_data2016_data2015_Recommendation_Dec2016.config"), - m_jetAntiKt4_Data_CalibSequence("JetArea_Residual_Origin_EtaJES_GSC_Insitu"), + // Calibration strings for R21 only + m_jetAntiKt4_Data_ConfigFile("JES_MC16Recommendation_Consolidated_EMTopo_Apr2019_Rel21.config"), + m_jetAntiKt4_Data_CalibSequence("JetArea_Residual_EtaJES_GSC_Insitu"), - m_jetAntiKt4_MCFS_ConfigFile("JES_data2016_data2015_Recommendation_Dec2016.config"), - m_jetAntiKt4_MCFS_CalibSequence("JetArea_Residual_Origin_EtaJES_GSC"), + m_jetAntiKt4_MCFS_ConfigFile("JES_MC16Recommendation_Consolidated_EMTopo_Apr2019_Rel21.config"), + m_jetAntiKt4_MCFS_CalibSequence("JetArea_Residual_EtaJES_GSC_Smear"), - // AFII is different - still June 2015 pre-recommendations - m_jetAntiKt4_MCAFII_ConfigFile("JES_MC15Prerecommendation_AFII_June2015.config"), - m_jetAntiKt4_MCAFII_CalibSequence("JetArea_Residual_Origin_EtaJES_GSC"), + m_jetAntiKt4_MCAFII_ConfigFile("JES_MC16Recommendation_AFII_EMTopo_Apr2019_Rel21.config"), + m_jetAntiKt4_MCAFII_CalibSequence("JetArea_Residual_EtaJES_GSC_Smear"), - // Particle-Flow jets, August 2016 recommendations, no GSC - m_jetAntiKt4_PFlow_MCFS_ConfigFile("JES_MC15cRecommendation_PFlow_Aug2016.config"), - m_jetAntiKt4_PFlow_MCFS_CalibSequence("JetArea_Residual_EtaJES_GSC") { + m_jetAntiKt4_MCAFII_PFlow_ConfigFile("JES_MC16Recommendation_AFII_PFlow_Apr2019_Rel21.config"), + m_jetAntiKt4_MCAFII_PFlow_CalibSequence("JetArea_Residual_EtaJES_GSC_Smear"), - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); + m_jetAntiKt4_PFlow_MCFS_ConfigFile("JES_MC16Recommendation_Consolidated_PFlow_Apr2019_Rel21.config"), + m_jetAntiKt4_PFlow_MCFS_CalibSequence("JetArea_Residual_EtaJES_GSC_Smear"), - declareProperty( "JetCalibrationTool" , m_jetCalibrationTool ); - declareProperty( "JetCalibrationToolLargeR" , m_jetCalibrationToolLargeR ); + m_jetAntiKt4_Data_PFlow_ConfigFile("JES_MC16Recommendation_Consolidated_PFlow_Apr2019_Rel21.config"), + m_jetAntiKt4_Data_PFlow_CalibSequence("JetArea_Residual_EtaJES_GSC_Insitu") { + declareProperty("config", m_config); - declareProperty( "JetUncertaintiesTool" , m_jetUncertaintiesTool); - declareProperty( "JetUncertaintiesToolReducedNPScenario1" , m_jetUncertaintiesToolReducedNPScenario1 ); - declareProperty( "JetUncertaintiesToolReducedNPScenario2" , m_jetUncertaintiesToolReducedNPScenario2 ); - declareProperty( "JetUncertaintiesToolReducedNPScenario3" , m_jetUncertaintiesToolReducedNPScenario3 ); - declareProperty( "JetUncertaintiesToolReducedNPScenario4" , m_jetUncertaintiesToolReducedNPScenario4 ); + declareProperty("JetCalibrationTool", m_jetCalibrationTool); + declareProperty("JetCalibrationToolLargeR", m_jetCalibrationToolLargeR); - declareProperty( "JetCleaningToolLooseBad" , m_jetCleaningToolLooseBad ); - declareProperty( "JetCleaningToolTightBad" , m_jetCleaningToolTightBad ); + declareProperty("JetUncertaintiesTool", m_jetUncertaintiesTool); + declareProperty("JetUncertaintiesToolFrozenJMS", m_jetUncertaintiesToolFrozenJMS); + declareProperty("JetUncertaintiesToolReducedNPScenario1", m_jetUncertaintiesToolReducedNPScenario1); + declareProperty("JetUncertaintiesToolReducedNPScenario2", m_jetUncertaintiesToolReducedNPScenario2); + declareProperty("JetUncertaintiesToolReducedNPScenario3", m_jetUncertaintiesToolReducedNPScenario3); + declareProperty("JetUncertaintiesToolReducedNPScenario4", m_jetUncertaintiesToolReducedNPScenario4); - declareProperty( "JetJERTool" , m_jetJERTool ); - declareProperty( "JetJERSmearingTool" , m_jetJERSmearingTool ); - declareProperty( "JetUpdateJvtTool" , m_jetUpdateJvtTool ); + declareProperty("JetCleaningToolLooseBad", m_jetCleaningToolLooseBad); + declareProperty("JetCleaningToolTightBad", m_jetCleaningToolTightBad); - declareProperty( "JES_data2016_data2015_Recommendation_Dec2016.config", m_jetAntiKt4_MCFS_ConfigFile); - declareProperty( "JetCalibrationSequenceFS", m_jetAntiKt4_MCFS_CalibSequence ); + declareProperty("JetEventCleaningToolLooseBad", m_jetEventCleaningToolLooseBad); + declareProperty("JetEventCleaningToolTightBad", m_jetEventCleaningToolTightBad); - declareProperty( "JES_MC15cRecommendation_PFlow_Aug2016.config", m_jetAntiKt4_PFlow_MCFS_ConfigFile); - declareProperty( "JetArea_Residual_EtaJES_GSC", m_jetAntiKt4_PFlow_MCFS_CalibSequence ); + declareProperty("JetUpdateJvtTool", m_jetUpdateJvtTool); + declareProperty("JetSelectfJvtTool", m_jetSelectfJvtTool); + declareProperty("TruthJetCollectionForHSTagging", m_truthJetCollForHS = "AntiKt4TruthJets"); - declareProperty( "met_maker" , m_met_maker ); - declareProperty( "met_systematics" , m_met_systematics ); -} + declareProperty("JES_data2016_data2015_Recommendation_Dec2016.config", m_jetAntiKt4_MCFS_ConfigFile); + declareProperty("JetCalibrationSequenceFS", m_jetAntiKt4_MCFS_CalibSequence); -StatusCode JetMETCPTools::initialize() { - ATH_MSG_INFO("top::JetMETCPTools initialize..."); - if (m_config->isTruthDxAOD()) { - ATH_MSG_INFO("top::JetMETCPTools: no need to initialise anything on truth DxAOD"); - return StatusCode::SUCCESS; + declareProperty("JES_MC15cRecommendation_PFlow_Aug2016.config", m_jetAntiKt4_PFlow_MCFS_ConfigFile); + declareProperty("JetArea_Residual_EtaJES_GSC", m_jetAntiKt4_PFlow_MCFS_CalibSequence); + + declareProperty("met_maker", m_met_maker); + declareProperty("met_systematics", m_met_systematics); } - if (m_config->useJets()) { - if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs - top::check(setupJetsCalibration(), "Failed to setup jet calibration tools"); + StatusCode JetMETCPTools::initialize() { + ATH_MSG_INFO("top::JetMETCPTools initialize..."); + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::JetMETCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; } - // JVT tool needed for both MC and data (for both selection and SFs) - top::check(setupJetsScaleFactors(), "Failed to setup jet scale-factor tools"); - } - if (m_config->useLargeRJets()) - top::check(setupLargeRJetsCalibration(), "Failed to setup large-R jet calibration"); + if (m_config->getDerivationStream() == "PHYS") { + m_truthJetCollForHS = "AntiKt4TruthDressedWZJets"; + } - if (m_config->makeAllCPTools()) {// MET not needed on mini-xAODs - top::check(setupMET(), "Failed to setup MET tools"); - } + if (m_config->useJets()) { + if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs + top::check(setupJetsCalibration(), "Failed to setup jet calibration tools"); + } + // JVT tool needed for both MC and data (for both selection and SFs) + top::check(setupJetsScaleFactors(), "Failed to setup jet scale-factor tools"); + } - return StatusCode::SUCCESS; -} - -StatusCode JetMETCPTools::setupJetsCalibration() { - - // Release 21 specific - // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/ApplyJetCalibration2016#Calibrating_jets_in_Release_21 - if(m_release_series == 25){ - ATH_MSG_INFO("Updating configuration options for Rel21"); - // Data - m_jetAntiKt4_Data_ConfigFile = "JES_data2016_data2015_Recommendation_Dec2016_rel21.config"; - m_jetAntiKt4_Data_CalibSequence = "JetArea_Residual_EtaJES_GSC_Insitu"; - // FS EM/LC - m_jetAntiKt4_MCFS_ConfigFile = "JES_data2016_data2015_Recommendation_Dec2016_rel21.config"; - m_jetAntiKt4_MCFS_CalibSequence = "JetArea_Residual_EtaJES_GSC"; - // AFII EM/LC - m_jetAntiKt4_MCAFII_ConfigFile = ""; // No Rel21 - m_jetAntiKt4_MCAFII_CalibSequence = ""; - // FS PFlow - m_jetAntiKt4_PFlow_MCFS_ConfigFile = "JES_MC15cRecommendation_PFlow_Aug2016.config"; // MC15c? - m_jetAntiKt4_PFlow_MCFS_CalibSequence = "JetArea_Residual_EtaJES_GSC"; - // Note there are suggestions for PFlow in Data - // JES_MC15cRecommendation_PFlow_Aug2016.config - // JetArea_Residual_EtaJES_GSC - } + if (m_config->useLargeRJets()) top::check(setupLargeRJetsCalibration(), "Failed to setup large-R jet calibration"); - // Get jet calibration name and erase "Jets" from the end - std::string caloJets_collection = m_config->sgKeyJets(); - std::string jetCalibrationName; - if (caloJets_collection == "AntiKt4EMTopoNoElJets"){ - jetCalibrationName="AntiKt4EMTopoJets"; - } - else{ - jetCalibrationName = caloJets_collection ; - } - jetCalibrationName.erase(jetCalibrationName.length() - 4); + if (m_config->makeAllCPTools()) {// MET not needed on mini-xAODs + top::check(setupMET(), "Failed to setup MET tools"); + } - // In case of using JMS calibration - if ( m_config->jetCalibSequence() == "JMS" ) { - m_jetAntiKt4_MCFS_ConfigFile.erase(m_jetAntiKt4_MCFS_ConfigFile.length() - 7);//erase ".config" at the end - m_jetAntiKt4_MCFS_ConfigFile += "_JMS.config"; - m_jetAntiKt4_MCFS_CalibSequence += "_JMS"; + return StatusCode::SUCCESS; } - ///-- Calibration --/// - if (asg::ToolStore::contains<IJetCalibrationTool>("JetCalibrationTool")) { - m_jetCalibrationTool = asg::ToolStore::get<IJetCalibrationTool>("JetCalibrationTool"); - } else { - std::string calibConfig, calibSequence; - if (m_config->isMC()) { - if (m_config->isAFII()) { - calibConfig = m_jetAntiKt4_MCAFII_ConfigFile; - calibSequence = m_jetAntiKt4_MCAFII_CalibSequence; - } else { - calibConfig = m_jetAntiKt4_MCFS_ConfigFile; - calibSequence = m_jetAntiKt4_MCFS_CalibSequence; - } + StatusCode JetMETCPTools::setupJetsCalibration() { + // Release 21 specific + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/JetEtmissRecommendationsR21 + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/ApplyJetCalibrationR21 + + // Get jet calibration name and erase "Jets" from the end + std::string caloJets_type = m_config->sgKeyJetsType(); + std::string jetCalibrationName; + if (caloJets_type == "AntiKt4EMTopoNoElJets") { + jetCalibrationName = "AntiKt4EMTopoJets"; } else { - calibConfig = m_jetAntiKt4_Data_ConfigFile; - calibSequence = m_jetAntiKt4_Data_CalibSequence; + jetCalibrationName = caloJets_type; } - if (m_config->useParticleFlowJets()) { - calibConfig = m_jetAntiKt4_PFlow_MCFS_ConfigFile; - calibSequence = m_jetAntiKt4_PFlow_MCFS_CalibSequence; + jetCalibrationName.erase(jetCalibrationName.length() - 4); + + // In case of using JMS calibration + if (m_config->jetCalibSequence() == "JMS") { + ATH_MSG_ERROR("Unable to calibrate jets with JMS calib sequence in release 21: No recommendations! "); + return StatusCode::FAILURE; + + // If this is functional, remove the error above and reconfigure the calibration sequence + m_jetAntiKt4_MCFS_ConfigFile.erase(m_jetAntiKt4_MCFS_ConfigFile.length() - 7);//erase ".config" at the end + m_jetAntiKt4_MCFS_ConfigFile += "_JMS.config"; + m_jetAntiKt4_MCFS_CalibSequence += "_JMS"; } - JetCalibrationTool* jetCalibrationTool = new JetCalibrationTool("JetCalibrationTool"); - top::check(asg::setProperty(jetCalibrationTool, "JetCollection", jetCalibrationName), - "Failed to set JetCollection " + jetCalibrationName); - top::check(asg::setProperty(jetCalibrationTool, "ConfigFile", calibConfig), - "Failed to set ConfigFile " + calibConfig); - top::check(asg::setProperty(jetCalibrationTool, "CalibSequence", calibSequence), - "Failed to set CalibSequence " + calibSequence); - top::check(asg::setProperty(jetCalibrationTool, "IsData", !m_config->isMC()), - "Failed to set IsData " + !m_config->isMC()); - - top::check(jetCalibrationTool->initializeTool(jetCalibrationName), - "Failed to initialize JetCalibrationTool"); - m_jetCalibrationTool = jetCalibrationTool; - } + ///-- Calibration --/// + if (asg::ToolStore::contains<IJetCalibrationTool>("JetCalibrationTool")) { + m_jetCalibrationTool = asg::ToolStore::get<IJetCalibrationTool>("JetCalibrationTool"); + } else { + std::string calibConfig, calibSequence; + if (m_config->isMC()) { + // AFII + if (m_config->isAFII()) { + if (m_config->useParticleFlowJets()) { + calibConfig = m_jetAntiKt4_MCAFII_PFlow_ConfigFile; + calibSequence = m_jetAntiKt4_MCAFII_PFlow_CalibSequence; + } else { + calibConfig = m_jetAntiKt4_MCAFII_ConfigFile; + calibSequence = m_jetAntiKt4_MCAFII_CalibSequence; + } + } + // FS - PFlow + else if (m_config->useParticleFlowJets()) { + calibConfig = m_jetAntiKt4_PFlow_MCFS_ConfigFile; + calibSequence = m_jetAntiKt4_PFlow_MCFS_CalibSequence; + } + // FS + else { + calibConfig = m_jetAntiKt4_MCFS_ConfigFile; + calibSequence = m_jetAntiKt4_MCFS_CalibSequence; + } + } else { + if (m_config->useParticleFlowJets()) { + calibConfig = m_jetAntiKt4_Data_PFlow_ConfigFile; + calibSequence = m_jetAntiKt4_Data_PFlow_CalibSequence; + } else { + calibConfig = m_jetAntiKt4_Data_ConfigFile; + calibSequence = m_jetAntiKt4_Data_CalibSequence; + } + } - ///-- Update JVT --/// - const std::string jvt_update_name = "JetUpdateJvtTool"; - if (asg::ToolStore::contains<IJetUpdateJvt>(jvt_update_name)) { - m_jetUpdateJvtTool = asg::ToolStore::get<IJetUpdateJvt>(jvt_update_name); - } else { - IJetUpdateJvt* jetUpdateJvtTool = new JetVertexTaggerTool(jvt_update_name); - top::check(asg::setProperty(jetUpdateJvtTool, "JVTFileName", "JetMomentTools/" + m_jetJVT_ConfigFile), - "Failed to set JVTFileName for JetUpdateJvtTool"); - top::check(jetUpdateJvtTool->initialize(), "Failed to initialize"); - m_jetUpdateJvtTool = jetUpdateJvtTool; - } + // Print out some information + ATH_MSG_INFO("Configuration JES tools with "); + ATH_MSG_INFO("JES Calibration Configuration : " << calibConfig); + ATH_MSG_INFO("JES Calibration Sequence : " << calibSequence); + + JetCalibrationTool* jetCalibrationTool = new JetCalibrationTool("JetCalibrationTool"); + top::check(asg::setProperty(jetCalibrationTool, "JetCollection", jetCalibrationName), + "Failed to set JetCollection " + jetCalibrationName); + top::check(asg::setProperty(jetCalibrationTool, "ConfigFile", calibConfig), + "Failed to set ConfigFile " + calibConfig); + top::check(asg::setProperty(jetCalibrationTool, "CalibSequence", calibSequence), + "Failed to set CalibSequence " + calibSequence); + top::check(asg::setProperty(jetCalibrationTool, "IsData", !m_config->isMC()), + "Failed to set IsData " + std::to_string (!m_config->isMC())); + + top::check(jetCalibrationTool->initializeTool(jetCalibrationName), + "Failed to initialize JetCalibrationTool"); + m_jetCalibrationTool = jetCalibrationTool; + } - ///-- Update fJVT --/// - const std::string fjvt_tool_name = "fJVTTool"; - if (asg::ToolStore::contains<IJetModifier>(fjvt_tool_name)) { - m_fjvtTool = asg::ToolStore::get<IJetModifier>(fjvt_tool_name); - } else { - IJetModifier* fJVTTool = new JetForwardJvtTool(fjvt_tool_name); - top::check(asg::setProperty(fJVTTool, "JvtMomentName", "AnalysisTop_JVT"), - "Failed to set JvtMomentName for JetForwardJvtTool"); - // following instructions from: - // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/METUtilities#MET_with_forward_JVT - if (m_config->fwdJetAndMET() == "fJVT") { - top::check(asg::setProperty(fJVTTool, "CentralMaxPt", 60e3), - "Failed to set CentralMaxPt for JetForwardJvtTool"); + ///-- Update JVT --/// + const std::string jvt_update_name = "JetUpdateJvtTool"; + if (asg::ToolStore::contains<IJetUpdateJvt>(jvt_update_name)) { + m_jetUpdateJvtTool = asg::ToolStore::get<IJetUpdateJvt>(jvt_update_name); + } else { + IJetUpdateJvt* jetUpdateJvtTool = new JetVertexTaggerTool(jvt_update_name); + top::check(asg::setProperty(jetUpdateJvtTool, "JVTFileName", "JetMomentTools/" + m_jetJVT_ConfigFile), + "Failed to set JVTFileName for JetUpdateJvtTool"); + top::check(jetUpdateJvtTool->initialize(), "Failed to initialize"); + m_jetUpdateJvtTool = jetUpdateJvtTool; } - top::check(fJVTTool->initialize(), "Failed to initialize " + fjvt_tool_name); - m_fjvtTool = fJVTTool; - } - // TODO(tom.neep@cern.ch): Currently we don't have uncertainties for - // particle flow jets, so return successfully - // here. Keep an eye on this in the future. - // Also: no jet cleaning for particle-flow jets. - if (m_config->useParticleFlowJets()) - return StatusCode::SUCCESS; + ///-- Calculate fJVT --/// + //Only setup fJVT tool if user actually wants it + if (m_config->doForwardJVTinMET() || m_config->getfJVTWP() != "None") { + + const std::string fjvt_tool_name = "JetSelectfJvtTool"; + if (asg::ToolStore::contains<IJetModifier>(fjvt_tool_name)) { + m_jetSelectfJvtTool = asg::ToolStore::get<IJetModifier>(fjvt_tool_name); + } else { + IJetModifier* JetSelectfJvtTool = new JetForwardJvtTool(fjvt_tool_name); + top::check(asg::setProperty(JetSelectfJvtTool, "JvtMomentName", "AnalysisTop_JVT"), //fJVT uses JVT decision + "Failed to set JvtMomentName for JetForwardJvtTool"); + + //Default fJVT WP is medium but this can't be used with default Tight MET WP + //MET WP takes precidence so making ATop default fJVT=Tight + if (m_config->getfJVTWP() != "Medium"){ + top::check(asg::setProperty(JetSelectfJvtTool, "UseTightOP", true), + "Failed to set UseTightOP for JetForwardJvtTool"); + } + top::check(asg::setProperty(JetSelectfJvtTool, "OutputDec", "AnalysisTop_fJVTdecision"), //Adds custom decorator, 'AnalysisTop_fJVTdecision', to all jets + "Failed to set OutputDec for JetForwardJvtTool"); + + top::check(JetSelectfJvtTool->initialize(), "Failed to initialize " + fjvt_tool_name); + m_jetSelectfJvtTool = JetSelectfJvtTool; + } + } - ///-- Jet Cleaning Tools --/// - m_jetCleaningToolLooseBad = setupJetCleaningTool("LooseBad"); - m_jetCleaningToolTightBad = setupJetCleaningTool("TightBad"); - - // Uncertainties - // Is our MC full or fast simulation? - std::string MC_type = (m_config->isAFII()) ? "AFII" : "MC15"; - - std::string conference = "Moriond2017"; - - // Are we doing multiple JES for the reduced NP senarios? - if (!m_config->doMultipleJES()) { - m_jetUncertaintiesTool - = setupJetUncertaintiesTool("JetUncertaintiesTool", - jetCalibrationName, MC_type, - "JES_2016/" - + conference - +"/JES2016_" - + m_config->jetUncertainties_NPModel() - + ".config",nullptr); - } else { - m_jetUncertaintiesToolReducedNPScenario1 - = setupJetUncertaintiesTool("JetUncertaintiesToolReducedNPScenario1", - jetCalibrationName, MC_type, - "JES_2016/" - + conference - + "/JES2016_SR_Scenario1.config",nullptr); - m_jetUncertaintiesToolReducedNPScenario2 - = setupJetUncertaintiesTool("JetUncertaintiesToolReducedNPScenario2", - jetCalibrationName, MC_type, - "JES_2016/" - + conference - + "/JES2016_SR_Scenario2.config",nullptr); - m_jetUncertaintiesToolReducedNPScenario3 - = setupJetUncertaintiesTool("JetUncertaintiesToolReducedNPScenario3", - jetCalibrationName, MC_type, - "JES_2016/" - + conference - + "/JES2016_SR_Scenario3.config",nullptr); - m_jetUncertaintiesToolReducedNPScenario4 - = setupJetUncertaintiesTool("JetUncertaintiesToolReducedNPScenario4", - jetCalibrationName, MC_type, - "JES_2016/" - + conference - + "/JES2016_SR_Scenario4.config",nullptr); - } + ///-- Jet Cleaning Tools --/// + m_jetCleaningToolLooseBad = setupJetCleaningTool("LooseBad"); + m_jetCleaningToolTightBad = setupJetCleaningTool("TightBad"); - // JER Tool - if (asg::ToolStore::contains<IJERTool>("JetJERTool")) { - m_jetJERTool = asg::ToolStore::get<IJERTool>("JetJERTool"); - } else { - IJERTool* jetJERTool = new JERTool("JetJERTool"); - top::check(asg::setProperty(jetJERTool, "CollectionName", "AntiKt4EMTopoJets"), - "Failed to set CollectionName to JetJERTool"); - top::check(jetJERTool->initialize(), "Failed to initialize"); - m_jetJERTool = jetJERTool; - } + m_jetEventCleaningToolLooseBad = setupJetEventCleaningTool("LooseBad", m_jetCleaningToolLooseBad); + m_jetEventCleaningToolTightBad = setupJetEventCleaningTool("TightBad", m_jetCleaningToolTightBad); - // JER Smearing - const std::string jersmear_name = "JetJERSmearingTool"; - if (asg::ToolStore::contains<IJERSmearingTool>(jersmear_name)) { - m_jetJERSmearingTool = asg::ToolStore::get<IJERSmearingTool>(jersmear_name); - } else { - IJERSmearingTool* jetJERSmearingTool = new JERSmearingTool(jersmear_name); - top::check(asg::setProperty(jetJERSmearingTool, "JERTool" , m_jetJERTool), - "Failed to JERTool to " + jersmear_name); - top::check(asg::setProperty(jetJERSmearingTool, "ApplyNominalSmearing", false), - "Failed to ApplyNominalSmearing for " + jersmear_name); - top::check(asg::setProperty(jetJERSmearingTool, "isMC", m_config->isMC()), - "Failed to isMC to " + jersmear_name); - top::check(asg::setProperty(jetJERSmearingTool, "SystematicMode", m_config->jetJERSmearingModel()), - "Failed to SystematicMode for " + jersmear_name); - top::check(jetJERSmearingTool->initialize(), - "Failed to initialize " + jersmear_name); - m_jetJERSmearingTool = jetJERSmearingTool; - } + // Uncertainties + // Is our MC full or fast simulation? + std::string MC_type = (m_config->isAFII()) ? "AFII" : "MC16"; + + // Moriond2018 - AF2 JES + // Summer2019 - JES/JER update + std::string conference = "Summer2019"; - return StatusCode::SUCCESS; -} - -StatusCode JetMETCPTools::setupLargeRJetsCalibration() { - std::string jetCalibrationNameLargeR = m_config->sgKeyLargeRJets(); - // erase "Jets" from the end - jetCalibrationNameLargeR.erase(jetCalibrationNameLargeR.length() - 4); - - if (asg::ToolStore::contains<IJetCalibrationTool>("JetCalibrationToolLargeR")) { - m_jetCalibrationToolLargeR = asg::ToolStore::get<IJetCalibrationTool>("JetCalibrationToolLargeR"); - } else { - // Only a single calib config/sequence for MC and data - // so just put it here for now. - std::string calibConfigLargeR = ""; - const std::string calibChoice = m_config->largeRJESJMSConfig(); - if (calibChoice == "CombinedMass") { - calibConfigLargeR = "JES_MC15recommendation_FatJet_Nov2016_QCDCombinationUncorrelatedWeights.config"; + // If JMS is allowed then there should also be extrapolation and frozen uncertainties configured + std::string JMS_Uncertainty = ""; + if (m_config->jetCalibSequence() == "JMS") JMS_Uncertainty = "_JMSExtrap"; + + // By setting calib_area to "None" we pick up the default from the JES group + std::string calib_area = "None"; + + // JER string option configuration + bool JERisMC = m_config->isMC(); + std::string JERSmearModel = m_config->jetJERSmearingModel(); + // Any PseudoData Option (Smear MC as data) + if (JERSmearModel == "Full_PseudoData") { + if (JERisMC) JERisMC = false; + JERSmearModel = "Full"; + ATH_MSG_INFO("JER PseudoData option provided - Treating MC as if it is data for JER uncertainty"); } - else if (calibChoice == "CaloMass") { - calibConfigLargeR = "JES_MC15recommendation_FatJet_June2015.config"; + if (JERSmearModel == "All_PseudoData") { + if (JERisMC) JERisMC = false; + JERSmearModel = "All"; + ATH_MSG_INFO("JER PseudoData option provided - Treating MC as if it is data for JER uncertainty"); } + + // Strings need to be defined clearly for jet tool + if (JERSmearModel == "All") JERSmearModel = "_AllJERNP"; + else if (JERSmearModel == "Full") JERSmearModel = "_FullJER"; + else if (JERSmearModel == "Simple") JERSmearModel = "_SimpleJER"; else { - ATH_MSG_ERROR("Unknown largeRJESJMSConfig "+calibChoice); + ATH_MSG_ERROR("Incorrect JER option: All, All_PseudoData, Full, Full_PseudoData, Simple"); return StatusCode::FAILURE; } - const std::string calibSequenceLargeR = "EtaJES_JMS"; - - JetCalibrationTool* jetCalibrationToolLargeR - = new JetCalibrationTool("JetCalibrationToolLargeR"); - top::check(asg::setProperty(jetCalibrationToolLargeR, "JetCollection", jetCalibrationNameLargeR), - "Failed to set JetCollection " + jetCalibrationNameLargeR); - top::check(asg::setProperty(jetCalibrationToolLargeR, "ConfigFile", calibConfigLargeR), - "Failed to set ConfigFile " + calibConfigLargeR); - top::check(asg::setProperty(jetCalibrationToolLargeR, "CalibSequence", calibSequenceLargeR), - "Failed to set CalibSequence " + calibSequenceLargeR); - top::check(asg::setProperty(jetCalibrationToolLargeR, "IsData", !m_config->isMC()), - "Failed to set IsData " + !m_config->isMC()); - - top::check(jetCalibrationToolLargeR->initializeTool(jetCalibrationNameLargeR), - "Failed to initialize JetCalibrationToolLargeR"); - m_jetCalibrationToolLargeR = jetCalibrationToolLargeR; - } - // Moriond2017 uncertainty recommendations: - // names = "UJ_2016/Moriond2017/UJ2016_CaloMass_strong.config" // strong,medium,weak - // names = "UJ_2016/Moriond2017/UJ2016_CombinedMass_strong.config" // strong,medium,weak - - std::string conference(""); - std::string configDir(""); - std::vector<std::string>* variables = nullptr; - std::string largeRJES_config = m_config->largeRJESUncertaintyConfig(); - std::string MC_type = "MC15"; - - conference = "Moriond2017"; - configDir = "UJ_2016"; - MC_type += "c"; - - variables = new std::vector<std::string>; - variables->push_back("pT"); - std::string variable; - size_t pos_end = 0; - while( (pos_end = largeRJES_config.find(",")) != std::string::npos) { - variable = largeRJES_config.substr(0,pos_end); - variables->push_back(variable); - largeRJES_config.erase(0,pos_end+1); + // Are we doing multiple JES for the reduced NP senarios? + if (!m_config->doMultipleJES()) { + m_jetUncertaintiesTool = setupJetUncertaintiesTool("JetUncertaintiesTool", + jetCalibrationName, + MC_type, + JERisMC, + "rel21/" + conference + + "/R4_" + m_config->jetUncertainties_NPModel() + + JMS_Uncertainty + + JERSmearModel + + ".config", + nullptr, + m_config->jetUncertainties_QGFracFile(), + calib_area + ); + + // Implement additional tool for frozen config when using JMS + if (JMS_Uncertainty == "_JMSExtrap") { + JMS_Uncertainty = "_JMSFrozen"; + m_jetUncertaintiesToolFrozenJMS = setupJetUncertaintiesTool("JetUncertaintiesToolFrozenJMS", + jetCalibrationName, + MC_type, + JERisMC, + "rel21/" + conference + + "/R4_" + m_config->jetUncertainties_NPModel() + + JMS_Uncertainty + + ".config", + nullptr, + m_config->jetUncertainties_QGFracFile(), + calib_area + ); + } + } else { + // Strong reductions now enabled. If you want to run a single scenario please note the new config file names + // R4_SR_Scenario*_SimpleJER + m_jetUncertaintiesToolReducedNPScenario1 + = setupJetUncertaintiesTool("JetUncertaintiesToolReducedNPScenario1", + jetCalibrationName, + MC_type, + JERisMC, + "rel21/" + + conference + + "/R4_SR_Scenario1_SimpleJER.config", + nullptr, + m_config->jetUncertainties_QGFracFile(), + calib_area); + m_jetUncertaintiesToolReducedNPScenario2 + = setupJetUncertaintiesTool("JetUncertaintiesToolReducedNPScenario2", + jetCalibrationName, + MC_type, + JERisMC, + "rel21/" + + conference + + "/R4_SR_Scenario2_SimpleJER.config", + nullptr, + m_config->jetUncertainties_QGFracFile(), + calib_area); + m_jetUncertaintiesToolReducedNPScenario3 + = setupJetUncertaintiesTool("JetUncertaintiesToolReducedNPScenario3", + jetCalibrationName, + MC_type, + JERisMC, + "rel21/" + + conference + + "/R4_SR_Scenario3_SimpleJER.config", + nullptr, + m_config->jetUncertainties_QGFracFile(), + calib_area); + m_jetUncertaintiesToolReducedNPScenario4 + = setupJetUncertaintiesTool("JetUncertaintiesToolReducedNPScenario4", + jetCalibrationName, + MC_type, + JERisMC, + "rel21/" + + conference + + "/R4_SR_Scenario4_SimpleJER.config", + nullptr, + m_config->jetUncertainties_QGFracFile(), + calib_area); + } + + return StatusCode::SUCCESS; } - variables->push_back(largeRJES_config); - - largeRJES_config = m_config->largeRJESJMSConfig(); - if (largeRJES_config.find("UJ2016_") != 0) largeRJES_config.insert(0, "UJ2016_"); - - m_jetUncertaintiesToolLargeR_strong - = setupJetUncertaintiesTool("JetUncertaintiesToolLargeR_Strong", - jetCalibrationNameLargeR, MC_type, - configDir+"/"+conference - + "/"+largeRJES_config+"_strong.config",variables); - m_jetUncertaintiesToolLargeR_medium - = setupJetUncertaintiesTool("JetUncertaintiesToolLargeR_Medium", - jetCalibrationNameLargeR, MC_type, - configDir+"/"+conference - + "/"+largeRJES_config+"_medium.config",variables); - m_jetUncertaintiesToolLargeR_weak - = setupJetUncertaintiesTool("JetUncertaintiesToolLargeR_Weak", - jetCalibrationNameLargeR, MC_type, - configDir+"/"+conference - + "/"+largeRJES_config+"_weak.config",variables); - - if (variables) delete variables; - return StatusCode::SUCCESS; -} - -StatusCode JetMETCPTools::setupJetsScaleFactors() { - // <tom.neep@cern.ch> Added 16th Feb 2016. - // Jet JVT tool - can be used for both selection and for SFs - // Since we use this for jet selection we also need it for data - const std::string jvt_tool_name = "JetJvtEfficiencyTool"; - const std::string JVT_SFFile = - (m_config->sgKeyJets()=="AntiKt4LCTopoJets")? - "JetJvtEfficiency/Moriond2017/JvtSFFile_LC.root": - "JetJvtEfficiency/Moriond2017/JvtSFFile_EM.root";// default is EM jets - if (asg::ToolStore::contains<CP::IJetJvtEfficiency>(jvt_tool_name)) { - m_jetJvtTool = asg::ToolStore::get<CP::IJetJvtEfficiency>(jvt_tool_name); - } else { - CP::JetJvtEfficiency* jetJvtTool = new CP::JetJvtEfficiency(jvt_tool_name); - // Medium WP default for EM or LC jets; special WP for PFlow jets - top::check(jetJvtTool->setProperty("WorkingPoint", (m_config->useParticleFlowJets())?"PFlow":"Medium"), - "Failed to set JVT WP"); - top::check(jetJvtTool->setProperty("SFFile", JVT_SFFile), - "Failed to set JVT SFFile name"); - top::check(jetJvtTool->setProperty("JetJvtMomentName", "AnalysisTop_JVT"), - "Failed to set JVT decoration name"); - top::check(jetJvtTool->setProperty("TruthLabel", "AnalysisTop_isHS"), - "Failed to set JVT TruthLabel decoration name"); - top::check(jetJvtTool->initialize(), "Failed to initialize JVT tool"); - m_jetJvtTool = jetJvtTool; + + StatusCode JetMETCPTools::setupLargeRJetsCalibration() { + std::string jetCalibrationNameLargeR = m_config->sgKeyLargeRJets(); + // erase "Jets" from the end + jetCalibrationNameLargeR.erase(jetCalibrationNameLargeR.length() - 4); + + if (asg::ToolStore::contains<IJetCalibrationTool>("JetCalibrationToolLargeR")) { + m_jetCalibrationToolLargeR = asg::ToolStore::get<IJetCalibrationTool>("JetCalibrationToolLargeR"); + } else { + // Only a single calib config/sequence for MC and data + // so just put it here for now. + std::string calibConfigLargeR = ""; + const std::string calibChoice = m_config->largeRJESJMSConfig(); + if (m_config->isMC()) { + if (calibChoice == "CombMass") { + calibConfigLargeR = "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_17Oct2018.config"; + } else if (calibChoice == "TAMass") { + calibConfigLargeR = "JES_MC16recommendation_FatJet_Trimmed_JMS_TA_12Oct2018.config"; + } else if (calibChoice == "CaloMass") { + calibConfigLargeR = "JES_MC16recommendation_FatJet_Trimmed_JMS_calo_12Oct2018.config"; + } else if (calibChoice == "TCCMass") { + calibConfigLargeR = "JES_MC16recommendation_FatJet_TCC_JMS_calo_30Oct2018.config"; + } else { + ATH_MSG_ERROR( + "Unknown largeRJESJMSConfig (Available options: TAMass, CaloMass, CombMass and TCCMass)) : " + calibChoice); + return StatusCode::FAILURE; + } + } else { //Insitu calibration for Data + if ((calibChoice == "CombMass") || (calibChoice == "TAMass") || (calibChoice == "CaloMass")) { + calibConfigLargeR = "JES_MC16recommendation_FatJet_Trimmed_JMS_comb_3April2019.config"; //Data has only one + // config file + } else if (calibChoice == "TCCMass") { + calibConfigLargeR = "JES_MC16recommendation_FatJet_TCC_JMS_calo_30Oct2018.config"; //There's no insitu + // calibration yet + } else { + ATH_MSG_ERROR( + "Unknown largeRJESJMSConfig (Available options: TAMass, CaloMass, CombMass and TCCMass) : " + calibChoice); + return StatusCode::FAILURE; + } + } + std::string calibSequenceLargeR = "EtaJES_JMS"; + if ((!m_config->isMC()) && + (calibChoice != "TCCMass")) calibSequenceLargeR = "EtaJES_JMS_Insitu_InsituCombinedMass"; //For data, there's + // is insitu + // calibration for + // lc-topo jets + const std::string calibAreaLargeR = "00-04-82"; + JetCalibrationTool* jetCalibrationToolLargeR + = new JetCalibrationTool("JetCalibrationToolLargeR"); + top::check(asg::setProperty(jetCalibrationToolLargeR, "JetCollection", jetCalibrationNameLargeR), + "Failed to set JetCollection " + jetCalibrationNameLargeR); + top::check(asg::setProperty(jetCalibrationToolLargeR, "ConfigFile", calibConfigLargeR), + "Failed to set ConfigFile " + calibConfigLargeR); + top::check(asg::setProperty(jetCalibrationToolLargeR, "CalibSequence", calibSequenceLargeR), + "Failed to set CalibSequence " + calibSequenceLargeR); + top::check(asg::setProperty(jetCalibrationToolLargeR, "CalibArea", calibAreaLargeR), + "Failed to set CalibArea " + calibAreaLargeR); + top::check(asg::setProperty(jetCalibrationToolLargeR, "IsData", !m_config->isMC()), + "Failed to set IsData " + std::to_string (!m_config->isMC())); + top::check(jetCalibrationToolLargeR->initializeTool(jetCalibrationNameLargeR), + "Failed to initialize JetCalibrationToolLargeR"); + m_jetCalibrationToolLargeR = jetCalibrationToolLargeR; + } + + // Moriond2017 uncertainty recommendations: + // names = "UJ_2016/Moriond2017/UJ2016_CaloMass_strong.config" // strong,medium,weak + // names = "UJ_2016/Moriond2017/UJ2016_CombinedMass_strong.config" // strong,medium,weak + + std::string configDir(""); + std::string largeRJESJMS_config = m_config->largeRJetUncertainties_NPModel(); + std::string calibArea = "None"; // Take the default JetUncertainties CalibArea tag + std::string MC_type = "MC16"; + + configDir = m_config->largeRJetUncertaintiesConfigDir(); + + //This has zero impact on the JES uncertainties, but controls how the JER uncertainties (currently only for small-R + // jets) are applied + bool JERisMC = true; + + m_jetUncertaintiesToolLargeR + = setupJetUncertaintiesTool("JetUncertaintiesToolLargeR", + jetCalibrationNameLargeR, MC_type, JERisMC, + configDir + "/R10_" + largeRJESJMS_config + ".config", nullptr, "", calibArea); + + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} -StatusCode JetMETCPTools::setupMET() -{ - if ( asg::ToolStore::contains<IMETMaker>("met::METMaker") ) { - m_met_maker = asg::ToolStore::get<IMETMaker>("met::METMaker"); - } else { - met::METMaker* metMaker = new met::METMaker("met::METMaker"); - top::check( metMaker->setProperty("JetJvtMomentName", "AnalysisTop_JVT"), "Failed to set METMaker JVT moment name" ); - // following instructions from: - // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EtmissRecommendationsRel20p7Temp#Working_Points_NEW - // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/METUtilities#MET_with_forward_JVT - if (m_config->fwdJetAndMET() == "Tight") { - top::check( metMaker->setProperty("JetSelection", "Tight"), "Failed to set METMaker JetSelection to Tight" ); + StatusCode JetMETCPTools::setupJetsScaleFactors() { + // <tom.neep@cern.ch> Added 16th Feb 2016. + // Jet JVT tool - can be used for both selection and for SFs + // Since we use this for jet selection we also need it for data + const std::string jvt_tool_name = "JetJvtEfficiencyTool"; + const std::string JVT_SFFile = + (m_config->sgKeyJets() == "AntiKt4LCTopoJets") ? + "JetJvtEfficiency/Moriond2018/JvtSFFile_LC.root" : // LC jets + (m_config->useParticleFlowJets()) ? + "JetJvtEfficiency/Moriond2018/JvtSFFile_EMPFlow.root" : // pflow jets + "JetJvtEfficiency/Moriond2018/JvtSFFile_EMTopoJets.root"; // default is EM jets + + const std::string JVT_WP = m_config->getJVTWP(); + + if (asg::ToolStore::contains<CP::IJetJvtEfficiency>(jvt_tool_name)) { + m_jetJvtTool = asg::ToolStore::get<CP::IJetJvtEfficiency>(jvt_tool_name); + } else { + CP::JetJvtEfficiency* jetJvtTool = new CP::JetJvtEfficiency(jvt_tool_name); + top::check(jetJvtTool->setProperty("WorkingPoint", JVT_WP), + "Failed to set JVT WP"); + top::check(jetJvtTool->setProperty("SFFile", JVT_SFFile), + "Failed to set JVT SFFile name"); + top::check(jetJvtTool->setProperty("JetJvtMomentName", "AnalysisTop_JVT"), + "Failed to set JVT decoration name"); + top::check(jetJvtTool->setProperty("TruthLabel", "AnalysisTop_isHS"), + "Failed to set JVT TruthLabel decoration name"); + top::check(jetJvtTool->setProperty("TruthJetContainerName", m_truthJetCollForHS), + "Failed to set JVT TruthJetContainerName decoration name"); + top::check(jetJvtTool->initialize(), "Failed to initialize JVT tool"); + m_jetJvtTool = jetJvtTool; } - else if (m_config->fwdJetAndMET() == "fJVT") { - top::check( metMaker->setProperty("JetRejectionDec", "passFJVT"), "Failed to set METMaker JetRejectionDec to passFJVT" ); + + // <jonathan.jamieson@cern.ch> Added 9th June 2020. + // Jet fJVT tool - uses same tool as for JVT, + // Only setup fJVT Efficiency tool if user actually wants it + if (m_config->getfJVTWP() != "None") { + const std::string fjvt_tool_name = "JetForwardJvtEfficiencyTool"; + const std::string fJVT_SFFile = + (m_config->useParticleFlowJets()) ? + "JetJvtEfficiency/May2020/fJvtSFFile.EMPFlow.root" : // pflow jets + "JetJvtEfficiency/May2020/fJvtSFFile.EMtopo.root"; // default is EM jets + + std::string fJVT_WP = m_config->getfJVTWP(); + if (fJVT_WP == "Medium"){ + fJVT_WP = "Loose"; //Efficiency tool still uses old WP names... + } + + if (asg::ToolStore::contains<CP::IJetJvtEfficiency>(fjvt_tool_name)) { + m_jetfJvtTool = asg::ToolStore::get<CP::IJetJvtEfficiency>(fjvt_tool_name); + } else { + CP::JetJvtEfficiency* jetfJvtTool = new CP::JetJvtEfficiency(fjvt_tool_name); + top::check(jetfJvtTool->setProperty("WorkingPoint", fJVT_WP), + "Failed to set fJVT WP"); + top::check(jetfJvtTool->setProperty("SFFile", fJVT_SFFile), + "Failed to set fJVT SFFile name"); + top::check(jetfJvtTool->setProperty("UseMuSFFormat", true), + "Failed to set fJVT SFFile to updated mu binning"); + top::check(jetfJvtTool->setProperty("ScaleFactorDecorationName", "fJVTSF"), + "Failed to set fJVT SF decoration name"); + top::check(jetfJvtTool->setProperty("JetfJvtMomentName", "AnalysisTop_fJVTdecision"), + "Failed to set fJVT pass/fail decoration name"); + top::check(jetfJvtTool->setProperty("TruthLabel", "AnalysisTop_isHS"), + "Failed to set fJVT TruthLabel decoration name"); + top::check(jetfJvtTool->setProperty("TruthJetContainerName", m_truthJetCollForHS), + "Failed to set fJVT TruthJetContainerName decoration name"); + top::check(jetfJvtTool->initialize(), "Failed to initialize fJVT Efficiency tool"); + m_jetfJvtTool = jetfJvtTool; + } } - top::check( metMaker->initialize() , "Failed to initialize" ); - metMaker->msg().setLevel( MSG::INFO ); - m_met_maker = metMaker; + return StatusCode::SUCCESS; } - if ( asg::ToolStore::contains<IMETSystematicsTool>("met::METSystematicsTool") ) { - m_met_systematics = asg::ToolStore::get<IMETSystematicsTool>("met::METSystematicsTool"); - } else { - met::METSystematicsTool* metSyst = new met::METSystematicsTool("met::METSystematicsTool"); + StatusCode JetMETCPTools::setupMET() { + // See https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/EtmissRecommendationsRel21p2 + // METMaker tool + if (asg::ToolStore::contains<IMETMaker>("met::METMaker")) { + m_met_maker = asg::ToolStore::get<IMETMaker>("met::METMaker"); + } else { + met::METMaker* metMaker = new met::METMaker("met::METMaker"); + top::check(metMaker->setProperty("JetJvtMomentName", "AnalysisTop_JVT"), + "Failed to set METMaker JVT moment name"); - top::check( metSyst->setProperty("ConfigSoftTrkFile", "TrackSoftTerms.config"), "Failed to set property" ); + if (m_config->useParticleFlowJets()) { + top::check(metMaker->setProperty("DoPFlow", true), "Failed to set METMaker DoPFlow to true"); + } + + if (m_config->doForwardJVTinMET()) { + if (m_config->getfJVTWP() == "Medium") { + top::check(metMaker->setProperty("JetSelection", "Tenacious"), "Failed to set METMaker JetSelection to Tenacious"); + } + top::check(metMaker->setProperty("JetRejectionDec","AnalysisTop_fJVTdecision"), "Failed to set METMaker JetRejectionDec to AnalysisTop_fJVTdecision"); + top::check(metMaker->initialize(), "Failed to initialize"); + metMaker->msg().setLevel(MSG::INFO); + m_met_maker = metMaker; + } + } - // Turn off soft calo term systematics... if left on we get some warnings - top::check( metSyst->setProperty("ConfigSoftCaloFile", "" ), "Failed to set property" ); - top::check( metSyst->initialize() , "Failed to initialize" ); - m_met_systematics = metSyst; - } + // MET Systematics tool + if (asg::ToolStore::contains<IMETSystematicsTool>("met::METSystematicsTool")) { + m_met_systematics = asg::ToolStore::get<IMETSystematicsTool>("met::METSystematicsTool"); + } else { + met::METSystematicsTool* metSyst = new met::METSystematicsTool("met::METSystematicsTool"); + + std::string METconfigDir = m_config->METUncertaintiesConfigDir(); + if (METconfigDir == "Latest") METconfigDir = "METUtilities/run2_13TeV/"; //Find calib files here: /cvmfs/atlas.cern.ch/repo/sw/database/GroupData/METUtilities/ + top::check(metSyst->setProperty("ConfigPrefix", METconfigDir), "Failed to set METsyst calibration area"); //Set calib area explicitly - removes potential for crash when default area is changed in METSyst code + // TST (Track soft terms) + if (m_config->useParticleFlowJets()) { + top::check(metSyst->setProperty("ConfigSoftTrkFile", "TrackSoftTerms-pflow.config"), "Failed to set property"); + } else { + if (m_config->isAFII() && METconfigDir == "METUtilities/data17_13TeV/prerec_Jan16/") { + top::check(metSyst->setProperty("ConfigSoftTrkFile", "TrackSoftTerms_AFII.config"), "Failed to set property"); + } else { + top::check(metSyst->setProperty("ConfigSoftTrkFile", "TrackSoftTerms.config"), "Failed to set property"); + } + } + // Deactivate CST terms + top::check(metSyst->setProperty("ConfigSoftCaloFile", ""), "Failed to set property"); + top::check(metSyst->initialize(), "Failed to initialize"); + m_met_systematics = metSyst; + } + return StatusCode::SUCCESS; + } - return StatusCode::SUCCESS; -} - -ICPJetUncertaintiesTool* -JetMETCPTools::setupJetUncertaintiesTool(const std::string& name, - const std::string& jet_def, - const std::string& mc_type, - const std::string& config_file, - std::vector<std::string>* variables) { - ICPJetUncertaintiesTool* tool = nullptr; - if (asg::ToolStore::contains<ICPJetUncertaintiesTool>(name)) { - tool = asg::ToolStore::get<ICPJetUncertaintiesTool>(name); - } else { - tool = new JetUncertaintiesTool(name); - top::check(asg::setProperty(tool, "JetDefinition", jet_def), - "Failed to set JetDefinition for " + name); - top::check(asg::setProperty(tool, "MCType", mc_type), - "Failed to set MCType for " + name); - top::check(asg::setProperty(tool, "ConfigFile", config_file), - "Failed to set ConfigFile for " + name); - if (variables != nullptr){ - top::check(asg::setProperty(tool, "VariablesToShift", *variables), - "Failed to set VariablesToShift for LargeR Jes Uncertainty "+ name); + ICPJetUncertaintiesTool* + JetMETCPTools::setupJetUncertaintiesTool(const std::string& name, + const std::string& jet_def, + const std::string& mc_type, + bool isMC, + const std::string& config_file, + std::vector<std::string>* variables, + const std::string& analysis_file, + const std::string& calib_area + ) { + ICPJetUncertaintiesTool* tool = nullptr; + + if (asg::ToolStore::contains<ICPJetUncertaintiesTool>(name)) { + tool = asg::ToolStore::get<ICPJetUncertaintiesTool>(name); + } else { + tool = new JetUncertaintiesTool(name); + top::check(asg::setProperty(tool, "JetDefinition", jet_def), + "Failed to set JetDefinition for " + name); + top::check(asg::setProperty(tool, "MCType", mc_type), + "Failed to set MCType for " + name); + top::check(asg::setProperty(tool, "IsData", !isMC), + "Failed to set IsData (for JER only)"); + top::check(asg::setProperty(tool, "ConfigFile", config_file), + "Failed to set ConfigFile for " + name); + if (variables != nullptr) { + top::check(asg::setProperty(tool, "VariablesToShift", *variables), + "Failed to set VariablesToShift for LargeR Jes Uncertainty " + name); + } + if (analysis_file != "None") { + if (m_config->jetUncertainties_QGHistPatterns().size() == 0 || analysis_file == "") { // no histogram pattern to + // look for, or empty + // analysis_file argument + top::check(asg::setProperty(tool, "AnalysisFile", analysis_file), + "Failed to set AnalysisFile for " + name); + } else if (m_config->jetUncertainties_QGHistPatterns().size() == 1) { // a single pattern was specified - let's + // use it for all DSIDs + top::check(asg::setProperty(tool, "AnalysisFile", analysis_file), + "Failed to set AnalysisFile for " + name); + top::check(asg::setProperty(tool, "AnalysisHistPattern", m_config->jetUncertainties_QGHistPatterns()[0]), + "Failed to set AnalysisHistPattern for " + name); + } else { // a list of DSIDs was specified + int DSID = m_config->getDSID(); + for (auto s : m_config->jetUncertainties_QGHistPatterns()) { + if (std::atoi(s.c_str()) == DSID) { + top::check(asg::setProperty(tool, "AnalysisFile", analysis_file), + "Failed to set AnalysisFile for " + name); + top::check(asg::setProperty(tool, "AnalysisHistPattern", s), + "Failed to set AnalysisHistPattern for " + name); + break; + } + }// if the DSID is not found in the list, we don't try to use the AnalysisFile, so we get the default 50 +/- + // 50% + } + } + if (calib_area != "None") { + top::check(asg::setProperty(tool, "CalibArea", calib_area), + "Failed to set CalibArea " + calib_area); + } + top::check(tool->initialize(), "Failed to initialize " + name); } - top::check(tool->initialize(), "Failed to initialize " + name); + return tool; } - return tool; -} - -IJetSelector* JetMETCPTools::setupJetCleaningTool(const std::string& WP) { - IJetSelector* tool = nullptr; - std::string name = "JetCleaningTool" + WP; - if (asg::ToolStore::contains<IJetSelector>(name)) { - tool = asg::ToolStore::get<IJetSelector>(name); - } else { - tool = new JetCleaningTool(name); + + IJetSelector* JetMETCPTools::setupJetCleaningTool(const std::string& WP) { + IJetSelector* tool = nullptr; + + std::string name = "JetCleaningTool" + WP; + if (asg::ToolStore::contains<IJetSelector>(name)) { + tool = asg::ToolStore::get<IJetSelector>(name); + } else { + tool = new JetCleaningTool(name); top::check(asg::setProperty(tool, "CutLevel", WP), - "Failed to set CutLevel to " + WP + " for " + name); + "Failed to set CutLevel to " + WP + " for " + name); top::check(asg::setProperty(tool, "DoUgly", false), - "Failed to set DoUgly for " + name); + "Failed to set DoUgly for " + name); + top::check(asg::setProperty(tool, "UseDecorations", true), + "Failed to set UserDecorations for " + name); top::check(tool->initialize(), "Failed to initialize " + name); } - return tool; -} + return tool; + } + ECUtils::IEventCleaningTool* JetMETCPTools::setupJetEventCleaningTool(const std::string& WP, + ToolHandle<IJetSelector> JetCleaningToolHandle) + { + ECUtils::IEventCleaningTool* tool = nullptr; + std::string name = "JetEventCleaningTool" + WP; + if (asg::ToolStore::contains<ECUtils::IEventCleaningTool>(name)) { + tool = asg::ToolStore::get<ECUtils::IEventCleaningTool>(name); + } else { + tool = new ECUtils::EventCleaningTool(name); + top::check(asg::setProperty(tool, "PtCut", std::to_string(m_config->jetPtcut())), + "Failed to set jet pt cut in JetEventCleaningTool"); + top::check(asg::setProperty(tool, "EtaCut", std::to_string(m_config->jetEtacut())), + "Failed to set jet eta cut in JetEventCleaningTool"); + top::check(asg::setProperty(tool, "JvtDecorator", "passJVT"), + "Failed to set JVT property in JetEventCleaningTool"); + std::string OrDecorator = ""; + if (m_config->doLooseEvents()) OrDecorator = "ORToolDecorationLoose"; + else OrDecorator = "ORToolDecoration"; + top::check(asg::setProperty(tool, "OrDecorator", OrDecorator), + "Failed to set jet OR decoration in JetEventCleaningTool"); + top::check(asg::setProperty(tool, "CleaningLevel", WP), + "Failed to set jet WP " + WP + " in JetEventCleaningTool"); + top::check(asg::setProperty(tool, "JetCleaningTool", JetCleaningToolHandle), + "Failed to associate the JetCleaningTool object to JetEventCleaningTool"); + top::check(tool->initialize(), "Failed to initialize " + name); + } + + return tool; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopMuonCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopMuonCPTools.cxx index 6b26f420da28..2f645b9c1180 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopMuonCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopMuonCPTools.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "TopCPTools/TopMuonCPTools.h" @@ -21,241 +21,291 @@ #include "MuonEfficiencyCorrections/MuonEfficiencyScaleFactors.h" namespace top { - -MuonCPTools::MuonCPTools(const std::string& name) : + MuonCPTools::MuonCPTools(const std::string& name) : asg::AsgTool(name) { - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); + declareProperty("config", m_config); - declareProperty( "MuonCalibrationAndSmearingTool" , m_muonCalibrationAndSmearingTool ); - declareProperty( "MuonSelectionTool" , m_muonSelectionTool ); - declareProperty( "MuonSelectionToolLoose" , m_muonSelectionToolLoose ); - declareProperty( "MuonSelectionToolVeryLooseVeto" , m_muonSelectionToolVeryLooseVeto ); + declareProperty("MuonCalibrationPeriodTool", m_muonCalibrationPeriodTool); - declareProperty( "MuonEfficiencyCorrectionsTool" , m_muonEfficiencyCorrectionsTool ); - declareProperty( "MuonEfficiencyCorrectionsToolLoose" , m_muonEfficiencyCorrectionsToolLoose ); - declareProperty( "MuonEfficiencyCorrectionsToolIso" , m_muonEfficiencyCorrectionsToolIso ); - declareProperty( "MuonEfficiencyCorrectionsToolLooseIso" , m_muonEfficiencyCorrectionsToolLooseIso ); -} + declareProperty("MuonSelectionTool", m_muonSelectionTool); + declareProperty("MuonSelectionToolLoose", m_muonSelectionToolLoose); + declareProperty("MuonSelectionToolVeryLooseVeto", m_muonSelectionToolVeryLooseVeto); -StatusCode MuonCPTools::initialize() { - ATH_MSG_INFO("top::MuonCPTools initialize..."); + declareProperty("MuonEfficiencyCorrectionsTool", m_muonEfficiencyCorrectionsTool); + declareProperty("MuonEfficiencyCorrectionsToolLoose", m_muonEfficiencyCorrectionsToolLoose); + declareProperty("MuonEfficiencyCorrectionsToolIso", m_muonEfficiencyCorrectionsToolIso); + declareProperty("MuonEfficiencyCorrectionsToolLooseIso", m_muonEfficiencyCorrectionsToolLooseIso); + + declareProperty("SoftMuonSelectionTool", m_softmuonSelectionTool); + declareProperty("SoftMuonEfficiencyCorrectionsTool", m_softmuonEfficiencyCorrectionsTool); - if (m_config->isTruthDxAOD()) { - ATH_MSG_INFO("top::MuonCPTools: no need to initialise anything on truth DxAOD"); - return StatusCode::SUCCESS; } - if (!m_config->useMuons()) { - ATH_MSG_INFO("top::MuonCPTools: no need to initialise anything since not using muons"); + StatusCode MuonCPTools::initialize() { + ATH_MSG_INFO("top::MuonCPTools initialize..."); + + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::MuonCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; + } + + if (!m_config->useMuons() && !m_config->useSoftMuons()) { + ATH_MSG_INFO("top::MuonCPTools: no need to initialise anything since not using muons"); + return StatusCode::SUCCESS; + } + + if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs + top::check(setupCalibration(), "Failed to setup Muon calibration tools"); + } + if (m_config->isMC()) {// scale-factors are only for MC + top::check(setupScaleFactors(), "Failed to setup Muon scale-factor tools"); + } return StatusCode::SUCCESS; } - if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs - top::check(setupCalibration(), "Failed to setup Muon calibration tools"); - } - if (m_config->isMC()) {// scale-factors are only for MC - top::check(setupScaleFactors(), "Failed to setup Muon scale-factor tools"); - } - return StatusCode::SUCCESS; -} - -StatusCode MuonCPTools::setupCalibration() { - ///-- Calibration and smearing --/// - using IMuCalibSmearTool = CP::IMuonCalibrationAndSmearingTool; - const std::string mu_calib_smearing_name = "CP::MuonCalibrationAndSmearingTool"; - if (asg::ToolStore::contains<IMuCalibSmearTool>(mu_calib_smearing_name)) { - m_muonCalibrationAndSmearingTool - = asg::ToolStore::get<IMuCalibSmearTool>(mu_calib_smearing_name); - } else { - IMuCalibSmearTool* muonCalibrationAndSmearingTool - = new CP::MuonCalibrationAndSmearingTool(mu_calib_smearing_name); - top::check(muonCalibrationAndSmearingTool->initialize(), - "Failed to initialize " + mu_calib_smearing_name); - m_muonCalibrationAndSmearingTool = muonCalibrationAndSmearingTool; - } + StatusCode MuonCPTools::setupCalibration() { + ///-- Selection --/// + m_muonSelectionTool = setupMuonSelectionTool("CP::MuonSelectionTool", + m_config->muonQuality(), + m_config->muonEtacut(), + m_config->muonUseMVALowPt(), + m_config->muonUse2stationMuonsHighPt()); + m_muonSelectionToolLoose = setupMuonSelectionTool("CP::MuonSelectionToolLoose", + m_config->muonQualityLoose(), + m_config->muonEtacut(), + m_config->muonUseMVALowPtLoose(), + m_config->muonUse2stationMuonsHighPtLoose()); + // the following is needed to make sure all muons for which d0sig is calculated are at least Loose + m_muonSelectionToolVeryLooseVeto = setupMuonSelectionTool("CP::MuonSelectionToolVeryLooseVeto", + "Loose", + 2.5, + m_config->muonUseMVALowPt(), + m_config->muonUse2stationMuonsHighPt()); + ///-- Calibration and smearing --/// ---> now passing the flags (true/false) to CalibAndSmearingTool + m_muonCalibrationPeriodTool = setupMuonCalibrationAndSmearingTool("CP::MuonCalibrationPeriodTool", + m_config->muonMuonDoExtraSmearingHighPt(), + m_config->muonMuonDoSmearing2stationHighPt()); + //now the soft muon part + if (m_config->useSoftMuons()) { + m_softmuonSelectionTool = setupMuonSelectionTool("CP::SoftMuonSelectionTool", + m_config->softmuonQuality(), + m_config->softmuonEtacut(), + m_config->softmuonUseMVALowPt(), + false); + } - ///-- Selection --/// - m_muonSelectionTool = setupMuonSelectionTool("CP::MuonSelectionTool", - m_config->muonQuality(), - m_config->muonEtacut()); - m_muonSelectionToolLoose = setupMuonSelectionTool("CP::MuonSelectionToolLoose", - m_config->muonQualityLoose(), - m_config->muonEtacut()); - // the following is needed to make sure all muons for which d0sig is calculated are at least Loose - m_muonSelectionToolVeryLooseVeto = setupMuonSelectionTool("CP::MuonSelectionToolVeryLooseVeto", - "Loose", - 2.5); - return StatusCode::SUCCESS; -} - -StatusCode MuonCPTools::setupScaleFactors() { - // Setup muon SF tools - // However if we are running on data- we don't need these, - // so carry on. - if (!m_config->isMC()) return StatusCode::SUCCESS; - /************************************************************ + } + + StatusCode MuonCPTools::setupScaleFactors() { + // Setup muon SF tools + // However if we are running on data- we don't need these, + // so carry on. + if (!m_config->isMC()) return StatusCode::SUCCESS; + + /************************************************************ * * Muon Scale Factors: * muonSF = trigSF*effSF*isoSF*TTVASF * ************************************************************/ - // Muon SF tools now require you to have setup an instance of - // the pileup reweighting tool! - // If we haven't set it up then tell the user this and exit. - if (!m_config->doPileupReweighting()) { - ATH_MSG_ERROR("\nThe Muon SF tools now require that you have" - " previously setup an instance of " - "the pileup reweighting tool.\n\n" - "To do this set the options:\n\n\t" - "PRWLumiCalcFiles\n and \n\tPRWConfigFiles \n\n" - "in your config file."); - return StatusCode::FAILURE; - } - - /************************************************************ + // Muon SF tools now require you to have setup an instance of + // the pileup reweighting tool! + // If we haven't set it up then tell the user this and exit. + if (!m_config->doPileupReweighting()) { + ATH_MSG_ERROR("\nThe Muon SF tools now require that you have" + " previously setup an instance of " + "the pileup reweighting tool.\n\n" + "To do this set the options:\n\n\t" + "PRWLumiCalcFiles\n and \n\tPRWConfigFiles \n\n" + "in your config file."); + return StatusCode::FAILURE; + } + + /************************************************************ * Trigger Scale Factors: * setup trigger SFs for nominal and 'loose' muon WPs * recommendation for EOYE not to pass any isolation to tool * as SFs very similar for all WPs. - ************************************************************/ - - m_muonTriggerScaleFactors_2015 - = setupMuonTrigSFTool("CP::MuonTriggerScaleFactors_2015", - m_config->muonQuality(), "2015"); - m_muonTriggerScaleFactorsLoose_2015 - = setupMuonTrigSFTool("CP::MuonTriggerScaleFactorsLoose_2015", - m_config->muonQualityLoose(), "2015"); - m_muonTriggerScaleFactors_2016 - = setupMuonTrigSFTool("CP::MuonTriggerScaleFactors_2016", - m_config->muonQuality(), "2016"); - m_muonTriggerScaleFactorsLoose_2016 - = setupMuonTrigSFTool("CP::MuonTriggerScaleFactorsLoose_2016", - m_config->muonQualityLoose(), "2016"); - - - /************************************************************ + ************************************************************/ + + // In R21 now, we only need one instance of the tool + // and do not need to set the year as it is handled + // internally with PRW tool + m_muonTriggerScaleFactors_R21 + = setupMuonTrigSFTool("CP::MuonTriggerScaleFactors_R21", + m_config->muonQuality()); + m_muonTriggerScaleFactorsLoose_R21 + = setupMuonTrigSFTool("CP::MuonTriggerScaleFactorsLoose_R21", + m_config->muonQualityLoose()); + + /************************************************************ * Efficiency Scale Factors: - * setup muon efficiency SFs for the nominal and + * setup muon efficiency SFs for the nominal and * 'loose' muon WPs. - ************************************************************/ - m_muonEfficiencyCorrectionsTool - = setupMuonSFTool("CP::MuonEfficiencyScaleFactorsTool", - m_config->muonQuality()); - - m_muonEfficiencyCorrectionsToolLoose - = setupMuonSFTool("CP::MuonEfficiencyScaleFactorsToolLoose", - m_config->muonQualityLoose()); - - /************************************************************ - * Isolation Scale Factors: - * setup muon isolation SFs for the nominal and 'loose' + ************************************************************/ + + //if !Use2stationMuonsHighPt, HighPt -> HighPt3Layers + //if UseMVALowPt, LowPt -> LowPtMVA + std::string muonQuality_name = m_config->muonQuality(); + if (m_config->muonQuality() == "HighPt" && !(m_config->muonUse2stationMuonsHighPt()) ) muonQuality_name = "HighPt3Layers"; + if (m_config->muonQuality() == "LowPt" && m_config->muonUseMVALowPt()) muonQuality_name = "LowPtMVA"; + m_muonEfficiencyCorrectionsTool + = setupMuonSFTool("CP::MuonEfficiencyScaleFactorsTool", + muonQuality_name); + + std::string muonQualityLoose_name = m_config->muonQualityLoose(); + if (m_config->muonQualityLoose() == "HighPt" && !(m_config->muonUse2stationMuonsHighPtLoose()) ) muonQualityLoose_name = "HighPt3Layers"; + if (m_config->muonQualityLoose() == "LowPt" && m_config->muonUseMVALowPtLoose()) muonQualityLoose_name = "LowPtMVA"; + m_muonEfficiencyCorrectionsToolLoose + = setupMuonSFTool("CP::MuonEfficiencyScaleFactorsToolLoose", + muonQualityLoose_name); + + //now the soft muon part + std::string softmuonQuality_name = m_config->softmuonQuality(); + if (m_config->softmuonQuality() == "LowPt" && m_config->softmuonUseMVALowPt()) softmuonQuality_name = "LowPtMVA"; + if (m_config->useSoftMuons()) { + m_softmuonEfficiencyCorrectionsTool + = setupMuonSFTool("CP::SoftMuonEfficiencyScaleFactorsTool", + softmuonQuality_name); + } + + /************************************************************ + * Isolation Scale Factors: + * setup muon isolation SFs for the nominal and 'loose' * muons * * Note: if isolation WP is None, then don't setup the tool ************************************************************/ - // If we don't want isolation then we don't need the tool - if (m_config->muonIsolation() != "None") { - // Add iso as a suffix (see above for consistency between tools :) ) - std::string muon_isolation = m_config->muonIsolation(); - muon_isolation += "Iso"; - m_muonEfficiencyCorrectionsToolIso - = setupMuonSFTool("CP::MuonEfficiencyScaleFactorsToolIso", + // If we don't want isolation then we don't need the tool + if (m_config->muonIsolationSF() != "None") { + // Add iso as a suffix (see above for consistency between tools :) ) + std::string muon_isolation = m_config->muonIsolationSF() + "Iso"; + m_muonEfficiencyCorrectionsToolIso = + setupMuonSFTool("CP::MuonEfficiencyScaleFactorsToolIso", muon_isolation); - } - - // Do we have isolation on our loose muons? If not no need for the tool... - if (m_config->muonIsolationLoose() != "None") { - // Add iso as a suffix (see above for consistency between tools :) ) - // Note: now loose isolation - std::string muon_isolation = m_config->muonIsolationLoose(); - muon_isolation += "Iso"; - m_muonEfficiencyCorrectionsToolLooseIso = - setupMuonSFTool("CP::MuonEfficiencyScaleFactorsToolLooseIso", - muon_isolation); - } + } + + // Do we have isolation on our loose muons? If not no need for the tool... + if (m_config->muonIsolationSFLoose() != "None") { + // Add iso as a suffix (see above for consistency between tools :) ) + std::string muon_isolation = m_config->muonIsolationSFLoose() + "Iso"; + m_muonEfficiencyCorrectionsToolLooseIso = + setupMuonSFTool("CP::MuonEfficiencyScaleFactorsToolLooseIso", + muon_isolation); + } - /************************************************************ + /************************************************************ * Muon TTVA SF: * Track-to-vertex association. This depends on whether or * not we apply the tracking groups recommended impact * parameter cuts to associate muon to vertex. ************************************************************/ - m_muonEfficiencyCorrectionsToolTTVA - = setupMuonSFTool("CP::MuonEfficiencyScaleFactorsToolTTVA", - "TTVA"); - - return StatusCode::SUCCESS; -} - -CP::IMuonSelectionTool* -MuonCPTools::setupMuonSelectionTool(const std::string& name, const std::string& quality, double max_eta) { - std::map<std::string, int> muon_quality_map = { - {"Tight" , 0}, {"Medium", 1}, {"Loose", 2}, {"VeryLoose", 3}}; - int qual_int; - try { - qual_int = muon_quality_map.at(quality); - } catch (const std::out_of_range& oor_exc) { - ATH_MSG_ERROR("\n Invalid muon quality (" - + quality + ") for " + name - + ". Valid options are: " - " \n\t- Tight" - " \n\t- Medium" - " \n\t- Loose" - " \n\t- VeryLoose"); - throw; // Re-throw + m_muonEfficiencyCorrectionsToolTTVA + = setupMuonSFTool("CP::MuonEfficiencyScaleFactorsToolTTVA", + "TTVA"); + + // WARNING - The PromptLeptonIsolation scale factors are only derived with respect to the loose PID + // - Hence we need to fail if this has occured + if ((m_config->muonQuality() != "Loose" && m_config->muonIsolationSF() == "PromptLepton") + || (m_config->muonQualityLoose() != "Loose" && m_config->muonIsolationSFLoose() == "PromptLepton")) { + ATH_MSG_ERROR( + "Cannot use PromptLeptonIsolation on muons without using Loose quality - Scale factors are not available"); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; } - CP::IMuonSelectionTool* tool = nullptr; - if (asg::ToolStore::contains<CP::IMuonSelectionTool>(name)) { - tool = asg::ToolStore::get<CP::IMuonSelectionTool>(name); - } else { - tool = new CP::MuonSelectionTool(name); - top::check(asg::setProperty(tool, "MuQuality", qual_int), - "Failed to set MuQuality for " + name); - top::check(asg::setProperty(tool, "MaxEta", max_eta), - "Failed to set MaxEta for " + name); - top::check(tool->initialize(), "Failed to initialize " + name); + CP::IMuonSelectionTool* + MuonCPTools::setupMuonSelectionTool(const std::string& name, const std::string& quality, double max_eta, const bool& useMVALowPt, const bool& use2stationMuonsHighPt) { + std::map<std::string, int> muon_quality_map = { + {"Tight", 0}, {"Medium", 1}, {"Loose", 2}, {"VeryLoose", 3}, {"HighPt", 4}, {"LowPt", 5} + }; + int qual_int; + try { + qual_int = muon_quality_map.at(quality); + } catch (const std::out_of_range& oor_exc) { + ATH_MSG_ERROR("\n Invalid muon quality (" + + quality + ") for " + name + + ". Valid options are: " + " \n\t- Tight" + " \n\t- Medium" + " \n\t- Loose" + " \n\t- VeryLoose" + " \n\t- HighPt" + " \n\t- LowPt"); + throw; // Re-throw + } + + CP::IMuonSelectionTool* tool = nullptr; + if (asg::ToolStore::contains<CP::IMuonSelectionTool>(name)) { + tool = asg::ToolStore::get<CP::IMuonSelectionTool>(name); + } else { + tool = new CP::MuonSelectionTool(name); + top::check(asg::setProperty(tool, "MuQuality", qual_int), + "Failed to set MuQuality for " + name); + top::check(asg::setProperty(tool, "MaxEta", max_eta), + "Failed to set MaxEta for " + name); + top::check(asg::setProperty(tool, "UseMVALowPt", useMVALowPt), + "Failed to set UseMVALowPt for " + name + " tool"); + top::check(asg::setProperty(tool, "Use2stationMuonsHighPt", use2stationMuonsHighPt), + "Failed to set Use2stationMuonsHighPt for " + name + " tool"); + top::check(tool->initialize(), "Failed to initialize " + name); + } + return tool; } - return tool; -} - - -CP::IMuonTriggerScaleFactors* -MuonCPTools::setupMuonTrigSFTool(const std::string& name, const std::string& quality, const std::string& year) { - CP::IMuonTriggerScaleFactors* tool = nullptr; - if (asg::ToolStore::contains<CP::IMuonTriggerScaleFactors>(name)) { - tool = asg::ToolStore::get<CP::IMuonTriggerScaleFactors>(name); - } else { - tool = new CP::MuonTriggerScaleFactors(name); - top::check(asg::setProperty(tool, "MuonQuality", quality), - "Failed to set MuonQuality for " + name); - top::check(asg::setProperty(tool, "Year", year), - "Failed to set Year for " + name); - std::string MC_version = "mc15c"; - top::check(asg::setProperty(tool, "MC", MC_version), - "Failed to set MC for " + name); - top::check(tool->initialize(), "Failed to init. " + name); + + CP::IMuonTriggerScaleFactors* + MuonCPTools::setupMuonTrigSFTool(const std::string& name, const std::string& quality) { + CP::IMuonTriggerScaleFactors* tool = nullptr; + if (asg::ToolStore::contains<CP::IMuonTriggerScaleFactors>(name)) { + tool = asg::ToolStore::get<CP::IMuonTriggerScaleFactors>(name); + } else { + tool = new CP::MuonTriggerScaleFactors(name); + top::check(asg::setProperty(tool, "MuonQuality", quality), + "Failed to set MuonQuality for " + name); + top::check(asg::setProperty(tool, "AllowZeroSF", true), + "Failed to set AllowZeroSF for " + name); + top::check(tool->initialize(), "Failed to init. " + name); + } + return tool; } - return tool; -} - - -CP::IMuonEfficiencyScaleFactors* -MuonCPTools::setupMuonSFTool(const std::string& name, const std::string& WP) { - CP::IMuonEfficiencyScaleFactors* tool = nullptr; - if (asg::ToolStore::contains<CP::IMuonEfficiencyScaleFactors>(name)) { - tool = asg::ToolStore::get<CP::MuonEfficiencyScaleFactors>(name); - } else { - tool = new CP::MuonEfficiencyScaleFactors(name); - top::check(asg::setProperty(tool, "WorkingPoint", WP), - "Failed to set WP for " + name + " tool"); - top::check(tool->initialize(), - "Failed to set initialize " + name); + + CP::IMuonEfficiencyScaleFactors* + MuonCPTools::setupMuonSFTool(const std::string& name, const std::string& WP) { + CP::IMuonEfficiencyScaleFactors* tool = nullptr; + if (asg::ToolStore::contains<CP::IMuonEfficiencyScaleFactors>(name)) { + tool = asg::ToolStore::get<CP::MuonEfficiencyScaleFactors>(name); + } else { + tool = new CP::MuonEfficiencyScaleFactors(name); + top::check(asg::setProperty(tool, "WorkingPoint", WP), + "Failed to set WP for " + name + " tool"); + top::check(asg::setProperty(tool, "CloseJetDRDecorator", "dRMuJet_AT_usingWeirdNameToAvoidUsingOnTheFlyCalculation"), + "Failed to set WP for " + name + " tool"); //in this way we'll only read the dR(mu,jet) from the derivation, IF the variable is there, but we'll not use on-the-fly calculation, which is tricky in AT + top::check(tool->initialize(), + "Failed to set initialize " + name); + } + return tool; } - return tool; -} + + CP::IMuonCalibrationAndSmearingTool* + MuonCPTools::setupMuonCalibrationAndSmearingTool(const std::string& name, const bool& doExtraSmearingHighPt, const bool& do2StationsHighPt) { + CP::IMuonCalibrationAndSmearingTool* tool = nullptr; + if (asg::ToolStore::contains<CP::IMuonCalibrationAndSmearingTool>(name)) { + tool = asg::ToolStore::get<CP::IMuonCalibrationAndSmearingTool>(name); + } else { + tool = new CP::MuonCalibrationPeriodTool(name); + + top::check(asg::setProperty(tool, "doExtraSmearing", doExtraSmearingHighPt), + "Failed to set doExtraSmearing for " + name + " tool"); + top::check(asg::setProperty(tool, "do2StationsHighPt", do2StationsHighPt), + "Failed to set do2StationsHighPt for " + name + " tool"); + top::check(tool->initialize(), + "Failed to set initialize " + name); + } + return tool; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopOtherCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopOtherCPTools.cxx index f90263bece1f..f207c57a6e1a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopOtherCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopOtherCPTools.cxx @@ -1,11 +1,12 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopOtherCPTools.h" #include <map> #include <string> +#include <cstdio> // Top includes #include "TopConfiguration/TopConfig.h" @@ -20,128 +21,202 @@ // Pileup Reweighting include(s): #include "PileupReweighting/PileupReweightingTool.h" -namespace top { +// PMG include(s): +#include "PMGTools/PMGTruthWeightTool.h" -OtherCPTools::OtherCPTools(const std::string& name) : +namespace top { + OtherCPTools::OtherCPTools(const std::string& name) : asg::AsgTool(name) { - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); - - declareProperty( "GRLTool" , m_grlTool ); -} - -StatusCode OtherCPTools::initialize() { - ATH_MSG_INFO("top::OtherCPTools initialize..."); - - if (!m_config->isMC() || m_config->PileupUseGRLTool()) - top::check(setupGRL(), "Failed to setup GRL tool"); - - if (m_config->doPileupReweighting()) - top::check(setupPileupReweighting(), "Failed to setup pile-up reweighting"); - - if (m_config->isMC()) - top::check(setupPMGTools(), "Failed to setup PMG tools"); - - return StatusCode::SUCCESS; -} - -StatusCode OtherCPTools::setupGRL() { - using IGRLTool = IGoodRunsListSelectionTool; - const std::string grl_tool_name = "GoodRunsListSelectionTool"; - if (asg::ToolStore::contains<IGRLTool>(grl_tool_name)) { - m_grlTool = asg::ToolStore::get<IGRLTool>(grl_tool_name); - } else { - if (!m_config->grlFile().size()) { - // do not configure GRL tool - std::cout << "No GRL files provided. " - "Will NOT setup GoodRunsListSelectionTool." << std::endl; - return StatusCode::SUCCESS; - } - - IGRLTool* grlTool = new GoodRunsListSelectionTool(grl_tool_name); - std::vector<std::string> names = {}; - std::string grlDir = m_config->grlDir(); - if (grlDir.size()) grlDir += "/"; - for (const std::string& grl : m_config->grlFile()) { - names.push_back(PathResolverFindCalibFile(grlDir + grl)); - } - - top::check(asg::setProperty(grlTool, "GoodRunsListVec", names), - "GRLSelector failed to set GRL"); - top::check( grlTool->initialize() , - "Failed to initialize GRLSelectionTool" ); - m_grlTool = grlTool; + declareProperty("config", m_config); + + declareProperty("GRLTool", m_grlTool); } - return StatusCode::SUCCESS; -} - -StatusCode OtherCPTools::setupPileupReweighting() { - const std::string prw_tool_name = "CP::PileupReweightingTool"; - if (asg::ToolStore::contains<CP::IPileupReweightingTool>(prw_tool_name)) { - m_pileupReweightingTool = asg::ToolStore::get<CP::IPileupReweightingTool>(prw_tool_name); - } else { - CP::IPileupReweightingTool* pileupReweightingTool - = new CP::PileupReweightingTool(prw_tool_name); - - std::vector<std::string> pileup_config = m_config->PileupConfig(); - for (std::string& s : pileup_config) - s = PathResolverFindCalibFile(s); - - // now using by default the nominal mc15c definition - the config file is appended to the list provided by the user - ATH_MSG_INFO("Now appending the default pile-up profile mc15c_v2_defaults.NotRecommended.prw.root to list of PRW config files."); - ATH_MSG_INFO("This is required because we can't provide a default channel number anymore."); - pileup_config.push_back(PathResolverFindCalibFile("dev/PileupReweighting/mc15c_v2_defaults.NotRecommended.prw.root")); - - std::vector<std::string> pileup_lumi_calc = m_config->PileupLumiCalc(); - for (std::string& s : pileup_lumi_calc) - s = PathResolverFindCalibFile(s); - - if (m_config->PileupUseGRLTool()) - top::check(asg::setProperty(pileupReweightingTool, "GRLTool", m_grlTool), - "Failed to give GRLtool to pileup reweighting tool"); - - // Config file is not needed on Data - // see "Just random run numbers and lumi corrections" - // case in twiki page below - // However, the tool would spit out warnings for Data if we didn't supply ConfigFiles. - top::check(asg::setProperty(pileupReweightingTool, "ConfigFiles", pileup_config), - "Failed to set pileup reweighting config files"); - - top::check(asg::setProperty(pileupReweightingTool, "LumiCalcFiles", pileup_lumi_calc), - "Failed to set pileup reweighting lumicalc files"); - // see [http://cern.ch/go/hx7d] - top::check(asg::setProperty(pileupReweightingTool, "DataScaleFactor", 1/1.09), - "Failed to set pileup reweighting data scale factor"); - top::check(asg::setProperty(pileupReweightingTool, "DataScaleFactorUP", 1.0), - "Failed to set pileup reweighting data scale factor up"); - top::check(asg::setProperty(pileupReweightingTool, "DataScaleFactorDOWN", 1/1.18), - "Failed to set pileup reweighting data scale factor down"); - top::check(pileupReweightingTool->initialize(), - "Failed to initialize pileup reweighting tool"); - - m_pileupReweightingTool = pileupReweightingTool; + + StatusCode OtherCPTools::initialize() { + ATH_MSG_INFO("top::OtherCPTools initialize..."); + + if (!m_config->isMC() || m_config->PileupUseGRLTool()) top::check(setupGRL(), "Failed to setup GRL tool"); + + if (m_config->doPileupReweighting()) top::check(setupPileupReweighting(), "Failed to setup pile-up reweighting"); + + if (m_config->isMC()) top::check(setupPMGTools(), "Failed to setup PMG tools"); + + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} - - -StatusCode OtherCPTools::setupPMGTools() { - // Setup any PMG tools - // Currently only a single tool for reweighting - // Sherpa 2.2 V+jets samples based on the number of truth jets - const std::string name = "PMGSherpa22VJetsWeightTool"; - PMGTools::PMGSherpa22VJetsWeightTool* tool = nullptr; - if (asg::ToolStore::contains<PMGTools::PMGSherpa22VJetsWeightTool>(name)) { - tool = asg::ToolStore::get<PMGTools::PMGSherpa22VJetsWeightTool>(name); - } else { - tool = new PMGTools::PMGSherpa22VJetsWeightTool(name); - top::check(asg::setProperty(tool, "TruthJetContainer", - m_config->sgKeyTruthJets()), - "Failed to set TruthJetContainer to " + name); - top::check(tool->initialize(), "Failed to initialize " + name); + + StatusCode OtherCPTools::setupGRL() { + using IGRLTool = IGoodRunsListSelectionTool; + const std::string grl_tool_name = "GoodRunsListSelectionTool"; + if (asg::ToolStore::contains<IGRLTool>(grl_tool_name)) { + m_grlTool = asg::ToolStore::get<IGRLTool>(grl_tool_name); + } else { + if (!m_config->grlFile().size()) { + // do not configure GRL tool + ATH_MSG_WARNING("No GRL files provided -> Will NOT setup GoodRunsListSelectionTool."); + return StatusCode::SUCCESS; + } + + IGRLTool* grlTool = new GoodRunsListSelectionTool(grl_tool_name); + std::vector<std::string> names = {}; + std::string grlDir = m_config->grlDir(); + if (grlDir.size()) grlDir += "/"; + for (const std::string& grl : m_config->grlFile()) { + names.push_back(PathResolverFindCalibFile(grlDir + grl)); + } + + top::check(asg::setProperty(grlTool, "GoodRunsListVec", names), + "GRLSelector failed to set GRL"); + top::check(grlTool->initialize(), + "Failed to initialize GRLSelectionTool"); + m_grlTool = grlTool; + } + return StatusCode::SUCCESS; + } + + StatusCode OtherCPTools::setupPileupReweighting() { + const std::string prw_tool_name = "CP::PileupReweightingTool"; + + if (asg::ToolStore::contains<CP::IPileupReweightingTool>(prw_tool_name)) { + m_pileupReweightingTool = asg::ToolStore::get<CP::IPileupReweightingTool>(prw_tool_name); + } else { + CP::IPileupReweightingTool* pileupReweightingTool + = new CP::PileupReweightingTool(prw_tool_name); + + std::vector<std::string> pileup_config = m_config->PileupConfig(); + for (std::string& s : pileup_config) + s = PathResolverFindCalibFile(s); + + std::vector<std::string> pileup_lumi_calc = m_config->PileupLumiCalc(); + for (std::string& s : pileup_lumi_calc) + s = PathResolverFindCalibFile(s); + + std::vector<std::string> pileup_config_FS = m_config->PileupConfig_FS(); + for (std::string& s : pileup_config_FS) + s = PathResolverFindCalibFile(s); + + std::vector<std::string> pileup_config_AF = m_config->PileupConfig_AF(); + for (std::string& s : pileup_config_AF) + s = PathResolverFindCalibFile(s); + + std::vector<std::string> actual_mu_FS = m_config->PileupActualMu_FS(); + for (std::string& s : actual_mu_FS) + s = PathResolverFindCalibFile(s); + + std::vector<std::string> actual_mu_AF = m_config->PileupActualMu_AF(); + for (std::string& s : actual_mu_AF) + s = PathResolverFindCalibFile(s); + + // New checks - If FS or AF size != 0, then the general option should be empty + if ((pileup_config_AF.size() > 0 || pileup_config_FS.size() > 0) && (pileup_config.size() > 0)) { + ATH_MSG_ERROR("You have used PRWConfigFiles as well as PRWConfigFiles_FS and/or PRWConfigFiles_AF"); + ATH_MSG_ERROR("We do not know how to configure with all these options"); + return StatusCode::FAILURE; + } + + if (m_config->PileupUseGRLTool()) top::check(asg::setProperty(pileupReweightingTool, "GRLTool", m_grlTool), + "Failed to give GRLtool to pileup reweighting tool"); + + // Config file is not needed on Data + // see "Just random run numbers and lumi corrections" + // case in twiki page below + // However, the tool would spit out warnings for Data if we didn't supply ConfigFiles. + if (pileup_config.size() > 0) { + ATH_MSG_INFO("PRW tool is being configured without any FS/AF information"); + top::check(asg::setProperty(pileupReweightingTool, "ConfigFiles", pileup_config), + "Failed to set pileup reweighting config files"); + } else if (m_config->isAFII() && pileup_config_AF.size() > 0) { + // concatenate the config and the actual mu files + std::vector<std::string> final_config_AF = pileup_config_AF; + final_config_AF.insert(final_config_AF.end(), actual_mu_AF.begin(), actual_mu_AF.end()); + ATH_MSG_INFO("This sample is fast sim"); + ATH_MSG_INFO("PRW tool is being configured only with fast simulation (AF) config files"); + top::check(asg::setProperty(pileupReweightingTool, "ConfigFiles", final_config_AF), + "Failed to set pileup reweighting config files"); + } else if (!m_config->isAFII() && pileup_config_FS.size() > 0) { + // concatenate the config and the actual mu files + std::vector<std::string> final_config_FS = pileup_config_FS; + final_config_FS.insert(final_config_FS.end(), actual_mu_FS.begin(), actual_mu_FS.end()); + ATH_MSG_INFO("This sample is full sim"); + ATH_MSG_INFO("PRW tool is being configured only with full simulation (FS) config files"); + top::check(asg::setProperty(pileupReweightingTool, "ConfigFiles", final_config_FS), + "Failed to set pileup reweighting config files"); + } else { + ATH_MSG_ERROR("There are not any PRW config files provided with any allowed options"); + return StatusCode::FAILURE; + } + // data scale-factors, initialised to recommended values + // can also be customised, thanks to PRWCustomScaleFactor option + double SF_nominal = 1.0 / 1.03; + double SF_up = 1.0 / 0.99; + double SF_down = 1.0 / 1.07; + + // if custom data SFs + if (m_config->PileUpCustomScaleFactors().size() != 0) { + SF_nominal = m_config->PileUpCustomScaleFactors()[0]; + SF_up = m_config->PileUpCustomScaleFactors()[1]; + SF_down = m_config->PileUpCustomScaleFactors()[2]; + ATH_MSG_INFO("Using custom Data Scale-Factors for pile-up reweighting"); + std::ostringstream oss; + oss << "Nominal:" << SF_nominal << " up:" << SF_up << " down:" << SF_down << std::endl; + ATH_MSG_INFO(oss.str()); + } + + top::check(asg::setProperty(pileupReweightingTool, "LumiCalcFiles", pileup_lumi_calc), + "Failed to set pileup reweighting lumicalc files"); + // see [http://cern.ch/go/hx7d] + top::check(asg::setProperty(pileupReweightingTool, "DataScaleFactor", static_cast<Float_t>(SF_nominal)), + "Failed to set pileup reweighting data scale factor"); + top::check(asg::setProperty(pileupReweightingTool, "DataScaleFactorUP", SF_up), + "Failed to set pileup reweighting data scale factor up"); + top::check(asg::setProperty(pileupReweightingTool, "DataScaleFactorDOWN", SF_down), + "Failed to set pileup reweighting data scale factor down"); + // Set the unrepresented data tolerence (default is 5% same as the PRW tool) + top::check(asg::setProperty(pileupReweightingTool, "UnrepresentedDataThreshold", m_config->PileupDataTolerance()), + "Failed to set pileup reweighting data tolerance"); + if (m_config->PileupPeriodAssignments().size() > 0) { + // Set the period assignments associated with different running periods + top::check(asg::setProperty(pileupReweightingTool, "PeriodAssignments", m_config->PileupPeriodAssignments()), + "Failed to set pileup reweighting period assignments"); + } + top::check(pileupReweightingTool->initialize(), + "Failed to initialize pileup reweighting tool"); + + m_pileupReweightingTool = pileupReweightingTool; + } + return StatusCode::SUCCESS; } - m_pmg_sherpa22_vjets_tool = tool; - return StatusCode::SUCCESS; -} + StatusCode OtherCPTools::setupPMGTools() { + // Setup any PMG tools + + // Sherpa 2.2 V+jets samples based on the number of truth jets + const std::string name = "PMGSherpa22VJetsWeightTool"; + + PMGTools::PMGSherpa22VJetsWeightTool* tool = nullptr; + if (asg::ToolStore::contains<PMGTools::PMGSherpa22VJetsWeightTool>(name)) { + tool = asg::ToolStore::get<PMGTools::PMGSherpa22VJetsWeightTool>(name); + } else { + tool = new PMGTools::PMGSherpa22VJetsWeightTool(name); + top::check(asg::setProperty(tool, "TruthJetContainer", + m_config->sgKeyTruthJets()), + "Failed to set TruthJetContainer to " + name); + top::check(tool->initialize(), "Failed to initialize " + name); + } + m_pmg_sherpa22_vjets_tool = tool; + + // Tool for access truth weights via names + const std::string truthWeightToolName = "PMGTruthWeightTool"; + PMGTools::PMGTruthWeightTool* truthweightTool = new PMGTools::PMGTruthWeightTool(truthWeightToolName); + if (truthweightTool->initialize()) { + m_pmg_weightTool = truthweightTool; + } else { + // delete the tool instance, it is half-initialized at best = broken + // elsewere we won't be able to retrieve a ToolHandle, which indicates to us + // that we cannot rely on it for this MC sample + delete truthweightTool; + ATH_MSG_WARNING("Failed to initialize " << truthWeightToolName << ". Any features depending on PMGTruthWeightTool will not work!"); + } + + return StatusCode::SUCCESS; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopOverlapRemovalCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopOverlapRemovalCPTools.cxx index 706e8b9021d4..fdd41fb4da82 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopOverlapRemovalCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopOverlapRemovalCPTools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopOverlapRemovalCPTools.h" @@ -19,169 +19,286 @@ #include "AssociationUtils/OverlapRemovalTool.h" namespace top { - -OverlapRemovalCPTools::OverlapRemovalCPTools(const std::string& name) : + OverlapRemovalCPTools::OverlapRemovalCPTools(const std::string& name) : asg::AsgTool(name) { - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); -} + declareProperty("config", m_config); + } -StatusCode OverlapRemovalCPTools::initialize() { - ATH_MSG_INFO("top::OverlapRemovalCPTools initialize..."); + StatusCode OverlapRemovalCPTools::initialize() { + ATH_MSG_INFO("top::OverlapRemovalCPTools initialize..."); - if (m_config->isTruthDxAOD()) { - ATH_MSG_INFO("top::OverlapRemovalCPTools: no need to initialise anything on truth DxAOD"); - return StatusCode::SUCCESS; - } + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::OverlapRemovalCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; + } - if (!m_config->makeAllCPTools()) { - ATH_MSG_INFO("top::OverlapRemovalCPTools: no need to initialise for mini-xAOD"); + if (!m_config->makeAllCPTools()) { + ATH_MSG_INFO("top::OverlapRemovalCPTools: no need to initialise for mini-xAOD"); + return StatusCode::SUCCESS; + } + + top::check(setupOverlapRemoval(), "Failed to setup Overlap Removal"); return StatusCode::SUCCESS; } - top::check(setupOverlapRemoval(), "Failed to setup Overlap Removal"); - return StatusCode::SUCCESS; -} - -StatusCode OverlapRemovalCPTools::setupOverlapRemoval() { - // Allowed overlap removal options - std::set<std::string> allowed_OR_procedures = {"recommended", "jetmuApplyRelPt", "harmonized", - "Boosted", "BoostedSlidingDREl", "BoostedSlidingDRMu", "BoostedSlidingDRElMu", "noTauJetOLR"}; - std::string OR_procedure = m_config->overlapRemovalProcedure(); - - // If the requested OR procedure is unknown then fail. - // This is mostly to avoid me writing 'harmonised' by mistake ;) - if (allowed_OR_procedures.find(OR_procedure) - == allowed_OR_procedures.end()) { - ATH_MSG_ERROR(OR_procedure << " is not a valid option.\n" - "Valid options are currently: " - "recommended [default], jetmuApplyRelPt, harmonized, " - "Boosted, BoostedSlidingDREl, BoostedSlidingDRMu, BoostedSlidingDRElMu, noTauJetOLR"); - return StatusCode::FAILURE; - } - - ATH_MSG_INFO("Overlap removal procedure = " << OR_procedure); + StatusCode OverlapRemovalCPTools::setupOverlapRemoval() { + // Allowed overlap removal options + std::set<std::string> allowed_OR_procedures = { + "recommended", "jetmuApplyRelPt", "harmonized", + "Boosted", "BoostedSlidingDREl", "BoostedSlidingDRMu", "BoostedSlidingDRElMu", "noTauJetOLR", "noPhotonMuOR", "noPhotonMuOrJetOR" + }; + std::string OR_procedure = m_config->overlapRemovalProcedure(); + + float overlapRemovalSlidingInnerDRel = m_config->overlapRemovalSlidingInnerDRel(); + float overlapRemovalSlidingInnerDRmu = m_config->overlapRemovalSlidingInnerDRmu(); + + // if this is set, turns OFF ele-jet OR completely (it's taken care of by the electronInJetSubtraction tool) + bool applyElectronInJetSubtraction = m_config->applyElectronInJetSubtraction(); + + // If the requested OR procedure is unknown then fail. + // This is mostly to avoid me writing 'harmonised' by mistake ;) + if (allowed_OR_procedures.find(OR_procedure) + == allowed_OR_procedures.end()) { + ATH_MSG_ERROR(OR_procedure << " is not a valid option.\n" + "Valid options are currently: " + "recommended [default], jetmuApplyRelPt, harmonized, " + "Boosted, BoostedSlidingDREl, BoostedSlidingDRMu, BoostedSlidingDRElMu, noTauJetOLR"); + return StatusCode::FAILURE; + } + + ATH_MSG_INFO("Overlap removal procedure = " << OR_procedure); // ORUtils::ORFlags OR_flags("OverlapRemovalTool", // "passPreORSelection"); - ORUtils::ORFlags OR_flags("OverlapRemovalTool", - "ORToolDecoration"); - - OR_flags.doElectrons = m_config->useElectrons(); - OR_flags.doMuons = m_config->useMuons(); - OR_flags.doJets = m_config->useJets(); - OR_flags.doTaus = m_config->useTaus(); - OR_flags.doPhotons = m_config->usePhotons(); - if (OR_procedure == "Boosted" || - OR_procedure == "BoostedSlidingDREl" || - OR_procedure == "BoostedSlidingDRMu" || - OR_procedure == "BoostedSlidingDRElMu") { - OR_flags.boostedLeptons = true; - } - OR_flags.doFatJets = (m_config->useLargeRJets() && m_config->doLargeJetOverlapRemoval()); - - const float floatMax = std::numeric_limits<float>::max(); - - top::check(ORUtils::recommendedTools(OR_flags, m_ORtoolBox), - "Failed to setup OR Tool box"); - if (OR_procedure == "harmonized") { - if (m_config->useMuons() && m_config->useElectrons()) - top::check(m_ORtoolBox.eleMuORT.setProperty("RemoveCaloMuons", false), - "Failed to set RemoveCaloMuons in eleMuORT"); - if (m_config->useMuons() && m_config->useJets()) { - top::check(m_ORtoolBox.muJetORT.setProperty("MuJetPtRatio", floatMax), - "Failed to set MuJetPtRatio in muJetORT"); - top::check(m_ORtoolBox.muJetORT.setProperty("MuJetTrkPtRatio", floatMax), - "Failed to set MuJetTrkPtRatio in muJetORT"); - top::check(m_ORtoolBox.muJetORT.setProperty("UseGhostAssociation", false), - "Failed to set UseGhostAssociation in muJetORT"); - top::check(m_ORtoolBox.muJetORT.setProperty("InnerDR", 0.4), - "Failed to set InnerDR in muJetORT"); + ORUtils::ORFlags OR_flags("OverlapRemovalTool", + "ORToolDecoration"); + + OR_flags.doElectrons = m_config->useElectrons(); + OR_flags.doMuons = m_config->useMuons(); + OR_flags.doJets = m_config->useJets(); + OR_flags.doTaus = m_config->useTaus(); + OR_flags.doPhotons = m_config->usePhotons(); + if (OR_procedure == "Boosted" || + OR_procedure == "BoostedSlidingDREl" || + OR_procedure == "BoostedSlidingDRMu" || + OR_procedure == "BoostedSlidingDRElMu") { + OR_flags.boostedLeptons = true; } - } - else if (OR_procedure == "jetmuApplyRelPt") { + OR_flags.doFatJets = (m_config->useLargeRJets() && m_config->doLargeJetOverlapRemoval()); + OR_flags.doMuPFJetOR = (m_config->useParticleFlowJets()); + + const float floatMax = std::numeric_limits<float>::max(); + + top::check(ORUtils::recommendedTools(OR_flags, m_ORtoolBox), + "Failed to setup OR Tool box"); + for (auto&& tool : m_ORtoolBox.getOverlapTools()) { + top::check(tool->setProperty("EnableUserPriority", true), + "Failed to set EnableUserPriority"); + } + if (OR_procedure == "harmonized") { + if (m_config->useMuons() && + m_config->useElectrons()) top::check(m_ORtoolBox.eleMuORT.setProperty("RemoveCaloMuons", false), + "Failed to set RemoveCaloMuons in eleMuORT"); + if (m_config->useMuons() && m_config->useJets()) { + top::check(m_ORtoolBox.muJetORT.setProperty("MuJetPtRatio", floatMax), + "Failed to set MuJetPtRatio in muJetORT"); + top::check(m_ORtoolBox.muJetORT.setProperty("MuJetTrkPtRatio", floatMax), + "Failed to set MuJetTrkPtRatio in muJetORT"); + top::check(m_ORtoolBox.muJetORT.setProperty("UseGhostAssociation", false), + "Failed to set UseGhostAssociation in muJetORT"); + top::check(m_ORtoolBox.muJetORT.setProperty("InnerDR", 0.4), + "Failed to set InnerDR in muJetORT"); + } + } else if (OR_procedure == "jetmuApplyRelPt") { top::check(m_ORtoolBox.muJetORT.setProperty("ApplyRelPt", true), - "Failed to set ApplyRelPt in muJetORT"); - } - else if ( OR_procedure == "BoostedSlidingDREl" || - OR_procedure == "BoostedSlidingDRMu" || - OR_procedure == "BoostedSlidingDRElMu") { - if ( m_config->useElectrons() && m_config->useJets() && - (OR_procedure == "BoostedSlidingDREl" || OR_procedure == "BoostedSlidingDRElMu") ) { - top::check(m_ORtoolBox.eleJetORT.setProperty("UseSlidingDR", true), - "Failed to setSliding DR in ElJetORT"); - top::check(m_ORtoolBox.eleJetORT.setProperty("InnerDR", 0.0), - "Failed to setting inner radius equal to 0.0 in EleJetORT"); + "Failed to set ApplyRelPt in muJetORT"); + } else if (OR_procedure == "BoostedSlidingDREl" || + OR_procedure == "BoostedSlidingDRMu" || + OR_procedure == "BoostedSlidingDRElMu") { + if (m_config->useElectrons() && m_config->useJets() && + OR_procedure == "BoostedSlidingDREl") { + top::check(m_ORtoolBox.eleJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in ElJetORT"); + top::check(m_ORtoolBox.eleJetORT.setProperty("InnerDR", overlapRemovalSlidingInnerDRel), + "Failed to setting inner radius equal to SlidingInnerDRel in EleJetORT"); + top::check(m_ORtoolBox.muJetORT.setProperty("UseSlidingDR", false), + "Failed to setSliding DR in MuJetORT"); + } + if (m_config->useMuons() && m_config->useJets() && + OR_procedure == "BoostedSlidingDRMu") { + top::check(m_ORtoolBox.eleJetORT.setProperty("UseSlidingDR", false), + "Failed to setSliding DR in ElJetORT"); + top::check(m_ORtoolBox.muJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in MuJetORT"); + top::check(m_ORtoolBox.muJetORT.setProperty("InnerDR", overlapRemovalSlidingInnerDRmu), + "Failed to setting inner radius equal to SlidingInnerDRmu in MuJetORT"); + } + if (m_config->useElectrons() && m_config->useMuons() && m_config->useJets() && + OR_procedure == "BoostedSlidingDRElMu") { + top::check(m_ORtoolBox.eleJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in ElJetORT"); + top::check(m_ORtoolBox.eleJetORT.setProperty("InnerDR", overlapRemovalSlidingInnerDRel), + "Failed to setting inner radius equal to SlidingInnerDRel in EleJetORT"); + top::check(m_ORtoolBox.muJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in MuJetORT"); + top::check(m_ORtoolBox.muJetORT.setProperty("InnerDR", overlapRemovalSlidingInnerDRmu), + "Failed to setting inner radius equal to SlidingInnerDRmu in MuJetORT"); + } + } else if (OR_procedure == "noTauJetOLR") { + top::check(m_ORtoolBox.tauJetORT.setProperty("DR", 0.0), + "Failed to set DR in TauJetORT to zero"); + } else if (OR_procedure == "noPhotonMuOR") { + top::check(m_ORtoolBox.phoMuORT.setProperty("DR", 0.0), + "Failed to set DR in phoMuonORT to zero"); + } else if (OR_procedure == "noPhotonMuOrJetOR") { + top::check(m_ORtoolBox.phoMuORT.setProperty("DR", 0.0), + "Failed to set DR in phoMuonORT to zero"); + top::check(m_ORtoolBox.phoJetORT.setProperty("DR", 0.0), + "Failed to set DR in phoJetORT to zero"); } - if ( m_config->useMuons() && m_config->useJets() && - (OR_procedure == "BoostedSlidingDRMu" || OR_procedure == "BoostedSlidingDRElMu") ) { - top::check(m_ORtoolBox.muJetORT.setProperty("UseSlidingDR", true), - "Failed to setSliding DR in MuJetORT"); - top::check(m_ORtoolBox.muJetORT.setProperty("InnerDR", 0.0), - "Failed to setting inner radius equal to 0.0 in MuJetORT"); + + if (applyElectronInJetSubtraction) { + top::check(m_ORtoolBox.eleJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in ElJetORT"); + top::check(m_ORtoolBox.eleJetORT.setProperty("InnerDR", 0), + "Failed to setting inner radius equal to SlidingInnerDRel in EleJetORT"); + top::check(m_ORtoolBox.eleJetORT.setProperty("SlidingDRC1", 0), + "Failed to set SlidingDRC1"); + top::check(m_ORtoolBox.eleJetORT.setProperty("SlidingDRC2", 0), + "Failed to set SlidingDRC2"); + top::check(m_ORtoolBox.eleJetORT.setProperty("SlidingDRMaxCone", 0), + "Failed to set SlidingDRMaxCone"); } - } - else if( OR_procedure == "noTauJetOLR"){ - top::check(m_ORtoolBox.tauJetORT.setProperty("DR", 0.0), - "Failed to set DR in TauJetORT to zero"); - } - top::check(m_ORtoolBox.initialize(), - "Failed to initialize overlap removal tools"); - m_overlapRemovalTool = std::move(m_ORtoolBox.masterTool); + + top::check(m_ORtoolBox.initialize(), + "Failed to initialize overlap removal tools"); + m_overlapRemovalTool = std::move(m_ORtoolBox.masterTool); - OR_flags.masterName = "OverlapRemovalToolLoose"; + OR_flags.masterName = "OverlapRemovalToolLoose"; // OR_flags.inputLabel = "passPreORSelectionLoose"; - OR_flags.inputLabel = "ORToolDecorationLoose"; - - top::check(ORUtils::recommendedTools(OR_flags, m_ORtoolBox_Loose), - "Failed to setup OR Tool box"); - if (OR_procedure == "harmonized") { - if (m_config->useMuons() && m_config->useElectrons()) - top::check(m_ORtoolBox_Loose.eleMuORT.setProperty("RemoveCaloMuons", - false), - "Failed to set RemoveCaloMuons in eleMuORT"); - if (m_config->useMuons() && m_config->useJets()) { - top::check(m_ORtoolBox_Loose.muJetORT.setProperty("MuJetPtRatio", floatMax), - "Failed to set MuJetPtRatio in muJetORT"); - top::check(m_ORtoolBox_Loose.muJetORT.setProperty("MuJetTrkPtRatio", floatMax), - "Failed to set MuJetTrkPtRatio in muJetORT"); - top::check(m_ORtoolBox_Loose.muJetORT.setProperty("UseGhostAssociation", false), - "Failed to set UseGhostAssociation in muJetORT"); - top::check(m_ORtoolBox_Loose.muJetORT.setProperty("InnerDR", 0.4), - "Failed to set InnerDR in muJetORT"); + OR_flags.inputLabel = "ORToolDecorationLoose"; + + top::check(ORUtils::recommendedTools(OR_flags, m_ORtoolBox_Loose), + "Failed to setup OR Tool box"); + for (auto&& tool : m_ORtoolBox_Loose.getOverlapTools()) { + top::check(tool->setProperty("EnableUserPriority", true), + "Failed to set EnableUserPriority"); } - } - else if (OR_procedure == "jetmuApplyRelPt") { - top::check(m_ORtoolBox_Loose.muJetORT.setProperty("ApplyRelPt", false), - "Failed to set ApplyRelPt in muJetORT"); - } - else if ( OR_procedure == "BoostedSlidingDREl" || - OR_procedure == "BoostedSlidingDRMu" || - OR_procedure == "BoostedSlidingDRElMu") { - if ( m_config->useElectrons() && m_config->useJets() && - (OR_procedure == "BoostedSlidingDREl" || OR_procedure == "BoostedSlidingDRElMu") ) { + if (OR_procedure == "harmonized") { + if (m_config->useMuons() && m_config->useElectrons()) + top::check(m_ORtoolBox_Loose.eleMuORT.setProperty("RemoveCaloMuons", + false), + "Failed to set RemoveCaloMuons in eleMuORT"); + if (m_config->useMuons() && m_config->useJets()) { + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("MuJetPtRatio", floatMax), + "Failed to set MuJetPtRatio in muJetORT"); + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("MuJetTrkPtRatio", floatMax), + "Failed to set MuJetTrkPtRatio in muJetORT"); + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("UseGhostAssociation", false), + "Failed to set UseGhostAssociation in muJetORT"); + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("InnerDR", 0.4), + "Failed to set InnerDR in muJetORT"); + } + } else if (OR_procedure == "jetmuApplyRelPt") { + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("ApplyRelPt", false), + "Failed to set ApplyRelPt in muJetORT"); + } else if (OR_procedure == "BoostedSlidingDREl" || + OR_procedure == "BoostedSlidingDRMu" || + OR_procedure == "BoostedSlidingDRElMu") { + if (m_config->useElectrons() && m_config->useJets() && + OR_procedure == "BoostedSlidingDREl") { + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in ElJetORT"); + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("InnerDR", overlapRemovalSlidingInnerDRel), + "Failed to setting inner radius equal to SlidingInnerDRel in EleJetORT"); + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("UseSlidingDR", false), + "Failed to setSliding DR in MuJetORT"); + } + if (m_config->useMuons() && m_config->useJets() && + OR_procedure == "BoostedSlidingDRMu") { + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("UseSlidingDR", false), + "Failed to setSliding DR in ElJetORT"); + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in MuJetORT"); + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("InnerDR", overlapRemovalSlidingInnerDRmu), + "Failed to setting inner radius equal to SlidingInnerDRmu in MuJetORT"); + } + if (m_config->useElectrons() && m_config->useMuons() && m_config->useJets() && + OR_procedure == "BoostedSlidingDRElMu") { + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in ElJetORT"); + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("InnerDR", overlapRemovalSlidingInnerDRel), + "Failed to setting inner radius equal to SlidingInnerDRel in EleJetORT"); + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("UseSlidingDR", true), + "Failed to setSliding DR in MuJetORT"); + top::check(m_ORtoolBox_Loose.muJetORT.setProperty("InnerDR", overlapRemovalSlidingInnerDRmu), + "Failed to setting inner radius equal to SlidingInnerDRmu in MuJetORT"); + } + } else if (OR_procedure == "noTauJetOLR") { + top::check(m_ORtoolBox_Loose.tauJetORT.setProperty("DR", 0.0), + "Failed to set DR in TauJetORT to zero"); + } else if (OR_procedure == "noPhotonMuOR") { + top::check(m_ORtoolBox_Loose.phoMuORT.setProperty("DR", 0.0), + "Failed to set DR in phoMuonORT to zero"); + } else if (OR_procedure == "noPhotonMuOrJetOR") { + top::check(m_ORtoolBox_Loose.phoMuORT.setProperty("DR", 0.0), + "Failed to set DR in phoMuonORT to zero"); + top::check(m_ORtoolBox_Loose.phoJetORT.setProperty("DR", 0.0), + "Failed to set DR in phoJetORT to zero"); + } + + if (applyElectronInJetSubtraction) { top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("UseSlidingDR", true), - "Failed to setSliding DR in ElJetORT"); - top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("InnerDR", 0.0), - "Failed to setting inner radius equal to 0.0 in EleJetORT"); + "Failed to setSliding DR in ElJetORT"); + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("InnerDR", 0), + "Failed to setting inner radius equal to SlidingInnerDRel in EleJetORT"); + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("SlidingDRC1", 0), + "Failed to set SlidingDRC1"); + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("SlidingDRC2", 0), + "Failed to set SlidingDRC2"); + top::check(m_ORtoolBox_Loose.eleJetORT.setProperty("SlidingDRMaxCone", 0), + "Failed to set SlidingDRMaxCone"); } - if ( m_config->useMuons() && m_config->useJets() && - (OR_procedure == "BoostedSlidingDRMu" || OR_procedure == "BoostedSlidingDRElMu") ) { - top::check(m_ORtoolBox_Loose.muJetORT.setProperty("UseSlidingDR", true), - "Failed to setSliding DR in MuJetORT"); - top::check(m_ORtoolBox_Loose.muJetORT.setProperty("InnerDR", 0.0), - "Failed to setting inner radius equal to 0.0 in MuJetORT"); + + top::check(m_ORtoolBox_Loose.initialize(), + "Failed to initialize loose overlap removal tools"); + m_overlapRemovalTool_Loose = std::move(m_ORtoolBox_Loose.masterTool); + + ATH_MSG_INFO("Setting up special OR tools for soft muons"); + ORUtils::ORFlags OR_flags_sm_PFjets("OverlapRemovalTool_softMuons_PFjets","ORToolDecoration", "AT_fail_softMuons_OR_PFjets"); + OR_flags_sm_PFjets.doElectrons = false; + OR_flags_sm_PFjets.doMuons = true; + OR_flags_sm_PFjets.doJets = false; + OR_flags_sm_PFjets.doTaus = false; + OR_flags_sm_PFjets.doPhotons = false; + OR_flags_sm_PFjets.boostedLeptons = false; + OR_flags_sm_PFjets.doFatJets = false; + OR_flags_sm_PFjets.doMuPFJetOR = true; + + top::check(ORUtils::recommendedTools(OR_flags_sm_PFjets, m_ORtoolBox_softMuons_PFjets), "Failed to setup OR Tool box for soft muons-PFjets"); + for (auto&& tool : m_ORtoolBox_softMuons_PFjets.getOverlapTools()) { + top::check(tool->setProperty("EnableUserPriority", true), "Failed to set EnableUserPriority"); } + top::check(m_ORtoolBox_softMuons_PFjets.initialize(),"Failed to initialize soft muons overlap removal tools"); + m_overlapRemovalTool_softMuons_PFjets = std::move(m_ORtoolBox_softMuons_PFjets.masterTool); + + ORUtils::ORFlags OR_flags_sm_Alljets("OverlapRemovalTool_softMuons_Alljets","ORToolDecoration", "AT_fail_softMuons_OR_Alljets"); + OR_flags_sm_Alljets.doElectrons = false; + OR_flags_sm_Alljets.doMuons = true; + OR_flags_sm_Alljets.doJets = true; + OR_flags_sm_Alljets.doTaus = false; + OR_flags_sm_Alljets.doPhotons = false; + OR_flags_sm_Alljets.boostedLeptons = false; + OR_flags_sm_Alljets.doFatJets = false; + OR_flags_sm_Alljets.doMuPFJetOR = false; + + top::check(ORUtils::recommendedTools(OR_flags_sm_Alljets, m_ORtoolBox_softMuons_Alljets), "Failed to setup OR Tool box for soft muons-Alljets"); + for (auto&& tool : m_ORtoolBox_softMuons_Alljets.getOverlapTools()) { + top::check(tool->setProperty("EnableUserPriority", true), "Failed to set EnableUserPriority"); + } + top::check(m_ORtoolBox_softMuons_Alljets.initialize(),"Failed to initialize soft muons overlap removal tools"); + m_overlapRemovalTool_softMuons_Alljets = std::move(m_ORtoolBox_softMuons_Alljets.masterTool); + + return StatusCode::SUCCESS; } - else if( OR_procedure == "noTauJetOLR"){ - top::check(m_ORtoolBox_Loose.tauJetORT.setProperty("DR", 0.0), - "Failed to set DR in TauJetORT to zero"); - } - top::check(m_ORtoolBox_Loose.initialize(), - "Failed to initialize loose overlap removal tools"); - m_overlapRemovalTool_Loose = std::move(m_ORtoolBox_Loose.masterTool); - - return StatusCode::SUCCESS; -} - } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTauCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTauCPTools.cxx index 250e78f39100..9244882e6d08 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTauCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTauCPTools.cxx @@ -1,12 +1,9 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopTauCPTools.h" -#include <map> -#include <string> - // Top includes #include "TopConfiguration/TopConfig.h" #include "TopEvent/EventTools.h" @@ -21,40 +18,45 @@ #include "TauAnalysisTools/TauTruthMatchingTool.h" #include "TauAnalysisTools/Enums.h" +// c++ includes +#include <map> +#include <memory> +#include <string> + namespace top { + TauCPTools::TauCPTools(const std::string& name) : + asg::AsgTool(name), + m_pileupReweightingTool("CP::PileupReweightingTool") { + declareProperty("config", m_config); -TauCPTools::TauCPTools(const std::string& name) : - asg::AsgTool(name) { - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); + declareProperty("TauSmearingTool", m_tauSmearingTool); + declareProperty("TauTruthMatchingTool", m_truthMatchingTool); + } - declareProperty( "TauSmearingTool" , m_tauSmearingTool ); -} + StatusCode TauCPTools::initialize() { + ATH_MSG_INFO("top::TauCPTools initialize..."); -StatusCode TauCPTools::initialize() { - ATH_MSG_INFO("top::TauCPTools initialize..."); + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::TauCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; + } - if (m_config->isTruthDxAOD()) { - ATH_MSG_INFO("top::TauCPTools: no need to initialise anything on truth DxAOD"); - return StatusCode::SUCCESS; - } + if (!m_config->useTaus()) { + ATH_MSG_INFO("top::TauCPTools: no need to initialise anything since not using taus"); + return StatusCode::SUCCESS; + } - if (!m_config->useTaus()) { - ATH_MSG_INFO("top::TauCPTools: no need to initialise anything since not using taus"); + if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs + top::check(setupCalibration(), "Failed to setup Tau calibration tools"); + } + if (m_config->isMC()) {// scale-factors are only for MC + top::check(setupScaleFactors(), "Failed to setup Tau scale-factor tools"); + } return StatusCode::SUCCESS; } - if (m_config->makeAllCPTools()) {// skiping calibrations on mini-xAODs - top::check(setupCalibration(), "Failed to setup Tau calibration tools"); - } - if (m_config->isMC()) {// scale-factors are only for MC - top::check(setupScaleFactors(), "Failed to setup Tau scale-factor tools"); - } - return StatusCode::SUCCESS; -} - -StatusCode TauCPTools::setupCalibration() { - /************************************************************ + StatusCode TauCPTools::setupCalibration() { + /************************************************************ * * Setup the tools needed for Tau Analysis * ---------------------------------------- @@ -69,233 +71,290 @@ StatusCode TauCPTools::setupCalibration() { * ************************************************************/ - //============================================================ - // Convert tau jet IDWP string to int - // see: [http://cern.ch/go/z6cq] - // Updated: using enums from TauAnalysisTools package - //============================================================ - - auto tau_JetIDWP_to_enum = [](const std::string& s) { - if (s == "None") return TauAnalysisTools::JETIDNONE; - if (s == "Loose") return TauAnalysisTools::JETIDBDTLOOSE; - if (s == "Medium") return TauAnalysisTools::JETIDBDTMEDIUM; - if (s == "Tight") return TauAnalysisTools::JETIDBDTTIGHT; - if (s == "LooseNotMedium") return TauAnalysisTools::JETIDBDTLOOSENOTMEDIUM; - if (s == "LooseNotTight") return TauAnalysisTools::JETIDBDTLOOSENOTTIGHT; - if (s == "MediumNotTight") return TauAnalysisTools::JETIDBDTMEDIUMNOTTIGHT; - if (s == "NotLoose") return TauAnalysisTools::JETIDBDTNOTLOOSE; - - // If we haven't found the correct WP, then return -1 - return TauAnalysisTools::JETIDNONEUNCONFIGURED; - }; - - // convert taujetIDWP from string to int and check it's valid - int tauJetIDWP = tau_JetIDWP_to_enum(m_config->tauJetIDWP()); - top::check(tauJetIDWP >= 0, m_config->tauJetIDWP() + " is not a valid tau WP"); - - // convert taujetIDWPLoose from string to int and check it's valid - int tauJetIDWPLoose = tau_JetIDWP_to_enum(m_config->tauJetIDWPLoose()); - top::check(tauJetIDWPLoose >= 0, m_config->tauJetIDWPLoose() + " is not a valid tau WP"); - - auto tau_EleBDTWP_to_enum = [](const std::string& s) { - if (s == "None") return TauAnalysisTools::ELEIDNONE; - if (s == "Loose") return TauAnalysisTools::ELEIDBDTLOOSE; - if (s == "Medium") return TauAnalysisTools::ELEIDBDTMEDIUM; - if (s == "Tight") return TauAnalysisTools::ELEIDBDTTIGHT; - - // If we haven't found the correct WP, then return -1 - return TauAnalysisTools::ELEIDNONEUNCONFIGURED; - }; - - // convert tauEleBDTWP from string to int and check it's valid - int tauEleBDTWP = tau_EleBDTWP_to_enum(m_config->tauEleBDTWP()); - top::check(tauEleBDTWP >= 0, m_config->tauEleBDTWP() + " is not a valid tau WP"); - - // convert tauEleBDTWPLoose from string to int and check it's valid - int tauEleBDTWPLoose = tau_EleBDTWP_to_enum(m_config->tauEleBDTWPLoose()); - top::check(tauEleBDTWPLoose >= 0, m_config->tauEleBDTWPLoose() + " is not a valid tau WP"); - - const std::vector<float> absEtaRegion = {0., 1.37, 1.37, 1.52, 1.52, 2.5}; - const double absCharge = 1.; - const std::vector<size_t> nTracks = {1,3}; - - //============================================================ - // PathResolve tau config files. If set to default then - // set to empty string. - //============================================================ - - std::string tauJetConfigFile = m_config->tauJetConfigFile(); - if (tauJetConfigFile != "Default") - tauJetConfigFile = PathResolverFindCalibFile(tauJetConfigFile); - else - tauJetConfigFile.clear(); - std::string tauJetConfigFileLoose = m_config->tauJetConfigFileLoose(); - if (tauJetConfigFileLoose != "Default") - tauJetConfigFileLoose = PathResolverFindCalibFile(tauJetConfigFileLoose); - else - tauJetConfigFileLoose.clear(); - - // bitmap in case not using the config files - //WARNING: if we add more configurable cuts, they need to be added in this list - // a priori we alway apply these cuts below - int iSelectionCuts = 0; - iSelectionCuts |= TauAnalysisTools::CutPt; - iSelectionCuts |= TauAnalysisTools::CutAbsEta; - iSelectionCuts |= TauAnalysisTools::CutAbsCharge; - iSelectionCuts |= TauAnalysisTools::CutNTrack; - iSelectionCuts |= TauAnalysisTools::CutJetIDWP; - iSelectionCuts |= TauAnalysisTools::CutEleBDTWP; - - //WARNING the CutEleOLR is special, and has to be added only in the map if needed - int iSelectionCutsLoose = iSelectionCuts; - if (m_config->tauEleOLR()) iSelectionCuts |= TauAnalysisTools::CutEleOLR; - if (m_config->tauEleOLRLoose()) iSelectionCutsLoose |= TauAnalysisTools::CutEleOLR; - - //============================================================ - // Nominal Tau Selection - //============================================================ - - - // Alias long tool names - using ITauSelTool = TauAnalysisTools::ITauSelectionTool; - using ITauEffCorrTool = TauAnalysisTools::ITauEfficiencyCorrectionsTool; - // Names of tools here for a little clarity - std::string tauSelName = "TauAnalysisTools::TauSelectionTool"; - std::string tauEffCorrName = "TauAnalysisTools::TauEfficiencyCorrectionsTool"; - - ///-- Setup the tau selection tool --/// - if (asg::ToolStore::contains<ITauSelTool>(tauSelName)) { - m_tauSelectionTool = asg::ToolStore::get<ITauSelTool>(tauSelName); - } else { - ITauSelTool* tauSelectionTool = new TauAnalysisTools::TauSelectionTool(tauSelName); - if (!tauJetConfigFile.empty()) { - top::check(asg::setProperty(tauSelectionTool, "ConfigPath",tauJetConfigFile), - "Failed to set tau selection tool configuration path"); - top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::DEBUG), - "Failed to set tau OutputLevel"); - } else { - // set the ConfigPath to empty value is no file was provided (otherwise it creates conflicts) - top::check(asg::setProperty(tauSelectionTool, "ConfigPath", ""), - "Failed to set tau selection tool configuration path"); - top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::DEBUG), - "Failed to set tau OutputLevel"); - //WARNING: if we add more configurable cuts, they need to be added in the iSelectionCuts (see above) - top::check(asg::setProperty(tauSelectionTool, "SelectionCuts", iSelectionCuts), - "Failed to set tau SelectionCuts"); - top::check(asg::setProperty(tauSelectionTool, "PtMin", static_cast<double>(m_config->tauPtcut()/1e3)), - "Failed to set tau pT cut"); - top::check(asg::setProperty(tauSelectionTool, "AbsEtaRegion", absEtaRegion), - "Failed to set tau AbsEtaRegion"); - top::check(asg::setProperty(tauSelectionTool, "AbsCharge", absCharge), - "Failed to set tau AbsCharge"); - top::check(asg::setProperty(tauSelectionTool, "NTracks", nTracks), - "Failed to set tau NTracks"); - top::check(asg::setProperty(tauSelectionTool, "JetIDWP", tauJetIDWP), - "Failed to set tau JetIDWP"); - top::check(asg::setProperty(tauSelectionTool, "EleBDTWP", tauEleBDTWP), - "Failed to set tau EleBDTWP"); - top::check(asg::setProperty(tauSelectionTool, "EleOLR", m_config->tauEleOLR()), - "Failed to set tau-electron overlap removal in tau selection tool"); - } - top::check(tauSelectionTool->initialize(), "Failed to initialize tauSelectionTool"); - m_tauSelectionTool = tauSelectionTool; + //============================================================ + // Convert tau jet IDWP string to int + // see: [http://cern.ch/go/z6cq] + // Updated: using enums from TauAnalysisTools package + //============================================================ + + auto tau_JetIDWP_to_enum = [](const std::string& s) { + if (s == "None") return TauAnalysisTools::JETIDNONE; + + if (s == "Loose") return TauAnalysisTools::JETIDBDTLOOSE; + + if (s == "Medium") return TauAnalysisTools::JETIDBDTMEDIUM; + + if (s == "Tight") return TauAnalysisTools::JETIDBDTTIGHT; + + if (s == "LooseNotMedium") return TauAnalysisTools::JETIDBDTLOOSENOTMEDIUM; + + if (s == "LooseNotTight") return TauAnalysisTools::JETIDBDTLOOSENOTTIGHT; + + if (s == "MediumNotTight") return TauAnalysisTools::JETIDBDTMEDIUMNOTTIGHT; + + if (s == "NotLoose") return TauAnalysisTools::JETIDBDTNOTLOOSE; + + if (s == "RNNLoose") return TauAnalysisTools::JETIDRNNLOOSE; + + if (s == "RNNMedium") return TauAnalysisTools::JETIDRNNMEDIUM; + + if (s == "RNNTight") return TauAnalysisTools::JETIDRNNTIGHT; + + // If we haven't found the correct WP, then return -1 + return TauAnalysisTools::JETIDNONEUNCONFIGURED; + }; + + // convert taujetIDWP from string to int and check it's valid + int tauJetIDWP = tau_JetIDWP_to_enum(m_config->tauJetIDWP()); - ///-- Setup the EfficiencyCorrectionsTool while seting up the selection tool --/// - if (asg::ToolStore::contains<ITauEffCorrTool>(tauEffCorrName)) { - m_tauEffCorrTool = asg::ToolStore::get<ITauEffCorrTool>(tauEffCorrName); + top::check(tauJetIDWP >= 0, m_config->tauJetIDWP() + " is not a valid tau WP"); + + // convert taujetIDWPLoose from string to int and check it's valid + int tauJetIDWPLoose = tau_JetIDWP_to_enum(m_config->tauJetIDWPLoose()); + top::check(tauJetIDWPLoose >= 0, m_config->tauJetIDWPLoose() + " is not a valid tau WP"); + + auto tau_EleBDTWP_to_enum = [](const std::string& s) { + if (s == "None") return TauAnalysisTools::ELEIDNONE; + + if (s == "Loose") return TauAnalysisTools::ELEIDBDTLOOSE; + + if (s == "Medium") return TauAnalysisTools::ELEIDBDTMEDIUM; + + if (s == "Tight") return TauAnalysisTools::ELEIDBDTTIGHT; + + // If we haven't found the correct WP, then return 0 + return TauAnalysisTools::ELEIDNONEUNCONFIGURED; + }; + + // convert tauEleBDTWP from string to int and check it's valid + int tauEleBDTWP = tau_EleBDTWP_to_enum(m_config->tauEleBDTWP()); + top::check(tauEleBDTWP >= 0, m_config->tauEleBDTWP() + " is not a valid tau WP"); + + // convert tauEleBDTWPLoose from string to int and check it's valid + int tauEleBDTWPLoose = tau_EleBDTWP_to_enum(m_config->tauEleBDTWPLoose()); + top::check(tauEleBDTWPLoose >= 0, m_config->tauEleBDTWPLoose() + " is not a valid tau WP"); + + const double absCharge = 1.; + const std::vector<size_t> nTracks = { + 1, 3 + }; + + //============================================================ + // PathResolve tau config files. If set to default then + // set to empty string. + //============================================================ + + std::string tauJetConfigFile = m_config->tauJetConfigFile(); + if (tauJetConfigFile != "Default") tauJetConfigFile = PathResolverFindCalibFile(tauJetConfigFile); + else tauJetConfigFile.clear(); + std::string tauJetConfigFileLoose = m_config->tauJetConfigFileLoose(); + if (tauJetConfigFileLoose != "Default") tauJetConfigFileLoose = PathResolverFindCalibFile(tauJetConfigFileLoose); + else tauJetConfigFileLoose.clear(); + + // bitmap in case not using the config files + //WARNING: if we add more configurable cuts, they need to be added in this list + // a priori we alway apply these cuts below + int iSelectionCuts = 0; + iSelectionCuts |= TauAnalysisTools::CutPt; + iSelectionCuts |= TauAnalysisTools::CutAbsEta; + iSelectionCuts |= TauAnalysisTools::CutAbsCharge; + iSelectionCuts |= TauAnalysisTools::CutNTrack; + iSelectionCuts |= TauAnalysisTools::CutJetIDWP; + iSelectionCuts |= TauAnalysisTools::CutEleBDTWP; + + //WARNING the CutEleOLR is special, and has to be added only in the map if needed + int iSelectionCutsLoose = iSelectionCuts; + if (m_config->tauEleOLR()) iSelectionCuts |= TauAnalysisTools::CutEleOLR; + if (m_config->tauEleOLRLoose()) iSelectionCutsLoose |= TauAnalysisTools::CutEleOLR; + + //add warning for special case of using EleIDBDT AND ELEOLR outdated->can just use oldBDT + + if (m_config->tauEleOLR()&& tauEleBDTWP >=2){ + ATH_MSG_WARNING("Using TauELeOLR is just usable together with the old EleBDT options" + "use OldLoose or OldMedium if you really want to use both (outdated)"); + } + if (m_config->tauEleOLRLoose() && tauEleBDTWPLoose >=2 ){ + ATH_MSG_WARNING("Using TauELeOLR is just usable together with the old EleBDT options. " + "Use OldLoose or OldMedium if you really want to use both (outdated)"); + } + + //============================================================ + // Nominal Tau Selection + //============================================================ + + + // Alias long tool names + using ITauSelTool = TauAnalysisTools::ITauSelectionTool; + using ITauEffCorrTool = TauAnalysisTools::ITauEfficiencyCorrectionsTool; + // Names of tools here for a little clarity + std::string tauSelName = "TauAnalysisTools::TauSelectionTool"; + std::string tauEffCorrName = "TauAnalysisTools::TauEfficiencyCorrectionsTool"; + + ///-- Setup the tau selection tool --/// + if (asg::ToolStore::contains<ITauSelTool>(tauSelName)) { + m_tauSelectionTool = asg::ToolStore::get<ITauSelTool>(tauSelName); } else { - ITauEffCorrTool* tauEffCorrTool - = new TauAnalysisTools::TauEfficiencyCorrectionsTool(tauEffCorrName); - top::check(asg::setProperty(tauEffCorrTool, "TauSelectionTool", m_tauSelectionTool), - "Failed to set TauSelectionTool for " + tauEffCorrName); - top::check(tauEffCorrTool->initialize() , "Failed to initialize"); - m_tauEffCorrTool = tauEffCorrTool; + std::unique_ptr<ITauSelTool> tauSelectionTool = std::make_unique<TauAnalysisTools::TauSelectionTool>(tauSelName); + if (!tauJetConfigFile.empty()) { + top::check(asg::setProperty(tauSelectionTool, "ConfigPath", tauJetConfigFile), + "Failed to set tau selection tool configuration path"); + top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::DEBUG), + "Failed to set tau OutputLevel"); + } else { + // set the ConfigPath to empty value is no file was provided (otherwise it creates conflicts) + top::check(asg::setProperty(tauSelectionTool, "ConfigPath", ""), + "Failed to set tau selection tool configuration path"); + top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::DEBUG), + "Failed to set tau OutputLevel"); + //WARNING: if we add more configurable cuts, they need to be added in the iSelectionCuts (see above) + top::check(asg::setProperty(tauSelectionTool, "SelectionCuts", iSelectionCuts), + "Failed to set tau SelectionCuts"); + top::check(asg::setProperty(tauSelectionTool, "PtMin", static_cast<double>(m_config->tauPtcut() / 1e3)), + "Failed to set tau pT cut"); + top::check(asg::setProperty(tauSelectionTool, "AbsEtaRegion", m_config->tauEtaRegions() ), + "Failed to set tau AbsEtaRegion"); + top::check(asg::setProperty(tauSelectionTool, "AbsCharge", absCharge), + "Failed to set tau AbsCharge"); + top::check(asg::setProperty(tauSelectionTool, "NTracks", nTracks), + "Failed to set tau NTracks"); + top::check(asg::setProperty(tauSelectionTool, "JetIDWP", tauJetIDWP), + "Failed to set tau JetIDWP"); + top::check(asg::setProperty(tauSelectionTool, "EleBDTWP", tauEleBDTWP), + "Failed to set tau EleBDTWP"); + top::check(asg::setProperty(tauSelectionTool, "EleOLR", m_config->tauEleOLR()), + "Failed to set tau-electron overlap removal in tau selection tool"); + } + top::check(tauSelectionTool->initialize(), "Failed to initialize tauSelectionTool"); + m_tauSelectionTool = tauSelectionTool.release(); + + ///-- Setup the EfficiencyCorrectionsTool while seting up the selection tool --/// + if (asg::ToolStore::contains<ITauEffCorrTool>(tauEffCorrName)) { + m_tauEffCorrTool = asg::ToolStore::get<ITauEffCorrTool>(tauEffCorrName); + } else { + std::unique_ptr<ITauEffCorrTool> tauEffCorrTool + = std::make_unique<TauAnalysisTools::TauEfficiencyCorrectionsTool>(tauEffCorrName); + if (m_config->isMC()) { + top::check(m_pileupReweightingTool.retrieve(), "Failed to retireve pileup reweighting tool"); + top::check(asg::setProperty(tauEffCorrTool, "PileupReweightingTool", m_pileupReweightingTool), + "Failed to set PileupReweightingTool for " + tauEffCorrName); + + top::check(asg::setProperty(tauEffCorrTool, "UseTauSubstructure", m_config->tauSubstructureSF()), + "Failed to set UseTauSubstructure for " + tauEffCorrName); + + top::check(asg::setProperty(tauEffCorrTool, "isAFII", m_config->isAFII()), + "Failed to set isAFII for " + tauEffCorrName); + } + top::check(asg::setProperty(tauEffCorrTool, "TauSelectionTool", m_tauSelectionTool), + "Failed to set TauSelectionTool for " + tauEffCorrName); + top::check(tauEffCorrTool->initialize(), "Failed to initialize"); + m_tauEffCorrTool = tauEffCorrTool.release(); + } } - } - //============================================================ - // 'Loose' Tau Selection - //============================================================ - - ///-- Names of tools here for a little clarity --/// - std::string tauSelNameLoose = "TauAnalysisTools::TauSelectionToolLoose"; - std::string tauEffCorrNameLoose = "TauAnalysisTools::TauEfficiencyCorrectionsToolLoose"; - - ///-- Setup the tau selection tool --/// - if (asg::ToolStore::contains<ITauSelTool>(tauSelNameLoose)) { - m_tauSelectionToolLoose = asg::ToolStore::get<ITauSelTool>(tauSelNameLoose); - } else { - ITauSelTool* tauSelectionTool = new TauAnalysisTools::TauSelectionTool(tauSelNameLoose); - if (!tauJetConfigFileLoose.empty()) { - top::check(asg::setProperty(tauSelectionTool, "ConfigPath",tauJetConfigFileLoose), - "Failed to set tau selection tool configuration path"); - top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::DEBUG), - "Failed to set tau OutputLevel"); + //============================================================ + // 'Loose' Tau Selection + //============================================================ + + ///-- Names of tools here for a little clarity --/// + std::string tauSelNameLoose = "TauAnalysisTools::TauSelectionToolLoose"; + std::string tauEffCorrNameLoose = "TauAnalysisTools::TauEfficiencyCorrectionsToolLoose"; + + ///-- Setup the tau selection tool --/// + if (asg::ToolStore::contains<ITauSelTool>(tauSelNameLoose)) { + m_tauSelectionToolLoose = asg::ToolStore::get<ITauSelTool>(tauSelNameLoose); } else { - // set the ConfigPath to empty value is no file was provided (otherwise it creates conflicts) - top::check(asg::setProperty(tauSelectionTool, "ConfigPath", ""), - "Failed to set tau selection tool configuration path"); - top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::DEBUG), - "Failed to set tau OutputLevel"); - //WARNING: if we add more configurable cuts, they need to be added in the iSelectionCuts (see above) - top::check(asg::setProperty(tauSelectionTool, "SelectionCuts", iSelectionCutsLoose), - "Failed to set tau SelectionCuts"); - top::check(asg::setProperty(tauSelectionTool, "PtMin", static_cast<double>(m_config->tauPtcut()/1e3)), - "Failed to set tau pT cut"); - top::check(asg::setProperty(tauSelectionTool, "AbsEtaRegion", absEtaRegion), - "Failed to set loose tau AbsEtaRegion"); - top::check(asg::setProperty(tauSelectionTool, "AbsCharge", absCharge), - "Failed to set loose tau AbsCharge"); - top::check(asg::setProperty(tauSelectionTool, "NTracks", nTracks), - "Failed to set loose tau NTracks"); - top::check(asg::setProperty(tauSelectionTool, "JetIDWP", tauJetIDWPLoose), - "Failed to set loose tau JetIDWP"); - top::check(asg::setProperty(tauSelectionTool, "EleBDTWP", tauEleBDTWPLoose), - "Failed to set loose tau EleBDTWP"); - top::check(asg::setProperty(tauSelectionTool, "EleOLR", m_config->tauEleOLRLoose()), - "Failed to set tau-electron overlap removal in loose tau selection tool"); + std::unique_ptr<ITauSelTool> tauSelectionTool = std::make_unique<TauAnalysisTools::TauSelectionTool>(tauSelNameLoose); + if (!tauJetConfigFileLoose.empty()) { + top::check(asg::setProperty(tauSelectionTool, "ConfigPath", tauJetConfigFileLoose), + "Failed to set tau selection tool configuration path"); + top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::DEBUG), + "Failed to set tau OutputLevel"); + } else { + // set the ConfigPath to empty value is no file was provided (otherwise it creates conflicts) + top::check(asg::setProperty(tauSelectionTool, "ConfigPath", ""), + "Failed to set tau selection tool configuration path"); + top::check(asg::setProperty(tauSelectionTool, "OutputLevel", MSG::DEBUG), + "Failed to set tau OutputLevel"); + //WARNING: if we add more configurable cuts, they need to be added in the iSelectionCuts (see above) + top::check(asg::setProperty(tauSelectionTool, "SelectionCuts", iSelectionCutsLoose), + "Failed to set tau SelectionCuts"); + top::check(asg::setProperty(tauSelectionTool, "PtMin", static_cast<double>(m_config->tauPtcut() / 1e3)), + "Failed to set tau pT cut"); + top::check(asg::setProperty(tauSelectionTool, "AbsEtaRegion", m_config->tauEtaRegions()), + "Failed to set loose tau AbsEtaRegion"); + top::check(asg::setProperty(tauSelectionTool, "AbsCharge", absCharge), + "Failed to set loose tau AbsCharge"); + top::check(asg::setProperty(tauSelectionTool, "NTracks", nTracks), + "Failed to set loose tau NTracks"); + top::check(asg::setProperty(tauSelectionTool, "JetIDWP", tauJetIDWPLoose), + "Failed to set loose tau JetIDWP"); + top::check(asg::setProperty(tauSelectionTool, "EleBDTWP", tauEleBDTWPLoose), + "Failed to set loose tau EleBDTWP"); + top::check(asg::setProperty(tauSelectionTool, "EleOLR", m_config->tauEleOLRLoose()), + "Failed to set tau-electron overlap removal in loose tau selection tool"); + } + top::check(tauSelectionTool->initialize(), "Failed to initialize tauSelectionTool"); + m_tauSelectionToolLoose = tauSelectionTool.release(); + + ///-- Setup the EfficiencyCorrectionsTool while seting up the selection tool --/// + if (asg::ToolStore::contains<ITauEffCorrTool>(tauEffCorrNameLoose)) { + m_tauEffCorrTool = asg::ToolStore::get<ITauEffCorrTool>(tauEffCorrNameLoose); + } else { + std::unique_ptr<ITauEffCorrTool> tauEffCorrTool + = std::make_unique<TauAnalysisTools::TauEfficiencyCorrectionsTool>(tauEffCorrNameLoose); + if (m_config->isMC()) { + top::check(m_pileupReweightingTool.retrieve(), "Failed to retireve pileup reweighting tool"); + top::check(asg::setProperty(tauEffCorrTool, "PileupReweightingTool", m_pileupReweightingTool), + "Failed to set PileupReweightingTool for " + tauEffCorrNameLoose); + top::check(asg::setProperty(tauEffCorrTool, "UseTauSubstructure", m_config->tauSubstructureSFLoose()), + "Failed to set UseTauSubstructure for " + tauEffCorrNameLoose); + + top::check(asg::setProperty(tauEffCorrTool, "isAFII", m_config->isAFII()), + "Failed to set isAFII for " + tauEffCorrNameLoose); + } + top::check(asg::setProperty(tauEffCorrTool, "TauSelectionTool", m_tauSelectionToolLoose), + "Failed to set TauSelectionTool for " + tauEffCorrNameLoose); + + top::check(tauEffCorrTool->initialize(), "Failed to initialize"); + m_tauEffCorrToolLoose = tauEffCorrTool.release(); + } } - top::check(tauSelectionTool->initialize(), "Failed to initialize tauSelectionTool"); - m_tauSelectionToolLoose = tauSelectionTool; - ///-- Setup the EfficiencyCorrectionsTool while seting up the selection tool --/// - if (asg::ToolStore::contains<ITauEffCorrTool>(tauEffCorrNameLoose)) { - m_tauEffCorrTool = asg::ToolStore::get<ITauEffCorrTool>(tauEffCorrNameLoose); + ///-- Calibration and smearing --/// + static const std::string tauSmearName = "TauAnalysisTools::TauSmearingTool"; + if (asg::ToolStore::contains<TauAnalysisTools::ITauSmearingTool>(tauSmearName)) { + m_tauSmearingTool = asg::ToolStore::get<TauAnalysisTools::ITauSmearingTool>(tauSmearName); } else { - ITauEffCorrTool* tauEffCorrTool - = new TauAnalysisTools::TauEfficiencyCorrectionsTool(tauEffCorrNameLoose); - top::check(asg::setProperty(tauEffCorrTool, "TauSelectionTool", m_tauSelectionToolLoose), - "Failed to set TauSelectionTool for " + tauEffCorrNameLoose); - top::check(tauEffCorrTool->initialize() , "Failed to initialize"); - m_tauEffCorrToolLoose = tauEffCorrTool; + std::unique_ptr<TauAnalysisTools::TauSmearingTool> tauSmearingTool = std::make_unique<TauAnalysisTools::TauSmearingTool>(tauSmearName); + top::check(asg::setProperty(tauSmearingTool, "isAFII", m_config->isAFII()), + "Failed to set TauSmearingTools isAFII property"); + top::check(tauSmearingTool->initialize(), "Failed to initialize"); + m_tauSmearingTool = tauSmearingTool.release(); } - } - - ///-- Calibration and smearing --/// - std::string tauSmearName = "TauAnalysisTools::TauSmearingTool"; - if (asg::ToolStore::contains<TauAnalysisTools::ITauSmearingTool>(tauSmearName)) { - m_tauSmearingTool = asg::ToolStore::get<TauAnalysisTools::ITauSmearingTool>(tauSmearName); - } else { - TauAnalysisTools::TauSmearingTool* tauSmearingTool = new TauAnalysisTools::TauSmearingTool(tauSmearName); - if (m_config->applyTauMVATES()) { - top::check(tauSmearingTool->setProperty("ApplyMVATES", true) , "Failed to enable MVA TES for tau smearing tool"); + + ///-- Truth matching --/// + static const std::string tauTruthMatchingName = "TauAnalysisTools::TauTruthMatchingTool"; + if (asg::ToolStore::contains<TauAnalysisTools::ITauTruthMatchingTool>(tauTruthMatchingName)) { + m_truthMatchingTool = asg::ToolStore::get<TauAnalysisTools::ITauTruthMatchingTool>(tauTruthMatchingName); + } else { + std::unique_ptr<TauAnalysisTools::TauTruthMatchingTool> tauMatchingTool = std::make_unique<TauAnalysisTools::TauTruthMatchingTool>(tauTruthMatchingName); + top::check(tauMatchingTool->setProperty("TruthJetContainerName", "AntiKt4TruthDressedWZJets"), "Failed to set truth collection for tau truth matching tool"); + top::check(tauMatchingTool->initialize(), "Failed to initialize"); + m_truthMatchingTool = tauMatchingTool.release(); } - top::check(tauSmearingTool->initialize() , "Failed to initialize"); - m_tauSmearingTool = tauSmearingTool; - } - return StatusCode::SUCCESS; -} -StatusCode TauCPTools::setupScaleFactors() { - /** - * - * Fill this in at some point... - * - * ...or maybe we don't need to - * - **/ - return StatusCode::SUCCESS; -} + return StatusCode::SUCCESS; + } + StatusCode TauCPTools::setupScaleFactors() { + /** + * + * Fill this in at some point... + * + * ...or maybe we don't need to + * + **/ + return StatusCode::SUCCESS; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopToolStore.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopToolStore.cxx index e3033990983b..00c48b5f074e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopToolStore.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopToolStore.cxx @@ -1,8 +1,8 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -// $Id: TopToolStore.cxx 803886 2017-04-27 21:27:58Z iconnell $ +// $Id: TopToolStore.cxx 808118 2017-07-11 17:41:22Z tpelzer $ #include "TopCPTools/TopToolStore.h" #include <vector> @@ -17,126 +17,93 @@ #include "TopEvent/EventTools.h" namespace top { - -TopToolStore::TopToolStore( const std::string& name ) : - asg::AsgTool( name ), - m_config(nullptr) { - declareProperty( "config" , m_config ); -} - -StatusCode TopToolStore::initialize() { - ATH_MSG_INFO("top::TopToolStore initialize..."); - - std::string release_series = ""; - const char* rel_temp = std::getenv("ROOTCORE_RELEASE_SERIES"); - if (rel_temp) { - release_series = std::string(rel_temp); - } else { - ATH_MSG_WARNING("Can not access ROOTCORE_RELEASE_SERIES"); + TopToolStore::TopToolStore(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr) { + declareProperty("config", m_config); } - ATH_MSG_INFO( "Release variable : "+release_series ); - - if (release_series == "23") { - ATH_MSG_INFO("Setting release series to 2.3"); - m_release_series = 23; - } else if (release_series == "24") { - m_release_series = 24; - ATH_MSG_INFO("Setting release series to 2.4"); - } else if (release_series == "25" ){ - m_release_series = 25; - ATH_MSG_INFO("Setting release series to 2.6"); - } else { - m_release_series = 24; - ATH_MSG_WARNING("Unknown release series, assuming 2.4"); + StatusCode TopToolStore::initialize() { + ATH_MSG_INFO("top::TopToolStore initialize..."); + + m_trigger_CP_tools = std::make_unique<top::TriggerCPTools>("top::TriggerCPTools"); + top::check(m_trigger_CP_tools->setProperty("config", m_config), + "Failed to share config with trigger CP tools"); + top::check(m_trigger_CP_tools->initialize(), + "Failed to initialize trigger tools"); + + m_other_CP_tools = std::make_unique<top::OtherCPTools>("top::OtherCPTools"); + top::check(m_other_CP_tools->setProperty("config", m_config), + "Failed to share config with other CP tools"); + top::check(m_other_CP_tools->initialize(), + "Failed to initialize other tools"); + + m_egamma_CP_tools = std::make_unique<top::EgammaCPTools>("top::EgammaCPTools"); + top::check(m_egamma_CP_tools->setProperty("config", m_config), + "Failed to share config with egamma CP tools"); + top::check(m_egamma_CP_tools->initialize(), + "Failed to initialize egamma tools"); + + m_muon_CP_tools = std::make_unique<top::MuonCPTools>("top::MuonCPTools"); + top::check(m_muon_CP_tools->setProperty("config", m_config), + "Failed to share config with muon CP tools"); + top::check(m_muon_CP_tools->initialize(), + "Failed to initialize muon tools"); + + m_tau_CP_tools = std::make_unique<top::TauCPTools>("top::TauCPTools"); + top::check(m_tau_CP_tools->setProperty("config", m_config), + "Failed to share config with tau CP tools"); + top::check(m_tau_CP_tools->initialize(), + "Failed to initialize tau tools"); + + m_flavor_tagging_CP_tools = std::make_unique<top::FlavorTaggingCPTools>("top::FlavorTaggingCPTools"); + top::check(m_flavor_tagging_CP_tools->setProperty("config", m_config), + "Failed to share config with flavour tagging CP tools"); + top::check(m_flavor_tagging_CP_tools->initialize(), + "Failed to initialize flavor tagging tools"); + + m_boosted_tagging_CP_tools = std::make_unique<top::BoostedTaggingCPTools>("top::BoostedTaggingCPTools"); + top::check(m_boosted_tagging_CP_tools->setProperty("config", m_config), + "Failed to share config with flavour tagging CP tools"); + top::check(m_boosted_tagging_CP_tools->initialize(), + "Failed to initialize boosted tagging tools"); + + m_jetMET_CP_tools = std::make_unique<top::JetMETCPTools>("top::JetMETCPTools"); + top::check(m_jetMET_CP_tools->setProperty("config", m_config), + "Failed to share config with Jet/MET CP tools"); + top::check(m_jetMET_CP_tools->initialize(), + "Failed to initialize Jet/MET tools"); + + m_isolation_CP_tools = std::make_unique<top::IsolationCPTools>("top::IsolationCPTools"); + top::check(m_isolation_CP_tools->setProperty("config", m_config), + "Failed to share config with isolation CP tools"); + top::check(m_isolation_CP_tools->initialize(), + "Failed to initialize isolation tools"); + + m_OR_CP_tools = std::make_unique<top::OverlapRemovalCPTools>("top::OverlapRemovalCPTools"); + top::check(m_OR_CP_tools->setProperty("config", m_config), + "Failed to share config with overlap removal CP tools"); + top::check(m_OR_CP_tools->initialize(), + "Failed to initialize overlap removal tools"); + + m_ghost_track_CP_tools = std::make_unique<top::GhostTrackCPTools>("top::GhostTrackCPTools"); + top::check(m_ghost_track_CP_tools->setProperty("config", m_config), + "Failed to share config with ghost track CP tools"); + top::check(m_ghost_track_CP_tools->initialize(), + "Failed to initialize ghost track tools"); + + m_track_CP_tools = std::make_unique<top::TrackCPTools>("top::TrackCPTools"); + top::check(m_track_CP_tools->setProperty("config", m_config), + "Failed to share config with track CP tools"); + top::check(m_track_CP_tools->initialize(), + "Failed to initialize track tools"); + + + return StatusCode::SUCCESS; } - m_trigger_CP_tools = std::make_unique<top::TriggerCPTools>("top::TriggerCPTools"); - top::check(m_trigger_CP_tools->setProperty("config", m_config), - "Failed to share config with trigger CP tools"); - top::check(m_trigger_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with trigger CP tools"); - top::check(m_trigger_CP_tools->initialize(), - "Failed to initialize trigger tools"); - - m_other_CP_tools = std::make_unique<top::OtherCPTools>("top::OtherCPTools"); - top::check(m_other_CP_tools->setProperty("config", m_config), - "Failed to share config with other CP tools"); - top::check(m_other_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with other CP tools"); - top::check(m_other_CP_tools->initialize(), - "Failed to initialize other tools"); - - m_egamma_CP_tools = std::make_unique<top::EgammaCPTools>("top::EgammaCPTools"); - top::check(m_egamma_CP_tools->setProperty("config", m_config), - "Failed to share config with egamma CP tools"); - top::check(m_egamma_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with egamma CP tools"); - top::check(m_egamma_CP_tools->initialize(), - "Failed to initialize egamma tools"); - - m_muon_CP_tools = std::make_unique<top::MuonCPTools>("top::MuonCPTools"); - top::check(m_muon_CP_tools->setProperty("config", m_config), - "Failed to share config with muon CP tools"); - top::check(m_muon_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with muon CP tools"); - top::check(m_muon_CP_tools->initialize(), - "Failed to initialize muon tools"); - - m_tau_CP_tools = std::make_unique<top::TauCPTools>("top::TauCPTools"); - top::check(m_tau_CP_tools->setProperty("config", m_config), - "Failed to share config with tau CP tools"); - top::check(m_tau_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with tau CP tools"); - top::check(m_tau_CP_tools->initialize(), - "Failed to initialize tau tools"); - - m_flavor_tagging_CP_tools = std::make_unique<top::FlavorTaggingCPTools>("top::FlavorTaggingCPTools"); - top::check(m_flavor_tagging_CP_tools->setProperty("config", m_config), - "Failed to share config with flavour tagging CP tools"); - top::check(m_flavor_tagging_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with flavour tagging CP tools"); - top::check(m_flavor_tagging_CP_tools->initialize(), - "Failed to initialize flavor tagging tools"); - - m_jetMET_CP_tools = std::make_unique<top::JetMETCPTools>("top::JetMETCPTools"); - top::check(m_jetMET_CP_tools->setProperty("config", m_config), - "Failed to share config with Jet/MET CP tools"); - top::check(m_jetMET_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with Jet/MET CP tools"); - top::check(m_jetMET_CP_tools->initialize(), - "Failed to initialize Jet/MET tools"); - - m_isolation_CP_tools = std::make_unique<top::IsolationCPTools>("top::IsolationCPTools"); - top::check(m_isolation_CP_tools->setProperty("config", m_config), - "Failed to share config with isolation CP tools"); - top::check(m_isolation_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with isolation CP tools"); - top::check(m_isolation_CP_tools->initialize(), - "Failed to initialize isolation tools"); - - m_OR_CP_tools = std::make_unique<top::OverlapRemovalCPTools>("top::OverlapRemovalCPTools"); - top::check(m_OR_CP_tools->setProperty("config", m_config), - "Failed to share config with overlap removal CP tools"); - top::check(m_OR_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with overlap removal CP tools"); - top::check(m_OR_CP_tools->initialize(), - "Failed to initialize overlap removal tools"); - - m_ghost_track_CP_tools = std::make_unique<top::GhostTrackCPTools>("top::GhostTrackCPTools"); - top::check(m_ghost_track_CP_tools->setProperty("config", m_config), - "Failed to share config with ghost track CP tools"); - top::check(m_ghost_track_CP_tools->setProperty("release_series", m_release_series), - "Failed to release_series series with ghost track CP tools"); - top::check(m_ghost_track_CP_tools->initialize(), - "Failed to initialize ghost track tools"); - - return StatusCode::SUCCESS; -} - -StatusCode TopToolStore::finalize() { - ATH_MSG_INFO("top::TopToolStore finalize"); - return StatusCode::SUCCESS; -} - + StatusCode TopToolStore::finalize() { + ATH_MSG_INFO("top::TopToolStore finalize"); + return StatusCode::SUCCESS; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTrackCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTrackCPTools.cxx new file mode 100644 index 000000000000..7c9ac0a4ffb8 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTrackCPTools.cxx @@ -0,0 +1,177 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopCPTools/TopTrackCPTools.h" +#include "InDetTrackSelectionTool/InDetTrackSelectionTool.h" + +#include <map> +#include <string> +#include <utility> + +// Top includes +#include "TopConfiguration/TopConfig.h" +#include "TopEvent/EventTools.h" + +// PathResolver include(s): +#include "PathResolver/PathResolver.h" + + +namespace top { + TrackCPTools::TrackCPTools(const std::string& name) : + asg::AsgTool(name) { + declareProperty("config", m_config); + declareProperty("TrkSelTool", m_trkseltool); + } + + StatusCode TrackCPTools::initialize() { + ATH_MSG_INFO("top::TrackCPTools initialize..."); + + if (m_config->isTruthDxAOD()) { + ATH_MSG_INFO("top::TrackCPTools: no need to initialise anything on truth DxAOD"); + return StatusCode::SUCCESS; + } + + if (!m_config->useTracks()) { + ATH_MSG_INFO( + "top::TrackCPTools: no need to initialise anything since not using tracks"); + return StatusCode::SUCCESS; + } + + if (!m_config->makeAllCPTools()) { + ATH_MSG_INFO("top::TrackCPTools: no need to initialise for mini-xAOD"); + return StatusCode::SUCCESS; + } + + // This defines the run period (ranges) that are used by the + // InDet::InDetTrackBiasingTool. The following inputs are possible: + // - No / empty input: Use the maximum range, that is [0; + // UInt32_t::max) as allowed run number value range. Initialise + // the tool with run number 0 (which will use 2015 precriptions). + // - A single run number: Configure the tool with this run number + // and to not apply checks / selection on the random run number of + // the actual events. + // - At least two values: Use this to define adjacent ranges, each + // of which is processed using a unique instance of the tool which + // was initialised using the lower bound of the range. From an + // input of size n, n-1 ranges are formed. The i-th element is the + // lower bound (incl) of the i-th range; the (i+1)-th element is + // the upper bound (excl) of the i-th range. + + m_runPeriods = { + 276262, 297730, 300909, 311482, 334738, 341650, 364486 + }; + + m_config->runPeriodTrack(m_runPeriods); + + top::check(setupSmearingTool(), "Failed to setup track smearing tools"); + top::check(setupBiasingTools(), "Failed to setup track biasing tools"); + top::check(setupTruthFilterTool(), "Failed to setup truth filter tools"); + + if(m_trkseltool.empty()) { + InDet::InDetTrackSelectionTool *selTool = new InDet::InDetTrackSelectionTool( "TrkSelTool" , m_config->trackQuality()); + top::check(selTool -> initialize(), "Failed to initialize InDetTrackSelectionTool"); + m_trkseltool = ToolHandle<InDet::IInDetTrackSelectionTool>(selTool); + } + top::check(m_trkseltool.retrieve(), "Failed to retrieve InDetTrackSelectionTool"); + + return StatusCode::SUCCESS; + } + + StatusCode TrackCPTools::setupSmearingTool() { + if (asg::ToolStore::contains<InDet::InDetTrackSmearingTool>(m_smearingToolName)) { + m_smearingTool = asg::ToolStore::get<InDet::InDetTrackSmearingTool>(m_smearingToolName); + } else { + auto tool = new InDet::InDetTrackSmearingTool(m_smearingToolName); + top::check(tool->initialize(), "Failure to initialize InDetTrackSmearingTool"); + m_smearingTool = tool; + ATH_MSG_INFO(" Creating smearing tool " + m_smearingToolName); + } + return StatusCode::SUCCESS; + } + + StatusCode TrackCPTools::setupBiasingTools() { + top::check(not m_runPeriods.empty(), "Assertion failed"); + + // Two cases are possible: + // - Either a single run number was specified to the runPeriods + // parameter in which case we'll use exactly that run number, or + // - at least two numbers have been specified, which then define + // (potentially multiple) run number ranges. + + if (m_runPeriods.size() == 1) { + m_runPeriods.resize(1); + + const std::string biasToolName { + m_biasToolPrefix + "_" + std::to_string(m_runPeriods[0]) + }; + + if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)) { + m_biasingTool[0] = asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); + } else { + auto tool = new InDet::InDetTrackBiasingTool(biasToolName); + top::check(tool->setProperty("runNumber", m_runPeriods[0]), + "Failure to setProperty runNumber of InDetTrackBiasingTool " + biasToolName); + top::check(tool->initialize(), + "Failure to initialize InDetTrackBiasingTool " + biasToolName); + m_biasingTool[0] = tool; + } + ATH_MSG_INFO(" Creating biasing tool to calibrate for run#=" << m_runPeriods[0] << ": " + biasToolName); + } else { + m_biasingTool.resize(m_runPeriods.size() - 1); + for (std::size_t i = 0; i < m_runPeriods.size() - 1; ++i) { + const std::string biasToolName { + m_biasToolPrefix + + "_" + std::to_string(m_runPeriods[i]) + + "_" + std::to_string(m_runPeriods[i + 1]) + }; + ATH_MSG_INFO( + " Creating biasing tool to calibrate for period [" << m_runPeriods[i] << ", " << m_runPeriods[i + 1] << "): " << + biasToolName); + if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)) { + m_biasingTool[i] = + asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); + } else { + auto tool = new InDet::InDetTrackBiasingTool(biasToolName); + top::check(tool->setProperty("runNumber", m_runPeriods[i]), + "Failure to setProperty runNumber of InDetTrackBiasingTool " + biasToolName); + top::check(tool->initialize(), + "Failure to initialize InDetTrackBiasingTool " + biasToolName); + m_biasingTool[i] = tool; + } + } + } + return StatusCode::SUCCESS; + } + + StatusCode TrackCPTools::setupTruthFilterTool() { + + // for track reconstruction efficiency uncertainties and fake rate uncertainties + + if (asg::ToolStore::contains<InDet::InDetTrackTruthOriginTool>(m_truthOriginToolName)) { + m_truthOriginTool = asg::ToolStore::get<InDet::InDetTrackTruthOriginTool>(m_truthOriginToolName); + } else { + auto tool = new InDet::InDetTrackTruthOriginTool(m_truthOriginToolName); + top::check(tool->initialize(), + "Failure to initialize InDetTrackTruthOriginTool " + m_truthOriginToolName); + m_truthOriginTool = tool; + ATH_MSG_INFO(" Creating truth origin tool " + m_truthOriginToolName); + } + + if (asg::ToolStore::contains<InDet::InDetTrackTruthFilterTool>(m_truthFilterToolName)) { + m_truthFilterTool = asg::ToolStore::get<InDet::InDetTrackTruthFilterTool>(m_truthFilterToolName); + } else { + auto tool = new InDet::InDetTrackTruthFilterTool(m_truthFilterToolName); + top::check(tool->setProperty("trackOriginTool", + ToolHandle<InDet::IInDetTrackTruthOriginTool>{&(*m_truthOriginTool)}), + "Failed to setProperty trackOriginTool of InDetTrackTruthFilterTool " + m_truthFilterToolName); + top::check(tool->initialize(), + "Failure to initialize InDetTrackTruthFilterTool " + m_truthFilterToolName); + m_truthFilterTool = tool; + ATH_MSG_INFO(" Creating truth filter tool " + m_truthFilterToolName); + } + return StatusCode::SUCCESS; + } + + +} // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTriggerCPTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTriggerCPTools.cxx index 5028e3e0a21c..590a07ae2737 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTriggerCPTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/Root/TopTriggerCPTools.cxx @@ -1,11 +1,14 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #include "TopCPTools/TopTriggerCPTools.h" #include <map> +#include <set> #include <string> +#include <vector> +#include <unordered_map> // Top includes #include "TopConfiguration/TopConfig.h" @@ -17,85 +20,405 @@ // Trigger include(s): #include "TrigConfxAOD/xAODConfigTool.h" #include "TriggerMatchingTool/MatchingTool.h" +#include "TriggerMatchingTool/MatchFromCompositeTool.h" #include "TrigTauMatching/TrigTauMatching.h" +//#include "TrigGlobalEfficiencyCorrection/TrigGlobalEfficiencyCorrectionTool.h" +//#include "TrigGlobalEfficiencyCorrection/ImportData.h" +#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h" +#include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h" +#include "MuonEfficiencyCorrections/MuonTriggerScaleFactors.h" +#include "PATCore/PATCoreEnums.h" +#include "xAODBase/ObjectType.h" +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/join.hpp> namespace top { - -TriggerCPTools::TriggerCPTools(const std::string& name) : + TriggerCPTools::TriggerCPTools(const std::string& name) : asg::AsgTool(name) { - declareProperty("config", m_config); - declareProperty("release_series", m_release_series ); - - declareProperty( "TrigConfigTool", m_trigConfTool ); - declareProperty( "TrigDecisionTool", m_trigDecisionTool ); - declareProperty( "TrigMatchTool", m_trigMatchTool ); -} - -StatusCode TriggerCPTools::initialize() { - ATH_MSG_INFO("top::TriggerCPTools initialize..."); - - if (m_config->makeAllCPTools()) { - if (!m_config->isTruthDxAOD()) { - ///-- The configuration tool --/// - const std::string trig_config_name = "TrigConf::xAODConfigTool"; - if ( asg::ToolStore::contains<TrigConf::ITrigConfigTool>(trig_config_name) ) { - m_trigConfTool = asg::ToolStore::get<TrigConf::ITrigConfigTool>(trig_config_name); - } else { - TrigConf::xAODConfigTool* configTool = new TrigConf::xAODConfigTool(trig_config_name); - top::check( configTool->initialize() , "Failed to initialize trigger config tool" ); - m_trigConfTool = configTool; - } + declareProperty("config", m_config); - ///-- The decision tool --/// - const std::string trig_decision_name = "Trig::TrigDecisionTool"; - if ( asg::ToolStore::contains<Trig::TrigDecisionTool>(trig_decision_name) ) { - m_trigDecisionTool = asg::ToolStore::get<Trig::TrigDecisionTool>(trig_decision_name); - } else { - Trig::TrigDecisionTool* trigDecTool = new Trig::TrigDecisionTool(trig_decision_name); - top::check( trigDecTool->setProperty("ConfigTool", m_trigConfTool ) , "Failed to setProperty" ); - top::check( trigDecTool->setProperty("TrigDecisionKey", "xTrigDecision") , "Failed to setProperty" ); - top::check( trigDecTool->initialize() , "Failed to initialize trigger decision tool" ); - m_trigDecisionTool = trigDecTool; - } + declareProperty("TrigConfigTool", m_trigConfTool); + declareProperty("TrigDecisionTool", m_trigDecisionTool); + declareProperty("TrigMatchTool", m_trigMatchTool); +// declareProperty("GlobalTriggerEffTool", m_globalTriggerEffTool); +// declareProperty("GlobalTriggerEffToolLoose", m_globalTriggerEffToolLoose); - // Trigger matching tool - const std::string trig_match_name = "Trig::MatchingTool"; - if (asg::ToolStore::contains<Trig::IMatchingTool>(trig_match_name)) { - m_trigMatchTool = asg::ToolStore::get<Trig::IMatchingTool>(trig_match_name); - } else { - Trig::MatchingTool* trigMatchTool = new Trig::MatchingTool(trig_match_name); - top::check(trigMatchTool->setProperty("TrigDecisionTool", m_trigDecisionTool), - "Failed to set trigger decision tool to trigger matching tool"); - top::check(trigMatchTool->initialize(), - "Failed to initialize trig. matching tool"); - m_trigMatchTool = trigMatchTool; - } + m_muonTool = asg::AnaToolHandle<CP::IMuonTriggerScaleFactors>("CP::MuonTriggerScaleFactors/MuonTrigEff"); + m_muonToolLoose = asg::AnaToolHandle<CP::IMuonTriggerScaleFactors>("CP::MuonTriggerScaleFactors/MuonTrigEffLoose"); + } + + StatusCode TriggerCPTools::initialize() { + ATH_MSG_INFO("top::TriggerCPTools initialize..."); - ///-- Tau matching --/// - if( m_config->useTaus() ){ - const std::string tauMatchName = "Trig::TrigTauMatchingTool"; - if ( asg::ToolStore::contains<Trig::ITrigTauMatchingTool>(tauMatchName) ) { - m_trigMatchTauTool = asg::ToolStore::get<Trig::ITrigTauMatchingTool>(tauMatchName); + if (m_config->makeAllCPTools()) { + if (!m_config->isTruthDxAOD()) { + ///-- The configuration tool --/// + const std::string trig_config_name = "TrigConf::xAODConfigTool"; + if (asg::ToolStore::contains<TrigConf::ITrigConfigTool>(trig_config_name)) { + m_trigConfTool = asg::ToolStore::get<TrigConf::ITrigConfigTool>(trig_config_name); + } else { + TrigConf::xAODConfigTool* configTool = new TrigConf::xAODConfigTool(trig_config_name); + top::check(configTool->initialize(), "Failed to initialize trigger config tool"); + m_trigConfTool = configTool; } - else { - Trig::TrigTauMatchingTool* trigMatchTauTool = new Trig::TrigTauMatchingTool(tauMatchName); - top::check( trigMatchTauTool->setProperty("TrigDecisionTool", m_trigDecisionTool), - "Failed to set trig dec tool for tau matching" ); - top::check( trigMatchTauTool->initialize(), - "Failed to initialize tau trigger matching tool" ); - m_trigMatchTauTool = trigMatchTauTool; + + ///-- The decision tool --/// + const std::string trig_decision_name = "Trig::TrigDecisionTool"; + if (asg::ToolStore::contains<Trig::TrigDecisionTool>(trig_decision_name)) { + m_trigDecisionTool = asg::ToolStore::get<Trig::TrigDecisionTool>(trig_decision_name); + } else { + Trig::TrigDecisionTool* trigDecTool = new Trig::TrigDecisionTool(trig_decision_name); + top::check(trigDecTool->setProperty("ConfigTool", m_trigConfTool), "Failed to setProperty"); + top::check(trigDecTool->setProperty("TrigDecisionKey", "xTrigDecision"), "Failed to setProperty"); + top::check(trigDecTool->initialize(), "Failed to initialize trigger decision tool"); + m_trigDecisionTool = trigDecTool; } + + // Trigger matching tool + static const std::string trig_match_name = "Trig::MatchingTool"; + if (asg::ToolStore::contains<Trig::IMatchingTool>(trig_match_name)) { + m_trigMatchTool = asg::ToolStore::get<Trig::IMatchingTool>(trig_match_name); + } else { + if (m_config->getDerivationStream() == "PHYS") { + Trig::MatchFromCompositeTool* trigMatchTool = new Trig::MatchFromCompositeTool(trig_match_name); + top::check(trigMatchTool->initialize(), + "Failed to initialize trig. matching tool"); + m_trigMatchTool = trigMatchTool; + + } else { + Trig::MatchingTool* trigMatchTool = new Trig::MatchingTool(trig_match_name); + top::check(trigMatchTool->setProperty("TrigDecisionTool", m_trigDecisionTool), + "Failed to set trigger decision tool to trigger matching tool"); + top::check(trigMatchTool->initialize(), + "Failed to initialize trig. matching tool"); + m_trigMatchTool = trigMatchTool; + } + } + + ///-- Tau matching --/// + if (m_config->useTaus()) { + const std::string tauMatchName = "Trig::TrigTauMatchingTool"; + if (asg::ToolStore::contains<Trig::ITrigTauMatchingTool>(tauMatchName)) { + m_trigMatchTauTool = asg::ToolStore::get<Trig::ITrigTauMatchingTool>(tauMatchName); + } else { + Trig::TrigTauMatchingTool* trigMatchTauTool = new Trig::TrigTauMatchingTool(tauMatchName); + top::check(trigMatchTauTool->setProperty("TrigDecisionTool", m_trigDecisionTool), + "Failed to set trig dec tool for tau matching"); + top::check(trigMatchTauTool->initialize(), + "Failed to initialize tau trigger matching tool"); + m_trigMatchTauTool = trigMatchTauTool; + } + } + ///-- Trigger global efficiency corrections --/// + if (m_config->useGlobalTrigger()) { + top::check(this->initialiseGlobalTriggerEff(), + "Failed to construct global trigger efficiencies"); + } + } else { + ATH_MSG_INFO("top::TriggerCPTools: no need to initialise anything on truth DxAOD"); } + } else { + ATH_MSG_INFO("top::TriggerCPTools: no need to initialise anything in mini-xAOD mode"); } - else { - ATH_MSG_INFO("top::TriggerCPTools: no need to initialise anything on truth DxAOD"); - } + + return StatusCode::SUCCESS; } - else { - ATH_MSG_INFO("top::TriggerCPTools: no need to initialise anything in mini-xAOD mode"); + + StatusCode TriggerCPTools::initialiseGlobalTriggerEff() { + StatusCode statusCode = StatusCode::SUCCESS; + + // utilities for TrigGlobEffCorr::ImportData + //TrigGlobEffCorr::ImportData triggerData; + //top::check(triggerData.importTriggers(), "failed to import trigger data"); + //auto const& triggerDict = triggerData.getDictionary(); + //std::unordered_map<std::string, TrigGlobEffCorr::ImportData::TrigDef> triggerDefs; + //for (auto&& kv : triggerData.getTriggerDefs()) { + // auto it = triggerDict.find(kv.first); + // if (it != triggerDict.end()) { + // triggerDefs[it->second] = kv.second; + // } + //} + //auto getTriggerLegs = + // [&](std::unordered_map<std::string, std::vector<std::string> > const& triggerCombination, + // std::unordered_map<std::string, std::set<std::string> >& electronLegsByPeriod) { + // for (auto&& kv : triggerCombination) { + // std::string const& period = kv.first; + // for (auto const& trigKey : kv.second) { + // auto triggerDefsIt = triggerDefs.find(trigKey); + // if (triggerDefsIt == triggerDefs.end()) { + // statusCode = StatusCode::FAILURE; + // ATH_MSG_ERROR("unrecognized trigger `" << trigKey << "'"); + // continue; + // } + // auto const& trigDef = triggerDefsIt->second; + // for (auto const& leg : trigDef.leg) { + // if (!leg) continue; + // std::string const& legname = triggerDict.at(leg); + // bool ok = true; + // xAOD::Type::ObjectType legtype = triggerData.associatedLeptonFlavour(legname, ok); + // if (!ok) { + // statusCode = StatusCode::FAILURE; + // ATH_MSG_ERROR("could not determine object type for trigger leg `" << legname << + // "'"); + // continue; + // } + // switch (legtype) { + // case xAOD::Type::Electron: + // electronLegsByPeriod[period].insert(legname); + // break; + + // case xAOD::Type::Muon: + // break; + + // default: + // statusCode = StatusCode::FAILURE; + // ATH_MSG_ERROR( + // "trigger leg `" << legname << "' has unsupported object type `" << legtype << "'"); + // continue; + // } + // } + // } + // } + // }; + + //// Get trigger strings from configuration + //std::map<std::string, std::string> triggerCombination, triggerCombinationLoose; + //std::vector<std::string> electronSystematics, muonSystematics, electronToolNames, muonToolNames; + //std::unordered_map<std::string, std::vector<std::string> > const emptymap; + //std::unordered_map<std::string, std::vector<std::string> > const& + //triggersByPeriod = (m_config->doTightEvents() ? m_config->getGlobalTriggers() : emptymap), + // triggersByPeriodLoose = (m_config->doLooseEvents() ? m_config->getGlobalTriggersLoose() : emptymap); + + //std::unordered_map<std::string, std::set<std::string> > electronLegsByPeriod, electronLegsByPeriodLoose; + //getTriggerLegs(triggersByPeriod, electronLegsByPeriod); + //getTriggerLegs(triggersByPeriodLoose, electronLegsByPeriodLoose); + + //// Get quality + //std::string electronID, electronIDLoose, electronIsolation, electronIsolationLoose, muonQuality, muonQualityLoose; + //if (m_config->doTightEvents()) { + // electronID = m_config->electronID(); + // electronIsolation = m_config->electronIsolationSF(); + // muonQuality = m_config->muonQuality(); + //} + //if (m_config->doLooseEvents()) { + // electronIDLoose = m_config->electronIDLoose(); + // electronIsolationLoose = m_config->electronIsolationSFLoose(); + // muonQualityLoose = m_config->muonQualityLoose(); + //} + + //// Tidy name for e/gamma + //electronID = mapWorkingPoints(electronID); + //electronIDLoose = mapWorkingPoints(electronIDLoose); + //// This is hopefully only temporary + //electronIsolation = mapWorkingPoints(electronIsolation); + //electronIsolationLoose = mapWorkingPoints(electronIsolationLoose); + + //// Create electron trigger SF and Eff tools + //ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools, electronSFTools, electronEffToolsLoose, + // electronSFToolsLoose; + //std::map<std::string, std::string> legsPerTool, legsPerToolLoose; + //int nTools = 0; + + //// Loop over the triggers found (electrons - tight) + //for (auto& y_t : electronLegsByPeriod) { + // std::string year = y_t.first; + // for (auto& trigKey : y_t.second) { + // nTools++; + // for (int j = 0; j < 2; ++j) { // one tool instance for efficiencies, another for scale factors + // ATH_MSG_INFO("TIGHT " << year << " " << trigKey << " " << electronID << " " << electronIsolation); + // auto t = m_electronToolsFactory.emplace( + // m_electronToolsFactory.end(), "AsgElectronEfficiencyCorrectionTool/ElTrigEff_" + std::to_string( + // j) + "_" + std::to_string(nTools)); + // top::check(t->setProperty("MapFilePath", + // "ElectronEfficiencyCorrection/2015_2017/rel21.2/Consolidation_September2018_v1/map3.txt"), + // "Fail"); + // top::check(t->setProperty("TriggerKey", + // (j ? year + "_" + trigKey : "Eff_" + year + "_" + trigKey)), + // "Failed to set TriggerKey"); + // if (electronID != "None") top::check(t->setProperty("IdKey", electronID), "Failed to set IdKey"); + // if (electronIsolation != "None") top::check(t->setProperty("IsoKey", + // electronIsolation), "Failed to set IsoKey"); + // top::check(t->setProperty("CorrelationModel", "TOTAL"), "Failed to set CorrelationModel"); + // top::check(t->setProperty("ForceDataType", + // (int) PATCore::ParticleDataType::Full), "Failed to set ForceDataType"); + // top::check(t->setProperty("OutputLevel", MSG::INFO), "Failed to set OutputLevel"); + // top::check(t->initialize(), "Failed to initalise"); + // // Using syntax from examples + // auto& handles = j ? electronSFTools : electronEffTools; + // handles.push_back(t->getHandle()); + // std::string name = handles[handles.size() - 1].name(); + // legsPerTool[name] = trigKey + " [" + year + "]"; + // ATH_MSG_INFO("TIGHT " << name << " -> " << trigKey); + // electronToolNames.push_back(name); + // // Special - Record the systematic names from the efficiency tool (not SF tool) + // if (electronSystematics.size() == 0 && j == 1) { + // for (auto& s : + // handles[handles.size() - 1]->recommendedSystematics().getBaseNames()) electronSystematics.push_back(s); + + // } + // } + // } + //} + + //// Loop over the triggers found (electrons - loose) + //nTools = 0; + //for (auto& y_t : electronLegsByPeriodLoose) { + // std::string year = y_t.first; + // for (auto& trigKey : y_t.second) { + // nTools++; + // for (int j = 0; j < 2; ++j) { // one tool instance for efficiencies, another for scale factors + // ATH_MSG_INFO("LOOSE " << year << " " << trigKey << " " << electronIDLoose << " " << electronIsolationLoose); + // auto tLoose = m_electronToolsFactoryLoose.emplace( + // m_electronToolsFactoryLoose.end(), "AsgElectronEfficiencyCorrectionTool/ElTrigEffLoose_" + std::to_string( + // j) + "_" + std::to_string(nTools)); + // top::check(tLoose->setProperty("MapFilePath", + // "ElectronEfficiencyCorrection/2015_2017/rel21.2/Consolidation_September2018_v1/map3.txt"), + // "Fail"); + // top::check(tLoose->setProperty("TriggerKey", + // (j ? year + "_" + trigKey : "Eff_" + year + "_" + trigKey)), + // "Failed to set TriggerKey"); + // if (electronIDLoose != + // "None") top::check(tLoose->setProperty("IdKey", electronIDLoose), "Failed to set IdKey"); + // if (electronIsolationLoose != "None") top::check(tLoose->setProperty("IsoKey", + // electronIsolationLoose), + // "Failed to set IsoKey"); + // top::check(tLoose->setProperty("CorrelationModel", "TOTAL"), "Failed to set CorrelationModel"); + // top::check(tLoose->setProperty("ForceDataType", + // (int) PATCore::ParticleDataType::Full), "Failed to set ForceDataType"); + // top::check(tLoose->setProperty("OutputLevel", MSG::INFO), "Failed to set OutputLevel"); + // top::check(tLoose->initialize(), "Failed to initalise"); + // // Using syntax from examples + // auto& handlesLoose = j ? electronSFToolsLoose : electronEffToolsLoose; + // handlesLoose.push_back(tLoose->getHandle()); + // std::string name = handlesLoose[handlesLoose.size() - 1].name(); + // legsPerToolLoose[name] = trigKey + " [" + year + "]"; + // ATH_MSG_INFO("LOOSE " << name << " -> " << trigKey); + // electronToolNames.push_back(name); + // // Special - Record the systematic names from the efficiency tool (not SF tool) + // if (electronSystematics.size() == 0 && j == 1) { + // for (auto& s : + // handlesLoose[handlesLoose.size() - + // 1]->recommendedSystematics().getBaseNames()) electronSystematics.push_back(s); + // } + // } + // } + //} + + //// Create muon trigger SF tool + //ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools; + //ToolHandleArray<CP::IMuonTriggerScaleFactors> muonToolsLoose; + + //if (m_config->doTightEvents()) { + // if (muonQuality != "None") top::check(m_muonTool.setProperty("MuonQuality", + // muonQuality), "Failed to set MuonQuality"); + // top::check(m_muonTool.setProperty("AllowZeroSF", true), "Failed to set AllowZeroSF"); + // top::check(m_muonTool.initialize(), "Failed to initialise"); + // muonTools.push_back(m_muonTool.getHandle()); + // ATH_MSG_INFO("Muon tool name (tight) " << muonTools[muonTools.size() - 1].name()); + // muonToolNames.push_back(muonTools[muonTools.size() - 1].name()); + // // Special - Get muon systematics + // if (muonSystematics.size() == 0) { + // for (auto& s: + // muonTools[muonTools.size() - 1]->recommendedSystematics().getBaseNames()) muonSystematics.push_back(s); + // } + //} + + //if (m_config->doLooseEvents()) { + // if (muonQualityLoose != "None") top::check(m_muonToolLoose.setProperty("MuonQuality", + // muonQualityLoose), + // "Failed to set MuonQuality"); + // top::check(m_muonToolLoose.setProperty("AllowZeroSF", true), "Failed to set AllowZeroSF"); + // top::check(m_muonToolLoose.initialize(), "Failed to initialise"); + // muonToolsLoose.push_back(m_muonToolLoose.getHandle()); + // ATH_MSG_INFO("Muon tool name (loose) " << muonToolsLoose[muonToolsLoose.size() - 1].name()); + // muonToolNames.push_back(muonToolsLoose[muonToolsLoose.size() - 1].name()); + // // Special - Get muon systematics + // if (muonSystematics.size() == 0) { + // for (auto& s: muonToolsLoose[muonToolsLoose.size() - 1]->recommendedSystematics().getBaseNames()) muonSystematics.push_back(s); + // } + //} + + //for (auto& key : triggersByPeriod) { + // if (triggerCombination.find(key.first) == triggerCombination.end()) { + // triggerCombination[key.first] = ""; + // } else { + // triggerCombination[key.first] += " || "; + // } + // triggerCombination[key.first] += boost::algorithm::join(key.second, " || "); + //} + //for (auto& key : triggersByPeriodLoose) { + // if (triggerCombinationLoose.find(key.first) == triggerCombinationLoose.end()) { + // triggerCombinationLoose[key.first] = ""; + // } else { + // triggerCombinationLoose[key.first] += " || "; + // } + // triggerCombinationLoose[key.first] += boost::algorithm::join(key.second, " || "); + //} + + //// Print out what we configured + //for (auto kv: triggerCombination) ATH_MSG_DEBUG("TRIG (TIGHT): " << kv.first << " -> " << kv.second); + //for (auto kv: triggerCombinationLoose) ATH_MSG_DEBUG("TRIG (LOOSE): " << kv.first << " -> " << kv.second); + + // Make the global trigger tool +// if (m_config->doTightEvents()) { +// TrigGlobalEfficiencyCorrectionTool* globalTriggerEffTool = new TrigGlobalEfficiencyCorrectionTool("TrigGlobalEfficiencyCorrectionTool::TrigGlobal"); +// top::check(globalTriggerEffTool->setProperty("ElectronEfficiencyTools", electronEffTools), "Failed to attach electron efficiency tools"); +// top::check(globalTriggerEffTool->setProperty("ElectronScaleFactorTools", electronSFTools), "Failed to attach electron scale factor tools"); +// top::check(globalTriggerEffTool->setProperty("MuonTools", muonTools), "Failed to attach muon tools"); +// top::check(globalTriggerEffTool->setProperty("ListOfLegsPerTool", legsPerTool), "Failed to define list of legs per tool"); +// top::check(globalTriggerEffTool->setProperty("TriggerCombination", triggerCombination), "Failed to define trigger combination"); +// top::check(globalTriggerEffTool->setProperty("TriggerMatchingTool", m_trigMatchTool), "Failed to set TriggerMatchingTool"); +// // Setting MSG::ERROR to avoid flooding output with invalid efficiency warnings before event selection is complete +// top::check(globalTriggerEffTool->setProperty("OutputLevel", MSG::ERROR), "Failed to set message level"); +// top::check(globalTriggerEffTool->initialize(), "Failed to initalise"); +// m_globalTriggerEffTool = globalTriggerEffTool; +// } +// if (m_config->doLooseEvents()) { +// TrigGlobalEfficiencyCorrectionTool* globalTriggerEffToolLoose = new TrigGlobalEfficiencyCorrectionTool("TrigGlobalEfficiencyCorrectionTool::TrigGlobalLoose"); +// top::check(globalTriggerEffToolLoose->setProperty("ElectronEfficiencyTools", electronEffToolsLoose), "Failed to attach electron efficiency tools"); +// top::check(globalTriggerEffToolLoose->setProperty("ElectronScaleFactorTools", electronSFToolsLoose), "Failed to attach electron scale factor tools"); +// top::check(globalTriggerEffToolLoose->setProperty("MuonTools", muonToolsLoose), "Failed to attach muon tools"); +// top::check(globalTriggerEffToolLoose->setProperty("ListOfLegsPerTool", legsPerToolLoose), "Failed to define list of legs per tool"); +// top::check(globalTriggerEffToolLoose->setProperty("TriggerCombination", triggerCombinationLoose), "Failed to define trigger combination"); +// top::check(globalTriggerEffToolLoose->setProperty("TriggerMatchingTool", m_trigMatchTool), "Failed to set TriggerMatchingTool"); +// // Setting MSG::ERROR to avoid flooding output with invalid efficiency warnings before event selection is complete +// top::check(globalTriggerEffToolLoose->setProperty("OutputLevel", MSG::ERROR), "Failed to set message level"); +// top::check(globalTriggerEffToolLoose->initialize(), "Failed to initalise"); +// m_globalTriggerEffToolLoose = globalTriggerEffToolLoose; +// } + + // Set information about systematics inside TopConfig +// m_config->setGlobalTriggerConfiguration(electronSystematics, muonSystematics, electronToolNames, muonToolNames); + + return statusCode; } - return StatusCode::SUCCESS; -} + std::string TriggerCPTools::mapWorkingPoints(const std::string& type) { + std::string working_point = ""; + // ID + if (type == "LooseAndBLayerLLH" || type == "LooseBLayer" || type == "LooseAndBLayerLH") { + working_point = "LooseBLayer"; + } + if (type == "MediumLLH" || type == "Medium" || type == "MediumLH") { + working_point = "Medium"; + } + if (type == "TightLLH" || type == "Tight" || type == "TightLH") { + working_point = "Tight"; + } + // Temporary ISO map to handle the mess that is EGamma+IFF right now... + if (type.find("Pflow") != std::string::npos) { + ATH_MSG_WARNING("You selected a Pflow isolation WP for at least one of your electron collections - BE WARNED THAT THESE ARE NOT YET READY TO BE RELEASED FOR USE IN PHYSICS ANALYSES AND OF COURSE DON'T HAVE ASSOCIATED SCALE FACTORS YET!!!"); + if (type == "PflowLoose") working_point = "FCLoose"; + if (type == "PflowTight") working_point = "FCTight"; + } + if (type == "Tight") working_point = "FCTight"; + if (type == "Loose") working_point = "FCLoose"; + if (type == "HighPtCaloOnly") working_point = "FCHighPtCaloOnly"; + if (type == "TightTrackOnly") working_point = "Gradient"; + if (type == "TightTrackOnly_FixedRad") working_point = "Gradient"; + if (type == "FCTight" || type == "FCLoose" || type == "FCHighPtCaloOnly" || type == "Gradient") working_point = type; + + return working_point; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopBoostedTaggingCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopBoostedTaggingCPTools.h new file mode 100644 index 000000000000..523d678de379 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopBoostedTaggingCPTools.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TOPCPTOOLS_TOPBOOSTEDTAGGINGCPTOOLS_H_ +#define TOPCPTOOLS_TOPBOOSTEDTAGGINGCPTOOLS_H_ + +// Include what you use +#include <vector> +#include <string> +#include <map> + +// Framework include(s): +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" +#include "AsgTools/ToolHandleArray.h" +#include "AsgTools/AnaToolHandle.h" +#include "JetAnalysisInterfaces/IJetSelectorTool.h" +#include "JetCPInterfaces/ICPJetUncertaintiesTool.h" + +namespace top { + class TopConfig; + + class BoostedTaggingCPTools final: public asg::AsgTool { + public: + explicit BoostedTaggingCPTools(const std::string& name); + virtual ~BoostedTaggingCPTools() {} + + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::unordered_map<std::string, asg::AnaToolHandle<IJetSelectorTool> > m_taggers; + std::unordered_map<std::string, ToolHandle<ICPJetUncertaintiesTool> > m_tagSFuncertTool; + }; +} // namespace top + +#endif // TOPCPTOOLS_TOPBOOSTEDTAGGINGCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopEgammaCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopEgammaCPTools.h index 073366660585..a1623edc12c2 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopEgammaCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopEgammaCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPEGAMMACPTOOLS_H_ #define TOPCPTOOLS_TOPEGAMMACPTOOLS_H_ @@ -21,69 +21,112 @@ #include "EgammaAnalysisInterfaces/IElectronPhotonShowerShapeFudgeTool.h" #include "EgammaAnalysisInterfaces/IAsgPhotonEfficiencyCorrectionTool.h" #include "EgammaAnalysisInterfaces/IAsgPhotonIsEMSelector.h" +//#include "ElectronPhotonSelectorTools/AsgForwardElectronLikelihoodTool.h" +//#include "TrigBunchCrossingTool/WebBunchCrossingTool.h" -namespace top { - -class TopConfig; - -class EgammaCPTools final : public asg::AsgTool { - public: - explicit EgammaCPTools(const std::string& name); - virtual ~EgammaCPTools() {} - - StatusCode initialize(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - int m_release_series = 24; // Default to 2.4 - - std::string m_electronEffTriggerFile; - std::string m_electronEffTriggerLooseFile; - std::string m_electronEffSFTriggerFile; - std::string m_electronEffSFTriggerLooseFile; - std::string m_electronEffSFRecoFile; - std::string m_electronEffSFIDFile; - std::string m_electronEffSFIDLooseFile; - std::string m_electronEffSFIsoFile; - std::string m_electronEffSFIsoLooseFile; - std::string m_electronEffSFChargeIDFile; - - ToolHandle<CP::IEgammaCalibrationAndSmearingTool> m_egammaCalibrationAndSmearingTool; - - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTrigger; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTriggerLoose; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTrigger; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTriggerLoose; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFReco; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFID; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDLoose; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIso; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIsoLoose; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFChargeID; +#include "TopConfiguration/Tokenize.h" - ToolHandle<IElectronPhotonShowerShapeFudgeTool> m_photonFudgeTool; - ToolHandle<IAsgPhotonEfficiencyCorrectionTool> m_photonEffSF; - ToolHandleArray<IAsgPhotonEfficiencyCorrectionTool> m_photonIsoSFTools; - - ToolHandle<IAsgPhotonIsEMSelector> m_photonTightIsEMSelector; - ToolHandle<IAsgPhotonIsEMSelector> m_photonMediumIsEMSelector; - ToolHandle<IAsgPhotonIsEMSelector> m_photonLooseIsEMSelector; - - - - StatusCode setupCalibration(); - StatusCode setupScaleFactors(); - - IAsgElectronEfficiencyCorrectionTool* - setupElectronSFTool(const std::string& name, const std::vector<std::string>& file_list, int data_type); - - // Helper function to deal with path resolving the - // egamma groups very long file names for SFs and efficiencies. - std::string electronSFFilePath(const std::string& type, const std::string& ID = "", const std::string& isolation = ""); - - -}; +namespace top { + class TopConfig; + + class EgammaCPTools final: public asg::AsgTool { + public: + explicit EgammaCPTools(const std::string& name); + virtual ~EgammaCPTools() {} + + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::string m_electronEffTriggerFile; + std::string m_electronEffTriggerLooseFile; + std::string m_electronEffSFTriggerFile; + std::string m_electronEffSFTriggerLooseFile; + std::string m_electronEffSFRecoFile; + std::string m_electronEffSFIDFile; + std::string m_electronEffSFIDLooseFile; + std::string m_electronEffSFIsoFile; + std::string m_electronEffSFIsoLooseFile; + std::string m_electronEffSFChargeIDFile; + std::string m_electronEffSFChargeIDLooseFile; + std::string m_electronEffSFChargeMisIDFile; + std::string m_electronEffSFChargeMisIDLooseFile; + +// std::string m_fwdElectronEffSFIDFile; +// std::string m_fwdElectronEffSFIDLooseFile; + + ToolHandle<CP::IEgammaCalibrationAndSmearingTool> m_egammaCalibrationAndSmearingTool; + + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTrigger; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTriggerLoose; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTrigger; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTriggerLoose; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFReco; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFID; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDLoose; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIso; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIsoLoose; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFChargeID; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFChargeIDLoose; + + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTriggerCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTriggerLooseCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTriggerCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTriggerLooseCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFRecoCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDLooseCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIsoCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIsoLooseCorrModel; + + ToolHandle<IElectronPhotonShowerShapeFudgeTool> m_photonFudgeTool; + ToolHandle<IAsgPhotonEfficiencyCorrectionTool> m_photonEffSF; + ToolHandleArray<IAsgPhotonEfficiencyCorrectionTool> m_photonIsoSFTools; + + ToolHandle<IAsgPhotonIsEMSelector> m_photonTightIsEMSelector; + ToolHandle<IAsgPhotonIsEMSelector> m_photonMediumIsEMSelector; + ToolHandle<IAsgPhotonIsEMSelector> m_photonLooseIsEMSelector; + +// ToolHandle<AsgForwardElectronLikelihoodTool> m_fwdElectronSelector; +// ToolHandle<AsgForwardElectronLikelihoodTool> m_fwdElectronSelectorLoose; +// ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_fwdElectronEffSFID; +// ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_fwdElectronEffSFIDLoose; + +// ToolHandle<Trig::WebBunchCrossingTool> m_webBunchCrossingTool; + + StatusCode setupSelectors(); + StatusCode setupCalibration(); + StatusCode setupScaleFactors(); + + IAsgElectronEfficiencyCorrectionTool* setupElectronSFTool(const std::string& name, + const std::vector<std::string>& file_list, + const int& data_type, + const std::string& correlation_model="TOTAL", + const std::string& correlationModelEtaBinning="", + const std::string& correlationModelEtBinning=""); + + // Helper function to deal with path resolving the + // egamma groups very long file names for SFs and efficiencies. + std::string electronSFFilePath(const std::string& type, const std::string& ID, const std::string& ISO); + + // Helper for using maps from egamma groups + IAsgElectronEfficiencyCorrectionTool* setupElectronSFToolWithMap(const std::string& name, + const std::string& map_path, + const std::string& reco_key, + const std::string& ID_key, + const std::string& iso_key, + const std::string& trigger_key, + const int& data_type, + const std::string& correlationModel, + const std::string& correlationModelEtaBinning, + const std::string& correlationModelEtBinning); + + std::string electronSFMapFilePath(const std::string& type); + void setCorrelationModelBinning(IAsgElectronEfficiencyCorrectionTool* tool, const std::string& binningName, + const std::string& binning); + + std::string mapWorkingPoints(const std::string& type); + }; } // namespace top #endif // TOPCPTOOLS_TOPEGAMMACPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopFlavorTaggingCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopFlavorTaggingCPTools.h index 44ef30105db3..c463b71fe62b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopFlavorTaggingCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopFlavorTaggingCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPFLAVORTAGGINGCPTOOLS_H_ #define TOPCPTOOLS_TOPFLAVORTAGGINGCPTOOLS_H_ @@ -8,6 +8,7 @@ // Include what you use #include <vector> #include <string> +#include <map> // Framework include(s): #include "AsgTools/AsgTool.h" @@ -18,39 +19,50 @@ #include "TopConfiguration/TopConfig.h" // Flavor tagging include(s): -#include "xAODBTaggingEfficiency/IBTaggingEfficiencyTool.h" -#include "xAODBTaggingEfficiency/IBTaggingSelectionTool.h" +#include "FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h" +#include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h" +// Need a pointer for excluded systematic functions +#include "xAODBTaggingEfficiency/BTaggingEfficiencyTool.h" namespace top { + class TopConfig; -class TopConfig; - -class FlavorTaggingCPTools final : public asg::AsgTool { - public: - explicit FlavorTaggingCPTools(const std::string& name); - virtual ~FlavorTaggingCPTools() {} - - StatusCode initialize(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - int m_release_series = 24; // Default to 2.4 - - std::string m_tagger = ""; - std::string m_cdi_file = ""; - std::string m_efficiency_maps; - const std::vector<std::string> m_jet_flavors = {"B", "C", "T", "Light"}; - std::vector<std::string> m_calo_WPs_calib; - std::vector<std::string> m_calo_WPs; - std::vector<std::string> m_trackAntiKt2_WPs_calib; - std::vector<std::string> m_trackAntiKt2_WPs; - std::vector<std::string> m_trackAntiKt4_WPs_calib; - std::vector<std::string> m_trackAntiKt4_WPs; - // Some tools here - ToolHandleArray<IBTaggingEfficiencyTool> m_btagging_efficiency_tools; - ToolHandleArray<IBTaggingSelectionTool> m_btagging_selection_tools; -}; + class FlavorTaggingCPTools final: public asg::AsgTool { + public: + explicit FlavorTaggingCPTools(const std::string& name); + virtual ~FlavorTaggingCPTools() {} + + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::string m_tagger = ""; + std::string m_cdi_file = ""; + std::string m_efficiency_maps; + const std::vector<std::string> m_jet_flavors = { + "B", "C", "T", "Light" + }; + std::vector<std::string> m_calo_WPs_calib; + std::vector<std::string> m_calo_WPs; + std::vector<std::string> m_trackAntiKtVR_WPs_calib; + std::vector<std::string> m_trackAntiKtVR_WPs; + std::vector<std::string> m_trackAntiKt2_WPs_calib; + std::vector<std::string> m_trackAntiKt2_WPs; + std::vector<std::string> m_trackAntiKt4_WPs_calib; + std::vector<std::string> m_trackAntiKt4_WPs; + std::vector<std::string> m_pflow_WPs_calib; + std::vector<std::string> m_pflow_WPs; + // Some tools here + ToolHandleArray<IBTaggingEfficiencyTool> m_btagging_efficiency_tools; + ToolHandleArray<IBTaggingSelectionTool> m_btagging_selection_tools; + // EV decomposition functions + StatusCode checkExcludedSysts(BTaggingEfficiencyTool*, std::string); + void createExcludedSystMapping(std::vector<std::string>); + std::map<std::string, std::string> m_mapped_excluded_systs; + // Helper function for tracking tagger/WP/Calibration + StatusCode setTaggerWorkingPoints(std::string, bool, std::string, std::vector<std::string>); + void printConfigurations(); + }; } // namespace top #endif // TOPCPTOOLS_TOPFLAVORTAGGINGCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopGhostTrackCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopGhostTrackCPTools.h index 9cbc57f50c24..a756e83fbc35 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopGhostTrackCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopGhostTrackCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPGHOSTTRACKCPTOOLS_H_ #define TOPCPTOOLS_TOPGHOSTTRACKCPTOOLS_H_ @@ -22,45 +22,60 @@ #include "InDetTrackSystematicsTools/InDetTrackTruthFilterTool.h" #include "InDetTrackSystematicsTools/InDetTrackTruthOriginTool.h" #include "InDetTrackSystematicsTools/JetTrackFilterTool.h" +#include "InDetTrackSystematicsTools/JetTrackFilterTool.h" +#include "InDetTrackSelectionTool/InDetTrackSelectionTool.h" -namespace top { - -class TopConfig; - -class GhostTrackCPTools final : public asg::AsgTool { - public: - explicit GhostTrackCPTools(const std::string& name); - virtual ~GhostTrackCPTools() {} - - StatusCode initialize(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - int m_release_series = 24; // Default to 2.4 - - std::vector<std::uint32_t> m_runPeriods; - - const std::string m_smearingToolName{"top::GhostTrackCPTools::InDetTrackSmearingTool"}; - const std::string m_biasToolPrefix{"top::GhostTrackCPTools::InDetTrackBiasingTool"}; - const std::string m_truthOriginToolName{"top::GhostTrackCPTools::InDetTrackTruthOriginTool"}; - const std::string m_truthFilterToolName{"top::GhostTrackCPTools::InDetTrackTruthFilterTool"}; - const std::string m_jetTrackFilterToolName{"top::GhostTrackCPTools::JetTrackFilterTool"}; - - ToolHandle<InDet::InDetTrackSmearingTool> m_smearingTool; - ToolHandle<InDet::InDetTrackTruthOriginTool> m_truthOriginTool; - ToolHandle<InDet::InDetTrackTruthFilterTool> m_truthFilterTool; - ToolHandle<InDet::JetTrackFilterTool> m_jetTrackFilterTool; - - std::vector<ToolHandle<InDet::InDetTrackBiasingTool> > m_biasingTool; - - StatusCode setupSmearingTool(); - StatusCode setupBiasingTools(); - StatusCode setupTruthFilterTool(); - StatusCode setupJetTrackFilterTool(); -}; +namespace top { + class TopConfig; + + class GhostTrackCPTools final: public asg::AsgTool { + public: + explicit GhostTrackCPTools(const std::string& name); + virtual ~GhostTrackCPTools() {} + + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::vector<std::uint32_t> m_runPeriods; + + const std::string m_smearingToolName { + "top::GhostTrackCPTools::InDetTrackSmearingTool" + }; + const std::string m_biasToolPrefix { + "top::GhostTrackCPTools::InDetTrackBiasingTool" + }; + const std::string m_truthOriginToolName { + "top::GhostTrackCPTools::InDetTrackTruthOriginTool" + }; + const std::string m_truthFilterToolName { + "top::GhostTrackCPTools::InDetTrackTruthFilterTool" + }; + const std::string m_jetTrackFilterToolName { + "top::GhostTrackCPTools::JetTrackFilterTool" + }; + + const std::string m_TrkSelName { + "top::GhostTrackCPTools::TrkSelTool" + }; + + ToolHandle<InDet::InDetTrackSmearingTool> m_smearingTool; + ToolHandle<InDet::InDetTrackTruthOriginTool> m_truthOriginTool; + ToolHandle<InDet::InDetTrackTruthFilterTool> m_truthFilterTool; + ToolHandle<InDet::JetTrackFilterTool> m_jetTrackFilterTool; + ToolHandle<InDet::InDetTrackSelectionTool> m_trackseltool; + + + std::vector<ToolHandle<InDet::InDetTrackBiasingTool> > m_biasingTool; + + StatusCode setupSmearingTool(); + StatusCode setupBiasingTools(); + StatusCode setupTruthFilterTool(); + StatusCode setupJetTrackFilterTool(); + StatusCode setupSelectionTool(); + }; } // namespace top #endif // TOPCPTOOLS_TOPGHOSTTRACKCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopIsolationCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopIsolationCPTools.h index 86d416765d2e..ec82cd6d167c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopIsolationCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopIsolationCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPISOLATIONCPTOOLS_H_ #define TOPCPTOOLS_TOPISOLATIONCPTOOLS_H_ @@ -17,31 +17,29 @@ // Isolation include(s): #include "IsolationSelection/IIsolationSelectionTool.h" +//#include "IsolationSelection/IIsolationLowPtPLVTool.h" #include "IsolationCorrections/IIsolationCorrectionTool.h" namespace top { + class TopConfig; -class TopConfig; + class IsolationCPTools final: public asg::AsgTool { + public: + explicit IsolationCPTools(const std::string& name); + virtual ~IsolationCPTools() {} -class IsolationCPTools final : public asg::AsgTool { - public: - explicit IsolationCPTools(const std::string& name); - virtual ~IsolationCPTools() {} + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; - StatusCode initialize(); + std::string m_isolationCalibFile; - private: - std::shared_ptr<top::TopConfig> m_config; + ToolHandle<CP::IIsolationCorrectionTool> m_isolationCorr; + ToolHandleArray<CP::IIsolationSelectionTool> m_isolationTools; +// ToolHandleArray<CP::IIsolationLowPtPLVTool> m_isolationToolsLowPtPLV; - int m_release_series = 24; // Default to 2.4 - - std::string m_isolationCalibFile; - - ToolHandle<CP::IIsolationCorrectionTool> m_isolationCorr; - ToolHandleArray<CP::IIsolationSelectionTool> m_isolationTools; - - StatusCode setupIsolation(); -}; + StatusCode setupIsolation(); + }; } // namespace top #endif // TOPCPTOOLS_TOPISOLATIONCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopJetMETCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopJetMETCPTools.h index cf55a3545aec..6f353590e53d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopJetMETCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopJetMETCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPJETMETCPTOOLS_H_ #define TOPCPTOOLS_TOPJETMETCPTOOLS_H_ @@ -8,6 +8,7 @@ // Include what you use #include <vector> #include <string> +#include <cstdlib> // Framework include(s): #include "AsgTools/AsgTool.h" @@ -21,86 +22,95 @@ #include "JetInterface/IJetUpdateJvt.h" #include "JetInterface/IJetSelector.h" #include "JetInterface/IJetModifier.h" -#include "JetResolution/IJERTool.h" -#include "JetResolution/IJERSmearingTool.h" -#include "JetJvtEfficiency/IJetJvtEfficiency.h" +#include "JetAnalysisInterfaces/IJetJvtEfficiency.h" +#include "JetSelectorTools/IEventCleaningTool.h" // MET include(s): #include "METInterface/IMETMaker.h" #include "METInterface/IMETSystematicsTool.h" namespace top { + class TopConfig; -class TopConfig; + class JetMETCPTools final: public asg::AsgTool { + public: + explicit JetMETCPTools(const std::string& name); + virtual ~JetMETCPTools() {} -class JetMETCPTools final : public asg::AsgTool { - public: - explicit JetMETCPTools(const std::string& name); - virtual ~JetMETCPTools() {} + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; - StatusCode initialize(); + std::string m_jetJVT_ConfigFile; + std::string m_truthJetCollForHS; - private: - std::shared_ptr<top::TopConfig> m_config; + std::string m_jetAntiKt4_Data_ConfigFile; + std::string m_jetAntiKt4_Data_CalibSequence; - int m_release_series = 24; // Default to 2.4 + std::string m_jetAntiKt4_MCFS_ConfigFile; + std::string m_jetAntiKt4_MCFS_CalibSequence; - std::string m_jetJVT_ConfigFile; + std::string m_jetAntiKt4_MCAFII_ConfigFile; + std::string m_jetAntiKt4_MCAFII_CalibSequence; - std::string m_jetAntiKt4_Data_ConfigFile; - std::string m_jetAntiKt4_Data_CalibSequence; + std::string m_jetAntiKt4_MCAFII_PFlow_ConfigFile; + std::string m_jetAntiKt4_MCAFII_PFlow_CalibSequence; - std::string m_jetAntiKt4_MCFS_ConfigFile; - std::string m_jetAntiKt4_MCFS_CalibSequence; + std::string m_jetAntiKt4_PFlow_MCFS_ConfigFile; + std::string m_jetAntiKt4_PFlow_MCFS_CalibSequence; - std::string m_jetAntiKt4_MCAFII_ConfigFile; - std::string m_jetAntiKt4_MCAFII_CalibSequence; + std::string m_jetAntiKt4_Data_PFlow_ConfigFile; + std::string m_jetAntiKt4_Data_PFlow_CalibSequence; - std::string m_jetAntiKt4_PFlow_MCFS_ConfigFile; - std::string m_jetAntiKt4_PFlow_MCFS_CalibSequence; + ToolHandle<IJetCalibrationTool> m_jetCalibrationTool; + ToolHandle<IJetCalibrationTool> m_jetCalibrationToolLargeR; - ToolHandle<IJetCalibrationTool> m_jetCalibrationTool; - ToolHandle<IJetCalibrationTool> m_jetCalibrationToolLargeR; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolLargeR; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolLargeR_strong; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolLargeR_medium; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolLargeR_weak; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesTool; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolFrozenJMS; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario1; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario2; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario3; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario4; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesTool; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario1; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario2; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario3; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario4; + ToolHandle<IJetSelector> m_jetCleaningToolLooseBad; + ToolHandle<IJetSelector> m_jetCleaningToolTightBad; - ToolHandle<IJetSelector> m_jetCleaningToolLooseBad; - ToolHandle<IJetSelector> m_jetCleaningToolTightBad; + // Implement event object cleaning tool + ToolHandle<ECUtils::IEventCleaningTool> m_jetEventCleaningToolLooseBad; + ToolHandle<ECUtils::IEventCleaningTool> m_jetEventCleaningToolTightBad; - ToolHandle<IJERTool> m_jetJERTool; - ToolHandle<IJERSmearingTool> m_jetJERSmearingTool; - ToolHandle<IJetUpdateJvt> m_jetUpdateJvtTool; - ToolHandle<IJetModifier> m_fjvtTool; + ToolHandle<IJetUpdateJvt> m_jetUpdateJvtTool; + ToolHandle<IJetModifier> m_jetSelectfJvtTool; - ToolHandle<CP::IJetJvtEfficiency> m_jetJvtTool; + ToolHandle<CP::IJetJvtEfficiency> m_jetJvtTool; + ToolHandle<CP::IJetJvtEfficiency> m_jetfJvtTool; - ToolHandle<IMETMaker> m_met_maker; - ToolHandle<IMETSystematicsTool> m_met_systematics; + ToolHandle<IMETMaker> m_met_maker; + ToolHandle<IMETSystematicsTool> m_met_systematics; - StatusCode setupJetsCalibration(); - StatusCode setupLargeRJetsCalibration(); - StatusCode setupJetsScaleFactors(); - StatusCode setupMET(); + StatusCode setupJetsCalibration(); + StatusCode setupLargeRJetsCalibration(); + StatusCode setupJetsScaleFactors(); + StatusCode setupMET(); - ICPJetUncertaintiesTool* + ICPJetUncertaintiesTool* setupJetUncertaintiesTool(const std::string& name, const std::string& jet_def, const std::string& mc_type, + bool isMC, const std::string& config_file, - std::vector<std::string>* variables); - - IJetSelector* setupJetCleaningTool(const std::string& WP); -}; + std::vector<std::string>* variables, + const std::string& analysis_file = "", + const std::string& calib_area = "None"); + + IJetSelector* setupJetCleaningTool(const std::string& WP); + ECUtils::IEventCleaningTool* setupJetEventCleaningTool(const std::string& WP, + ToolHandle<IJetSelector> JetCleaningToolHandle); + }; } // namespace top #endif // TOPCPTOOLS_TOPJETMETCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopMuonCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopMuonCPTools.h index 3ed0e73dfa51..95381e9c6d68 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopMuonCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopMuonCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPMUONCPTOOLS_H_ #define TOPCPTOOLS_TOPMUONCPTOOLS_H_ @@ -20,54 +20,61 @@ #include "MuonAnalysisInterfaces/IMuonSelectionTool.h" #include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h" #include "MuonAnalysisInterfaces/IMuonEfficiencyScaleFactors.h" +#include "MuonMomentumCorrections/MuonCalibrationPeriodTool.h" namespace top { + class TopConfig; -class TopConfig; + class MuonCPTools final: public asg::AsgTool { + public: + explicit MuonCPTools(const std::string& name); + virtual ~MuonCPTools() {} -class MuonCPTools final : public asg::AsgTool { - public: - explicit MuonCPTools(const std::string& name); - virtual ~MuonCPTools() {} + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; - StatusCode initialize(); + ToolHandle<CP::IMuonCalibrationAndSmearingTool> m_muonCalibrationPeriodTool; - private: - std::shared_ptr<top::TopConfig> m_config; + ToolHandle<CP::IMuonSelectionTool> m_muonSelectionTool; + ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolLoose; + // the following is needed to make sure all muons for which d0sig is calculated are at least Loose + ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolVeryLooseVeto; - int m_release_series = 24; // Default to 2.4 + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_2015; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_2015; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_2016; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_2016; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_R21; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_R21; - ToolHandle<CP::IMuonCalibrationAndSmearingTool> m_muonCalibrationAndSmearingTool; - ToolHandle<CP::IMuonSelectionTool> m_muonSelectionTool; - ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolLoose; - // the following is needed to make sure all muons for which d0sig is calculated are at least Loose - ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolVeryLooseVeto; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsTool; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolLoose; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolIso; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolLooseIso; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolPromptLeptonIso; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolTTVA; - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_2015; - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_2015; - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_2016; - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_2016; + ToolHandle<CP::IMuonSelectionTool> m_softmuonSelectionTool; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_softmuonEfficiencyCorrectionsTool; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsTool; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolLoose; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolIso; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolLooseIso; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolTTVA; + StatusCode setupCalibration(); + StatusCode setupScaleFactors(); - StatusCode setupCalibration(); - StatusCode setupScaleFactors(); + CP::IMuonSelectionTool* + setupMuonSelectionTool(const std::string& name, const std::string& quality, double max_eta, const bool& useMVALowPt, const bool& use2stationMuonsHighPt); - CP::IMuonSelectionTool* - setupMuonSelectionTool(const std::string& name, const std::string& quality, double max_eta); + CP::IMuonTriggerScaleFactors* + setupMuonTrigSFTool(const std::string& name, const std::string& quality); - CP::IMuonTriggerScaleFactors* - setupMuonTrigSFTool(const std::string& name, const std::string& quality, const std::string& year); - - CP::IMuonEfficiencyScaleFactors* + CP::IMuonEfficiencyScaleFactors* setupMuonSFTool(const std::string& name, const std::string& WP); -}; + + CP::IMuonCalibrationAndSmearingTool* + setupMuonCalibrationAndSmearingTool(const std::string& name, const bool& doExtraSmearingHighPt, const bool& do2StationsHighPt); + }; } // namespace top #endif // TOPCPTOOLS_TOPMUONCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopOtherCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopOtherCPTools.h index ff31a0d349a1..d0e1525adc61 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopOtherCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopOtherCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPOTHERCPTOOLS_H_ #define TOPCPTOOLS_TOPOTHERCPTOOLS_H_ @@ -23,31 +23,29 @@ // PMG Tools #include "PMGTools/PMGSherpa22VJetsWeightTool.h" +#include "PMGAnalysisInterfaces/IPMGTruthWeightTool.h" namespace top { - -class TopConfig; - -class OtherCPTools final : public asg::AsgTool { - public: - explicit OtherCPTools(const std::string& name); - virtual ~OtherCPTools() {} - - StatusCode initialize(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - int m_release_series = 24; // Default to 2.4 - - ToolHandle<IGoodRunsListSelectionTool> m_grlTool; - ToolHandle<CP::IPileupReweightingTool> m_pileupReweightingTool; - ToolHandle<PMGTools::PMGSherpa22VJetsWeightTool> m_pmg_sherpa22_vjets_tool; - - StatusCode setupGRL(); - StatusCode setupPileupReweighting(); - StatusCode setupPMGTools(); -}; + class TopConfig; + + class OtherCPTools final: public asg::AsgTool { + public: + explicit OtherCPTools(const std::string& name); + virtual ~OtherCPTools() {} + + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + ToolHandle<IGoodRunsListSelectionTool> m_grlTool; + ToolHandle<CP::IPileupReweightingTool> m_pileupReweightingTool; + ToolHandle<PMGTools::PMGSherpa22VJetsWeightTool> m_pmg_sherpa22_vjets_tool; + ToolHandle<PMGTools::IPMGTruthWeightTool> m_pmg_weightTool; + + StatusCode setupGRL(); + StatusCode setupPileupReweighting(); + StatusCode setupPMGTools(); + }; } // namespace top #endif // TOPCPTOOLS_TOPOTHERCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopOverlapRemovalCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopOverlapRemovalCPTools.h index f37987143de8..e3f9d552d473 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopOverlapRemovalCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopOverlapRemovalCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPOVERLAPREMOVALCPTOOLS_H_ #define TOPCPTOOLS_TOPOVERLAPREMOVALCPTOOLS_H_ @@ -20,28 +20,28 @@ #include "AssociationUtils/ToolBox.h" namespace top { - -class TopConfig; - -class OverlapRemovalCPTools final : public asg::AsgTool { - public: - explicit OverlapRemovalCPTools(const std::string& name); - virtual ~OverlapRemovalCPTools() {} - - StatusCode initialize(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - int m_release_series = 24; // Default to 2.4 - - ORUtils::ToolBox m_ORtoolBox; - ORUtils::ToolBox m_ORtoolBox_Loose; - asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool; - asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool_Loose; - - StatusCode setupOverlapRemoval(); -}; + class TopConfig; + + class OverlapRemovalCPTools final: public asg::AsgTool { + public: + explicit OverlapRemovalCPTools(const std::string& name); + virtual ~OverlapRemovalCPTools() {} + + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + ORUtils::ToolBox m_ORtoolBox; + ORUtils::ToolBox m_ORtoolBox_Loose; + ORUtils::ToolBox m_ORtoolBox_softMuons_PFjets; + ORUtils::ToolBox m_ORtoolBox_softMuons_Alljets; + asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool; + asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool_Loose; + asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool_softMuons_PFjets; + asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool_softMuons_Alljets; + + StatusCode setupOverlapRemoval(); + }; } // namespace top #endif // TOPCPTOOLS_TOPOVERLAPREMOVALCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTauCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTauCPTools.h index 685c3101b4fb..6683cdaab55b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTauCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTauCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPTAUCPTOOLS_H_ #define TOPCPTOOLS_TOPTAUCPTOOLS_H_ @@ -15,38 +15,40 @@ #include "AsgTools/ToolHandleArray.h" #include "AsgTools/AnaToolHandle.h" +//PileupReweighting include: +#include "AsgAnalysisInterfaces/IPileupReweightingTool.h" + // Tau include(s): #include "TauAnalysisTools/ITauSelectionTool.h" #include "TauAnalysisTools/ITauSmearingTool.h" #include "TauAnalysisTools/ITauEfficiencyCorrectionsTool.h" +#include "TauAnalysisTools/ITauTruthMatchingTool.h" namespace top { + class TopConfig; -class TopConfig; - -class TauCPTools final : public asg::AsgTool { - public: - explicit TauCPTools(const std::string& name); - virtual ~TauCPTools() {} - - StatusCode initialize(); - - private: - std::shared_ptr<top::TopConfig> m_config; + class TauCPTools final: public asg::AsgTool { + public: + explicit TauCPTools(const std::string& name); + virtual ~TauCPTools() {} - int m_release_series = 24; // Default to 2.4 + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; - ToolHandle<TauAnalysisTools::ITauSelectionTool> m_tauSelectionTool; - ToolHandle<TauAnalysisTools::ITauEfficiencyCorrectionsTool> m_tauEffCorrTool; + ToolHandle<TauAnalysisTools::ITauSelectionTool> m_tauSelectionTool; + ToolHandle<TauAnalysisTools::ITauEfficiencyCorrectionsTool> m_tauEffCorrTool; + ToolHandle<CP::IPileupReweightingTool> m_pileupReweightingTool; - ToolHandle<TauAnalysisTools::ITauSelectionTool> m_tauSelectionToolLoose; - ToolHandle<TauAnalysisTools::ITauEfficiencyCorrectionsTool> m_tauEffCorrToolLoose; + ToolHandle<TauAnalysisTools::ITauSelectionTool> m_tauSelectionToolLoose; + ToolHandle<TauAnalysisTools::ITauEfficiencyCorrectionsTool> m_tauEffCorrToolLoose; - ToolHandle<TauAnalysisTools::ITauSmearingTool> m_tauSmearingTool; + ToolHandle<TauAnalysisTools::ITauSmearingTool> m_tauSmearingTool; + ToolHandle<TauAnalysisTools::ITauTruthMatchingTool> m_truthMatchingTool; - StatusCode setupCalibration(); - StatusCode setupScaleFactors(); -}; + StatusCode setupCalibration(); + StatusCode setupScaleFactors(); + }; } // namespace top #endif // TOPCPTOOLS_TOPTAUCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopToolStore.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopToolStore.h index ae7f5a0b9800..1475e81458cd 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopToolStore.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopToolStore.h @@ -1,31 +1,38 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -// $Id: TopToolStore.h 802731 2017-04-11 16:35:41Z tpelzer $ +// $Id: TopToolStore.h 808118 2017-07-11 17:41:22Z tpelzer $ #ifndef ANALYSISTOP_TOPCPTOOLS_TOPTOOLSTORE_H #define ANALYSISTOP_TOPCPTOOLS_TOPTOOLSTORE_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief TopToolStore - * Configure all asg::AsgTools and place into asg::ToolStore - * This will allow other tools and algorithms to retrieve the tools - * This means that we can share tools and only configure them once - * - * $Revision: 802731 $ - * $Date: 2017-04-11 18:35:41 +0200 (Tue, 11 Apr 2017) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief TopToolStore + * Configure all asg::AsgTools and place into asg::ToolStore + * This will allow other tools and algorithms to retrieve the tools + * This means that we can share tools and only configure them once + * + * $Revision: 808118 $ + * $Date: 2017-07-11 18:41:22 +0100 (Tue, 11 Jul 2017) $ + * + **/ // system include(s): #include <vector> #include <memory> +// Framework include(s): +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" +#include "AsgTools/AnaToolHandle.h" + // Top includes +#include "TopCPTools/TopTrackCPTools.h" #include "TopCPTools/TopGhostTrackCPTools.h" #include "TopCPTools/TopFlavorTaggingCPTools.h" +#include "TopCPTools/TopBoostedTaggingCPTools.h" #include "TopCPTools/TopEgammaCPTools.h" #include "TopCPTools/TopMuonCPTools.h" #include "TopCPTools/TopIsolationCPTools.h" @@ -35,55 +42,38 @@ #include "TopCPTools/TopOverlapRemovalCPTools.h" #include "TopCPTools/TopOtherCPTools.h" -// Framework include(s): -#include "AsgTools/AsgTool.h" -#include "AsgTools/ToolHandle.h" -#include "AsgTools/AnaToolHandle.h" - -namespace top{ - +namespace top { // Forward declaration(s): class TopConfig; - class OverlapRemovalCPTools; - class OtherCPTools; - class FlavorTaggingCPTools; - class TriggerCPTools; - class EgammaCPTools; - class MuonCPTools; - class IsolationCPTools; - class TauCPTools; - class JetMETCPTools; - - class TopToolStore final : public asg::AsgTool { - public: - explicit TopToolStore( const std::string& name ); - virtual ~TopToolStore() {} - - TopToolStore(const TopToolStore& rhs) = delete; - TopToolStore(TopToolStore&& rhs) = delete; - TopToolStore& operator=(const TopToolStore& rhs) = delete; + class TopToolStore final: public asg::AsgTool { + public: + explicit TopToolStore(const std::string& name); + virtual ~TopToolStore() {} + + TopToolStore(const TopToolStore& rhs) = delete; + TopToolStore(TopToolStore&& rhs) = delete; + TopToolStore& operator = (const TopToolStore& rhs) = delete; + + StatusCode initialize(); + StatusCode finalize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::unique_ptr<OverlapRemovalCPTools> m_OR_CP_tools; + std::unique_ptr<OtherCPTools> m_other_CP_tools; + std::unique_ptr<FlavorTaggingCPTools> m_flavor_tagging_CP_tools; + std::unique_ptr<BoostedTaggingCPTools> m_boosted_tagging_CP_tools; + std::unique_ptr<TriggerCPTools> m_trigger_CP_tools; + std::unique_ptr<EgammaCPTools> m_egamma_CP_tools; + std::unique_ptr<MuonCPTools> m_muon_CP_tools; + std::unique_ptr<IsolationCPTools> m_isolation_CP_tools; + std::unique_ptr<TauCPTools> m_tau_CP_tools; + std::unique_ptr<JetMETCPTools> m_jetMET_CP_tools; + std::unique_ptr<GhostTrackCPTools> m_ghost_track_CP_tools; + std::unique_ptr<TrackCPTools> m_track_CP_tools; - StatusCode initialize(); - StatusCode finalize(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - int m_release_series = 24; // Default to 2.4 - - std::unique_ptr<top::OverlapRemovalCPTools> m_OR_CP_tools; - std::unique_ptr<top::OtherCPTools> m_other_CP_tools; - std::unique_ptr<top::FlavorTaggingCPTools> m_flavor_tagging_CP_tools; - std::unique_ptr<top::TriggerCPTools> m_trigger_CP_tools; - std::unique_ptr<top::EgammaCPTools> m_egamma_CP_tools; - std::unique_ptr<top::MuonCPTools> m_muon_CP_tools; - std::unique_ptr<top::IsolationCPTools> m_isolation_CP_tools; - std::unique_ptr<top::TauCPTools> m_tau_CP_tools; - std::unique_ptr<top::JetMETCPTools> m_jetMET_CP_tools; - std::unique_ptr<top::GhostTrackCPTools> m_ghost_track_CP_tools; }; - } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTrackCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTrackCPTools.h new file mode 100644 index 000000000000..a73eec9711e4 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTrackCPTools.h @@ -0,0 +1,68 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TOPCPTOOLS_TOPTRACKCPTOOLS_H_ +#define TOPCPTOOLS_TOPTRACKCPTOOLS_H_ + +// Include what you use +#include <vector> +#include <string> + +// Framework include(s): +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" +#include "AsgTools/ToolHandleArray.h" +#include "AsgTools/AnaToolHandle.h" + +// Tracking include(s): +#include "InDetTrackSystematicsTools/InDetTrackSystematics.h" +#include "InDetTrackSystematicsTools/InDetTrackSmearingTool.h" +#include "InDetTrackSystematicsTools/InDetTrackBiasingTool.h" +#include "InDetTrackSystematicsTools/InDetTrackTruthFilterTool.h" +#include "InDetTrackSystematicsTools/InDetTrackTruthOriginTool.h" +#include "InDetTrackSelectionTool/InDetTrackSelectionTool.h" + +namespace top { + class TopConfig; + + class TrackCPTools final: public asg::AsgTool { + public: + explicit TrackCPTools(const std::string& name); + virtual ~TrackCPTools() {} + + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::vector<std::uint32_t> m_runPeriods; + + const std::string m_smearingToolName { + "top::TrackCPTools::InDetTrackSmearingTool" + }; + const std::string m_biasToolPrefix { + "top::TrackCPTools::InDetTrackBiasingTool" + }; + const std::string m_truthOriginToolName { + "top::TrackCPTools::InDetTrackTruthOriginTool" + }; + const std::string m_truthFilterToolName { + "top::TrackCPTools::InDetTrackTruthFilterTool" + }; + + ToolHandle<InDet::InDetTrackSmearingTool> m_smearingTool; + ToolHandle<InDet::InDetTrackTruthOriginTool> m_truthOriginTool; + ToolHandle<InDet::InDetTrackTruthFilterTool> m_truthFilterTool; + + ToolHandle<InDet::IInDetTrackSelectionTool> m_trkseltool; + + std::vector<ToolHandle<InDet::InDetTrackBiasingTool> > m_biasingTool; + + StatusCode setupSmearingTool(); + StatusCode setupBiasingTools(); + StatusCode setupTruthFilterTool(); + + }; +} // namespace top + +#endif // TOPCPTOOLS_TOPTRACKCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTriggerCPTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTriggerCPTools.h index 5a62acbfc49c..360014344fe2 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTriggerCPTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/TopCPTools/TopTriggerCPTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCPTOOLS_TOPTRIGGERCPTOOLS_H_ #define TOPCPTOOLS_TOPTRIGGERCPTOOLS_H_ @@ -20,29 +20,38 @@ #include "TrigDecisionTool/TrigDecisionTool.h" #include "TriggerMatchingTool/IMatchingTool.h" #include "TrigTauMatching/ITrigTauMatching.h" +//#include "TriggerAnalysisInterfaces/ITrigGlobalEfficiencyCorrectionTool.h" +// Need to have these tools held in the class +#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h" +#include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h" namespace top { - -class TopConfig; - -class TriggerCPTools final : public asg::AsgTool { - public: - explicit TriggerCPTools(const std::string& name); - virtual ~TriggerCPTools() {} - - StatusCode initialize(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - int m_release_series = 24; // Default to 2.4 - - ToolHandle<TrigConf::ITrigConfigTool> m_trigConfTool; - ToolHandle<Trig::TrigDecisionTool> m_trigDecisionTool; - ToolHandle<Trig::IMatchingTool> m_trigMatchTool; - ToolHandle<Trig::ITrigTauMatchingTool> m_trigMatchTauTool; - -}; + class TopConfig; + + class TriggerCPTools final: public asg::AsgTool { + public: + explicit TriggerCPTools(const std::string& name); + virtual ~TriggerCPTools() {} + + StatusCode initialize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + ToolHandle<TrigConf::ITrigConfigTool> m_trigConfTool; + ToolHandle<Trig::TrigDecisionTool> m_trigDecisionTool; + ToolHandle<Trig::IMatchingTool> m_trigMatchTool; + ToolHandle<Trig::ITrigTauMatchingTool> m_trigMatchTauTool; +// ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerEffTool; +// ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerEffToolLoose; + StatusCode initialiseGlobalTriggerEff(); + std::string mapWorkingPoints(const std::string& type); + + // Tool handles for the CP tools, need to be members here, or inaccessible to global trigger tool + asg::AnaToolHandle<CP::IMuonTriggerScaleFactors> m_muonTool; + asg::AnaToolHandle<CP::IMuonTriggerScaleFactors> m_muonToolLoose; + std::vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool> > m_electronToolsFactory; + std::vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool> > m_electronToolsFactoryLoose; + }; } // namespace top #endif // TOPCPTOOLS_TOPTRIGGERCPTOOLS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/CMakeLists.txt index 4f7b254566bd..788d9749ce76 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/CMakeLists.txt @@ -1,34 +1,43 @@ +# Auto-generated on: 2017-03-08 14:47:35.608258 # Declare the name of this package: -atlas_subdir( TopConfiguration ) +atlas_subdir( TopConfiguration None ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC + xAODCore + Tools/PathResolver + TopDataPreparation PATInterfaces ) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) -find_package( Boost REQUIRED COMPONENTS iostreams ) +find_package( Boost REQUIRED COMPONENTS iostreams regex ) + +message( STATUS "${Boost_LIBRARIES}" ) # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopConfiguration _cintDictSource - ROOT_HEADERS TopConfiguration/TopPersistentSettings.h Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) # Build a library that other components can link against: atlas_add_library( TopConfiguration Root/*.cxx Root/*.h Root/*.icc TopConfiguration/*.h TopConfiguration/*.icc TopConfiguration/*/*.h TopConfiguration/*/*.icc ${_cintDictSource} PUBLIC_HEADERS TopConfiguration - LINK_LIBRARIES PATInterfaces + LINK_LIBRARIES xAODCore + PATInterfaces + PathResolver + TopDataPreparation ${ROOT_LIBRARIES} - ${Boost_LIBRARIES} - INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS}) + ${Boost_LIBRARIES} + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS}) # Install data files from the package: atlas_install_data( share/* ) # Install the python modules from the package -atlas_install_python_modules( python/*.py ) +atlas_install_scripts( python/AodMetaDataReader.py ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/AodMetaDataAccess.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/AodMetaDataAccess.cxx index 621dd8fb9269..0797bca977b0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/AodMetaDataAccess.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/AodMetaDataAccess.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopConfiguration/AodMetaDataAccess.h" @@ -14,132 +14,145 @@ #include <unistd.h> #include <utility> #include <vector> +#include <string> +#include <iostream> #include <boost/algorithm/string.hpp> #include <boost/iostreams/device/file_descriptor.hpp> #include <boost/iostreams/stream.hpp> #include <boost/scope_exit.hpp> +#include "PathResolver/PathResolver.h" -namespace top { - +#include "TopConfiguration/MsgCategory.h" +using namespace TopConfiguration; -AodMetaDataAccess::AodMetaDataAccess() : m_data(nullptr) { } +namespace top { + AodMetaDataAccess::AodMetaDataAccess() : m_data(nullptr) { } -AodMetaDataAccess::~AodMetaDataAccess() { - delete m_data; -} + AodMetaDataAccess::~AodMetaDataAccess() { + delete m_data; + } + void AodMetaDataAccess::loadWithFilesFrom(std::string const& fileListPath) { + // Implementation using PathResolver + std::string filename = "AodMetaDataReader.py"; + // Use the path resolver to find the script which is stored as an executable in bin (no package name) + std::string exePath = PathResolver::find_file(filename, "PATH"); -void AodMetaDataAccess::loadWithFilesFrom(std::string const & fileListPath) { + if (exePath == "") { + throw std::runtime_error("ERROR::AodMetaDataAccess - could not find file \n" + filename); + } + ATH_MSG_INFO("AodMetaDataAccess::Found " << exePath); - char const * rootCoreBin = getenv("ROOTCOREBIN"); - assert(rootCoreBin && rootCoreBin[0]); - std::string exePath(rootCoreBin); - if (exePath.back() != '/') - exePath.append("/"); - exePath.append("python/TopConfiguration/AodMetaDataReader.py"); - int pipefd[2] = { -1, -1 }; - if (pipe(pipefd) == -1) - throw std::runtime_error("pipe() failed"); - int pid = fork(); - if (pid == -1) { - std::for_each(pipefd, pipefd+2, close); + int pipefd[2] = { + -1, -1 + }; + if (pipe(pipefd) == -1) throw std::runtime_error("pipe() failed"); + int pid = fork(); + if (pid == -1) { + std::for_each(pipefd, pipefd + 2, close); throw std::runtime_error("fork() failed"); - } + } - if (pid == 0) { + if (pid == 0) { close(pipefd[0]); - if (dup2(pipefd[1], STDOUT_FILENO) != -1) - execlp(exePath.c_str(), "AodMetaDataReader.py", "--format", "plain", "--files-from", fileListPath.c_str(), nullptr); + if (dup2(pipefd[1], STDOUT_FILENO) != -1) execlp( + exePath.c_str(), "AodMetaDataReader.py", "--format", "plain", "--files-from", fileListPath.c_str(), nullptr); perror("popen(AodMetaDataReader.py)"); _exit(1); - } + } - BOOST_SCOPE_EXIT(pid) { + BOOST_SCOPE_EXIT(pid) { int status; - while (waitpid(pid, &status, 0) == -1 && errno == EINTR); - } BOOST_SCOPE_EXIT_END - close(pipefd[1]); - - boost::iostreams::stream<boost::iostreams::file_descriptor_source> stream(pipefd[0], boost::iostreams::close_handle); - - auto * data = new std::map< std::string, std::map< std::string, std::string > >(); // FIXME memory leak on exception - bool eof = false; - for (std::string line; std::getline(stream, line); ) { - if (eof) - throw std::runtime_error("received data from AodMetaDataReader after end-of-stream marker"); - if (line.empty()) { - eof = true; - } - else { - std::vector<std::string> tokens; - boost::split(tokens, line, boost::is_any_of("\t")); - if (tokens.size() != 3) - throw std::runtime_error("received malformed record from AodMetaDataReader"); - auto & folder = (*data)[tokens[0]]; - bool inserted = folder.insert(std::make_pair(tokens[1], tokens[2])).second; - if (!inserted) - throw std::runtime_error("received duplicate entry from AodMetaDataReader"); - } - } - if (!eof) - throw std::runtime_error("data stream from AodMetaDataReader not properly terminated"); - m_data = data; -} + while (waitpid(pid, &status, 0) == -1 && errno == EINTR) ; + } BOOST_SCOPE_EXIT_END + close(pipefd[1]); -std::string AodMetaDataAccess::get(std::string const & folderName, std::string const & keyName) const { - if (m_data == nullptr) - throw std::logic_error("meta-data not loaded"); - auto it1 = m_data->find(folderName); - if (it1 == m_data->end()) - throw std::logic_error("the folderName "+folderName+" does not exist in the metadata"); - auto const & folder = it1->second; - auto it2 = folder.find(keyName); - if (it2 == folder.end()) - throw std::logic_error("the keyName "+keyName+" does not exist in the metadata"); - - return m_data->at(folderName).at(keyName); -} - - -std::string AodMetaDataAccess::get(std::string const & folderName, std::string const & keyName, std::string const & defaultValue) const { - if (m_data == nullptr) - throw std::logic_error("meta-data not loaded"); - auto it1 = m_data->find(folderName); - if (it1 == m_data->end()) - return defaultValue; - auto const & folder = it1->second; - auto it2 = folder.find(keyName); - if (it2 == folder.end()) - return defaultValue; - return it2->second; -} + boost::iostreams::stream<boost::iostreams::file_descriptor_source> stream(pipefd[0], + boost::iostreams::close_handle); + auto* data = new std::map< std::string, std::map< std::string, std::string > >(); // FIXME memory leak on exception + bool eof = false; + for (std::string line; std::getline(stream, line); ) { + if (eof) throw std::runtime_error("received data from AodMetaDataReader after end-of-stream marker"); + if (line.empty()) { + eof = true; + } else { + std::vector<std::string> tokens; + boost::split(tokens, line, boost::is_any_of("\t")); + if (tokens.size() != 3) throw std::runtime_error("received malformed record from AodMetaDataReader"); + auto& folder = (*data)[tokens[0]]; + bool inserted = folder.insert(std::make_pair(tokens[1], tokens[2])).second; + if (!inserted) throw std::runtime_error("received duplicate entry from AodMetaDataReader"); + } + } + if (!eof) throw std::runtime_error("data stream from AodMetaDataReader not properly terminated"); + m_data = data; + } + + std::string AodMetaDataAccess::get(std::string const& folderName, std::string const& keyName) const { + if (m_data == nullptr) throw std::logic_error("meta-data not loaded"); + auto it1 = m_data->find(folderName); + if (it1 == + m_data->end()) throw std::logic_error("the folderName " + folderName + " does not exist in the metadata"); + auto const& folder = it1->second; + auto it2 = folder.find(keyName); + if (it2 == folder.end()) throw std::logic_error("the keyName " + keyName + " does not exist in the metadata"); + + return m_data->at(folderName).at(keyName); + } + + std::string AodMetaDataAccess::get(std::string const& folderName, std::string const& keyName, + std::string const& defaultValue) const { + if (m_data == nullptr) throw std::logic_error("meta-data not loaded"); + auto it1 = m_data->find(folderName); + if (it1 == m_data->end()) return defaultValue; + + auto const& folder = it1->second; + auto it2 = folder.find(keyName); + if (it2 == folder.end()) return defaultValue; + + return it2->second; + } + + bool AodMetaDataAccess::valid() const { + return(m_data != nullptr); + } + + bool AodMetaDataAccess::isSimulation() const { + auto projectName = get("/TagInfo", "project_name"); + + if (boost::equals(projectName, "IS_SIMULATION")) return true; + + if (boost::starts_with(projectName, "data")) return false; + + throw std::invalid_argument("unrecognized value in meta-data entry for key 'project_name'"); + } + + bool AodMetaDataAccess::IsEventOverlayInputSim() const { + std::string overlay; + try { + overlay = get("/Simulation/Parameters", "IsEventOverlayInputSim"); + } catch (const std::logic_error& e) { + // the key does not exists - is data most likely + return false; + } -bool AodMetaDataAccess::valid() const { - return (m_data != nullptr); -} + if (boost::iequals(overlay, "TRUE")) return true; + + return false; + } + bool AodMetaDataAccess::isAFII() const { + if (!isSimulation()) return false; // No need to check if not MC -bool AodMetaDataAccess::isSimulation() const { - auto projectName = get("/TagInfo", "project_name"); - if (boost::equals(projectName, "IS_SIMULATION")) + auto simulatorName = get("/Simulation/Parameters", "Simulator"); + if (boost::equals(simulatorName, "ATLFASTII")) // AFII will have this simulator return true; - if (boost::starts_with(projectName, "data")) - return false; - throw std::invalid_argument("unrecognized value in meta-data entry for key 'project_name'"); -} - -bool AodMetaDataAccess::isAFII() const{ - if (!isSimulation()) return false; // No need to check if not MC - auto simulatorName = get("/Simulation/Parameters","Simulator"); - if (boost::equals(simulatorName, "ATLFASTII")) // AFII will have this simulator - return true; - else return false; // Otherwise must be FullSim -} - + else return false; // Otherwise must be FullSim + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx index e6ec9d370c87..c519b907ff5c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopConfiguration/ConfigurationSettings.h" @@ -14,232 +14,507 @@ #include <boost/algorithm/string/trim_all.hpp> namespace top { + ConfigurationSettings* ConfigurationSettings::m_instance = 0; -ConfigurationSettings* ConfigurationSettings::m_instance = 0; - -ConfigurationSettings::ConfigurationSettings() : m_configured(false) { + ConfigurationSettings::ConfigurationSettings() : m_configured(false) { registerParameter("ElectronCollectionName", "Name of the Electron container"); + registerParameter("FwdElectronCollectionName", "Name of the Forward Electrons container, ForwardElectrons or None (default)", "None"); registerParameter("MuonCollectionName", "Name of the Muon container"); registerParameter("PhotonCollectionName", "Name of the Photon container"); registerParameter("JetCollectionName", "Name of the Jet container"); registerParameter("LargeJetCollectionName", "Name of the large-R Jet container"); - registerParameter("LargeJetSubstructure", "Setup to use when applying grooming on the large-R jet"); - registerParameter("TrackJetCollectionName", "Name of the track Jet container","None"); + registerParameter("LargeJetSubstructure", "Setup to use when applying grooming on the large-R jet", "None"); + registerParameter("TrackJetCollectionName", "Name of the track Jet container", "None"); + registerParameter("TrackCollectionName", "Name of the track container", "None"); registerParameter("TauCollectionName", "Name of the Tau container"); registerParameter("JetGhostTrackDecoName", "Name of the jet decoration that holds the ghost-associated track.", "None"); registerParameter("TruthCollectionName", "Name of the Truth container"); - registerParameter("TruthElectronCollectionName", "Name of the Truth Electron container", "TruthElectrons" ); + registerParameter("TruthElectronCollectionName", "Name of the Truth Electron container", "TruthElectrons"); registerParameter("TruthMuonCollectionName", "Name of the Truth Muon container", "TruthMuons"); registerParameter("TruthPhotonCollectionName", "Name of the Truth Photon container", "None"); registerParameter("TruthMETCollectionName", "Name of the Truth MET container", "MET_Truth"); registerParameter("TruthJetCollectionName", "Name of the Truth Jet container"); registerParameter("TruthLargeRJetCollectionName", "Name of the Truth Large R Jet container", "None"); + registerParameter("TruthTauCollectionName", "Name of the Truth tau container", "None"); registerParameter("applyTTVACut", "Decide if to apply lepton z0/d0 cuts", "True"); - - registerParameter("GRLDir","Location of GRL File","TopAnalysis"); - registerParameter("GRLFile","Name of GRL File", " "); - registerParameter("DumpBtagSystsInSystTrees", "Dump systematics-shifted b-tagging SFs in systematic TTrees, True or False (default: False)","False"); + registerParameter("GRLDir", "Location of GRL File", "TopAnalysis"); + registerParameter("GRLFile", "Name of GRL File", " "); + + registerParameter("TDPPath", "Path to TopDataPreparation file (accessible via PathResolver)", + "dev/AnalysisTop/TopDataPreparation/XSection-MC16-13TeV.data"); - registerParameter("ElectronID", "Type of electron. IsEM : Loose, Medium, Tight or Likelihood LooseAndBLayerLH, MediumLH, TightLH","TightLH"); - registerParameter("ElectronIDLoose", "Type of electron for background. IsEM : Loose, Medium, Tight or Likelihood LooseAndBLayerLH, MediumLH, TightLH","MediumLH"); + registerParameter("DumpBtagSystsInSystTrees", + "Dump systematics-shifted b-tagging SFs in systematic TTrees, True or False (default: False)", + "False"); + registerParameter("StorePerJetBtagSFs", "Store per-jet btag SFs", "False"); + + registerParameter("ElectronID", "Type of electron. Likelihood LooseAndBLayerLH, MediumLH, TightLH", "TightLH"); + registerParameter("ElectronIDLoose", + "Type of electron for background. Likelihood LooseAndBLayerLH, MediumLH, TightLH", "MediumLH"); registerParameter("ElectronPt", "Electron pT cut for object selection (in MeV). Default 25 GeV.", "25000."); - registerParameter("EgammaSystematicModel","Egamma Systematic model : FULL_v1 , FULL_ETACORRELATED_v1 , 1NP_v1 (default)","1NP_v1"); - registerParameter("ElectronIsolation","Isolation to use : Gradient, GradientLoose, FixedCutTight, FixedCutTightTrackOnly, FixedCutLoose, LooseTrackOnly, Loose, Tight, None","Gradient"); - registerParameter("ElectronIsolationLoose","Isolation to use : Gradient, GradientLoose, FixedCutTight, FixedCutTightTrackOnly, FixedCutLoose, LooseTrackOnly, Loose, Tight, None","None"); - registerParameter("ElectronIsoSFs", "True/False. Set to False to allow unsupported ID/isolation WP combinations to be used.", "True"); - registerParameter("ElectronVetoLArCrack", "True/False. Set to False to disable LAr crack veto (not recommended).", "True"); + registerParameter("EgammaSystematicModel", "Egamma Calibration Systematic model : FULL_v1 , 1NP_v1 (default)", + "1NP_v1"); + registerParameter("ElectronEfficiencySystematicModel", + "Electron Efficiency Systematic model : FULL, SIMPLIFIED, TOTAL (default)", "TOTAL"); + registerParameter("ElectronEfficiencySystematicModelEtaBinning", + "Electron Efficiency Systematic model eta binning (option for SIMPLIFIED model, do not specify to use default; format XXX:YYY:ZZZ, e.g. 0.0:1.37:4.9)", + "default"); + registerParameter("ElectronEfficiencySystematicModelEtBinning", + "Electron Efficiency Systematic model E_T binning (option for SIMPLIFIED model, do not specify to use default; format XXX:YYY:ZZZ. e.g. 4000:7000:10000:15000:13000000)", + "default"); + registerParameter("ElectronIsolation", + "Isolation to use : Gradient, FCLoose, FCTight, FCHighPtCaloOnly, PLVTight, PLVLoose, (EXPERIMENTAL: HighPtCaloOnly, Loose, Tight, TightTrackOnly, TightTrackOnly_FixedRad), (DANGEROUS: PflowTight, PflowLoose), None", + "FCTight"); + registerParameter("ElectronIsolationLoose", + "Isolation to use : Gradient, FCLoose, FCTight, FCHighPtCaloOnly, PLVTight, PLVLoose, (EXPERIMENTAL: HighPtCaloOnly, Loose, Tight, TightTrackOnly, TightTrackOnly_FixedRad), (DANGEROUS: PflowTight, PflowLoose), None", + "None"); + registerParameter("ElectronIsolationSF", "Force electron isolation SF (e.g. None). EXPERIMENTAL!", " "); + registerParameter("ElectronIsolationSFLoose", "Force electron isolation SF (e.g. None). EXPERIMENTAL!", " "); + registerParameter("ElectronVetoLArCrack", "True/False. Set to False to disable LAr crack veto (not recommended).", + "True"); + registerParameter("UseElectronChargeIDSelection", + "True/False. Switch on/off electron charge ID selection (Default False).", "False"); + registerParameter("UseEgammaLeakageCorrection", + "True/False. Switch on/off leakage correction -- REQUIRES ptag>p3947 (Default True).", "True"); + registerParameter("EnablePromptLeptonImprovedVetoStudies", + "True/False. Adds the (many!) variables necessary to validate the PromptLeptonImprovedVeto electron+muon isolation -- TEMPORARY, for studies only (Default False).", "False"); + + registerParameter("FwdElectronID", "Type of fwd electron. Loose, Medium, Tight (default)", "Tight"); + registerParameter("FwdElectronIDLoose", "Type of fwd loose electrons. Loose, Medium, Tight (default)", "Tight"); + registerParameter("FwdElectronPt", "Fwd Electron pT cut for object selection (in MeV). Default 25 GeV.", "25000."); + registerParameter("FwdElectronMinEta", "Fwd Electron lower |eta| cut for object selection. Default 2.5", "2.5"); + registerParameter("FwdElectronMaxEta", "Fwd Electron upper |eta| cut for object selection. Default 4.9", "4.9"); + registerParameter("FwdElectronBCIDCleaningRunRange", + "Specify run range for which the BCID cleaning must be applied for fwd el. in data: \"XXX:YYY\"; the cleaning will be applied for XXX<=runNumber<=YYY", + "266904:311481"); + registerParameter("PhotonPt", "Photon pT cut for object selection (in MeV). Default 25 GeV.", "25000."); registerParameter("PhotonEta", "Absolute Photon eta cut for object selection. Default 2.5.", "2.5"); - registerParameter("PhotonID","Type of photon. Definition to use : Tight, Loose and None.","Tight"); - registerParameter("PhotonIDLoose","Type of photon for background. Definition to use : Tight, Loose, None.","Loose"); - registerParameter("PhotonIsolation","Isolation to use : FixedCutTight, FixedCutLoose, None.","FixedCutTight"); - registerParameter("PhotonIsolationLoose","Isolation to use : FixedCutTight, FixedCutLoose, None.","FixedCutLoose"); - registerParameter("PhotonUseRadiativeZ", "True/False. Set to True to enable photon radiative Z up to 100 GeV.", "False"); + registerParameter("PhotonID", "Type of photon. Definition to use : Tight, Loose and None.", "Tight"); + registerParameter("PhotonIDLoose", "Type of photon for background. Definition to use : Tight, Loose, None.", + "Loose"); + registerParameter("PhotonIsolation", + "Isolation to use : FixedCutTightCaloOnly, FixedCutTight, FixedCutLoose, (EXPERIMENTAL: TightCaloOnly, Tight, Loose), None.", + "FixedCutTight"); + registerParameter("PhotonIsolationLoose", + "Isolation to use : FixedCutTightCaloOnly, FixedCutTight, FixedCutLoose, (EXPERIMENTAL: TightCaloOnly, Tight, Loose), None.", + "FixedCutLoose"); registerParameter("MuonPt", "Muon pT cut for object selection (in MeV). Default 25 GeV.", "25000"); - registerParameter("MuonEta", "Absolute Muon eta cut for object selection. Default 2.5.", "2.5" ); - registerParameter("MuonQuality", "Muon quality cut for object selection. Options are VeryLoose, Loose, Medium (default) and Tight", "Medium"); - registerParameter("MuonQualityLoose", "Muon quality cut for object selection. Options are VeryLoose, Loose, Medium (default) and Tight", "Medium"); - registerParameter("MuonIsolation","Isolation to use : Gradient, GradientLoose, Tight, Loose, LooseTrackOnly, FixedCutTightTrackOnly, FixedCutLoose, None","Gradient"); - registerParameter("MuonIsolationLoose","Isolation to use : Gradient, GradientLoose, Tight, Loose, LooseTrackOnly, FixedCutTightTrackOnly, FixedCutLoose, None","None"); + registerParameter("MuonEta", "Absolute Muon eta cut for object selection. Default 2.5.", "2.5"); + registerParameter("MuonQuality", + "Muon quality cut for object selection. Options are VeryLoose, Loose, Medium (default) and Tight", + "Medium"); + registerParameter("MuonQualityLoose", + "Muon quality cut for object selection. Options are VeryLoose, Loose, Medium (default) and Tight", + "Medium"); + registerParameter("MuonUseMVALowPt", + "Turn on MVA for low-pT muons (only for LowPt WP). Optimized to improve efficiency and hadron rejection. - Default: False", + "False"); + registerParameter("MuonUse2stationHighPt", + "Allows muon reconstruction using 2-station muons with missing inner MS station for |eta|<1.3 - Default: True (only for HighPt)", + "True"); + registerParameter("MuonUseMVALowPtLoose", + "Turn on MVA for low-pT muons (only for LowPt WP) for Loose tree. Optimized to improve efficiency and hadron rejection. - Default: False", + "False"); + registerParameter("MuonUse2stationHighPtLoose", + "Allows muon reconstruction using 2-station muons with missing inner MS station for |eta|<1.3 for Loose tree - Default: True (only for HighPt)", + "True"); + registerParameter("MuonIsolation", + "Isolation to use : PflowTight_VarRad, PflowTight_FixedRad, PflowLoose_VarRad, PflowLoose_FixedRad, HighPtTrackOnly, TightTrackOnly_VarRad, TightTrackOnly_FixedRad, PLVTight, PLVLoose, Tight_VarRad, Tight_FixedRad, Loose_VarRad, Loose_FixedRad, FCTight, FCLoose, FCTightTrackOnly, FCTightTrackOnly_FixedRad, FCLoose_FixedRad, FCTight_FixedRad, FixedCutPflowTight, FixedCutPflowLoose, FCTight_FixedRad, None", + "PflowTight_FixedRad"); + registerParameter("MuonIsolationLoose", + "Isolation to use : PflowTight_VarRad, PflowTight_FixedRad, PflowLoose_VarRad, PflowLoose_FixedRad, HighPtTrackOnly, TightTrackOnly_VarRad, TightTrackOnly_FixedRad, PLVTight, PLVLoose, Tight_VarRad, Tight_FixedRad, Loose_VarRad, Loose_FixedRad, FCTight, FCLoose, FCTightTrackOnly, FCTightTrackOnly_FixedRad, FCLoose_FixedRad, FCTight_FixedRad, FixedCutPflowTight, FixedCutPflowLoose, FCTight_FixedRad, None", + "None"); + registerParameter("MuonIsolationSF", "Force muon isolation SF (e.g. None). EXPERIMENTAL!", " "); + registerParameter("MuonIsolationSFLoose", "Force muon isolation SF (e.g. None). EXPERIMENTAL!", " "); + registerParameter("MuonDoSmearing2stationHighPt", "True/False, to turn on/off spacial corrections for 2-station muons reconstruction with missing inner MS station allowed for abs(eta)<1.3, only with MuonQuality HighPt. - Default: True", "True"); + registerParameter("MuonDoExtraSmearingHighPt", "True/False, To be used by analyses willing to check their sensitivity to momentum resolution effects at large muon momenta. - Default: false", "false"); registerParameter("UseAntiMuons", "Use AntiMuons for fake estimate. Default: false", "false"); + registerParameter("UseSoftMuons", "True to use soft muons, False (default) otherwise", "False"); + registerParameter("SoftMuonPt", "Soft Muon pT cut for object selection (in MeV). Default 4 GeV.", "4000"); + registerParameter("SoftMuonEta", "Absolute Soft Muon eta cut for object selection. Default 2.5.", "2.5"); + registerParameter("SoftMuonQuality", + "Soft Muon quality cut for object selection. Options are Loose, Medium, Tight (default), LowPt", + "Tight"); + registerParameter("SoftMuonUseMVALowPt", + "Turn on MVA for low-pT soft muons (only for LowPt WP). Optimized to improve efficiency and hadron rejection. - Default: False", + "False"); + registerParameter("SoftMuonDRJet", + "Soft Muon maximum dR wrt nearest selected jet. Can be set to 999. to keep all soft muons. Default 0.4", + "0.4"); + registerParameter("SoftMuonDRJetUseRapidity", + "How to calculate DR(soft muon,jet) for the SoftMuonDRJet cut: True -> use rapidity; False -> use pseudorapidity. Default False", + "False"); + registerParameter("SoftMuonAdditionalTruthInfo", + "Experimental: store additional truth information on soft muons particle-level origin: True or False (default)", + "False"); + registerParameter("SoftMuonAdditionalTruthInfoCheckPartonOrigin", + "Experimental: store additional truth information on soft muons parton-level origin; requires SoftMuonAdditionalTruthInfo to be true; automatically disabled if PS!=pythia8 and PS!=herwigpp : True or False (default)", + "False"); + registerParameter("SoftMuonAdditionalTruthInfoDoVerbose", + "Debug output for soft muon additional truth-level information: True or False (default)", + "False"); registerParameter("JetPt", "Jet pT cut for object selection (in MeV). Default 25 GeV.", "25000."); - registerParameter("JetEta", "Absolute Jet eta cut for object selection. Default 2.5.", "2.5" ); - registerParameter("FwdJetAndMET", "Forward jet selection and corresponding MET calculation." - "Default (does nothing on forward jets), fJVT (apply fJVT cut if pT<50GeV and |eta|>2.5), Tight (requires pT>30GeV if |eta|>2.5).", "Default"); - registerParameter("JetUncertainties_BunchSpacing", - "25ns (default) or 50ns - for JetUncertainties", - "25ns"); -// registerParameter("JetUncertainties_NPModel","AllNuisanceParameters, 19NP or 3NP (default) - for JetUncertainties","3NP"); - registerParameter("JetUncertainties_NPModel","AllNuisanceParameters, 29NP_ByCategory, or 21NP (default) - for JetUncertainties","21NP"); - registerParameter("LargeRSmallRCorrelations", - "Do large-small R jet correlation systematics - True or False (default)", - "False"); - registerParameter("JetJERSmearingModel","Full (inc data smearing) or Simple (default)","Simple"); - registerParameter("JetCalibSequence","Jet calibaration sequence, GSC (default) or JMS","GSC"); - registerParameter("JVTinMETCalculation", "Perfom a JVT cut on the jets in the MET recalculation? True (default) or False.", "True" ); - - registerParameter("JSF", "Used for top mass analysis, default is 1.0", "1.0"); + registerParameter("JetEta", "Absolute Jet eta cut for object selection. Default 2.5.", "2.5"); + + registerParameter("JVTinMETCalculation", + "Perfom a JVT cut on the jets in the MET recalculation? True (default) or False.", "True"); + registerParameter("SaveFailJVTJets", "Save the jets that failed the JVT cut? False (default) or True.", "False"); + registerParameter("JVTWP", "Set JVT WP, default is set to \'Default\' (Tight for PFlow and Medium for Topo).", + "Default"); + registerParameter("ForwardJVTWP", "Set fJVT Working Point for selecting forward jets (|eta|>2.5 & 20GeV<pT<60GeV)" + "\'None\': No fJVT (doesn't run tool for selection) - use this if you don't have forward jets in your selection or if using using PFlow jets with a derivation older than p4173, \'Tight\' (fJVT<0.4, recommended), \'Medium\': (fJVT<0.5, if combined with ForwardJVTinMETCalculation this will set MET WP to Tenacious with stricter JVTinMET requirements", + "None"); + registerParameter("ForwardJVTinMETCalculation", + "Use fJVT cut on forward jets to improve resolution in the MET recalculation? \'False\' (default - must set false if using pflow jets with derivations older than P4173), or \'True\'", "False"); + registerParameter("SaveFailForwardJVTJets", "Save the jets that failed the fJVT cut? \'False\' (default), or \'True\'", "False"); + registerParameter("AdvancedUsage_METUncertaintiesConfigDir", "Path to directory containing MET uncertainties configs (including trailing /) \'Latest\' (default), or previous \'METUtilities/data17_13TeV/prerec_Jan16/\'", "Latest"); + + registerParameter("JetPtGhostTracks", + "Jet pT threshold for ghost track systematic variations calculation (in MeV). Default 25 GeV.", + "25000."); + registerParameter("JetEtaGhostTracks", + "Jet eta threshold for ghost track systematic variations calculation. Default 2.5", + "2.5"); + registerParameter("GhostTrackspT", + "PT of the ghost tracks associated small-R jets (in MeV). Default 500 MeV.", + "500."); + registerParameter("GhostTracksVertexAssociation", + "WP of the ghost track vertex association. Option: none, nominal and tight. Default nominal.","nominal"); + registerParameter("GhostTracksQuality", + "WP of the ghost track quality. Option: TightPrimary, LoosePrimary. Loose, NoCut. Default TightPrimary.","TightPrimary"); + registerParameter("JetUncertainties_NPModel", + "AllNuisanceParameters, CategoryReduction (default), GlobalReduction, StrongReduction - for JetUncertainties", + "CategoryReduction"); + registerParameter("JetUncertainties_QGFracFile", "To specify a root file with quark/gluon fractions," + " in order to reduce FlavourComposition and response uncertainties." + " Default: None (i.e. no file is used and default flat 50+/-50% fraction is used).", + "None"); + registerParameter("JetUncertainties_QGHistPatterns", "To specify a pattern for the name of the quark/gluon fractions histograms, or a list of DSIDs which will have their specific histogram." + " Two syntaxes are possible, either a single string or a list of DSIDs separated by commas:" + " \"MyQGHisto\" (the histograms with \"MyQGHisto\" in their names will be used for all DSIDs)," + " \"410470,410472,345873,345874,345875\" (for the listed DSIDs, histograms with the processed DSID will be used, while the flat 50+/-50% fraction will be used for the other DSIDs)." + " Default: None (i.e. no specific pattern is looked for in the name of the provided histograms).", + "None"); + registerParameter("JetJERSmearingModel", + "All (inc. data smearing), All_PseudoData (use MC as pseudo-data), Full (inc. data smearing), Full_PseudoData (use MC as pseudo-data) or Simple (MC only - default)", + "Simple"); + registerParameter("JetCalibSequence", "Jet calibaration sequence, GSC (default) or JMS", "GSC"); + registerParameter("StoreJetTruthLabels", "Flag to store truth labels for jets - True (default) or False", "True"); + + registerParameter("JSF", "Used for top mass analysis, default is 1.0", "1.0"); registerParameter("bJSF", "Used for top mass analysis, default is 1.0", "1.0"); - registerParameter("LargeRJetPt", "Track Jet pT cut for object selection (in MeV). Default 7 GeV.", "25000."); - registerParameter("LargeRJetEta", "Absolute large-R jet eta cut for object selection. Default 2.0.", "2.0" ); - registerParameter("LargeRJESUncertaintyConfig", - "Variables to be varied with JES uncertainties. Options:D2Beta1,Tau21WTA,Tau32WTA,Split12,Split23,Qw ( default Split23,Tau32WTA)", - "Split23,Tau32WTA"); + registerParameter("LargeRJetPt", "LargeRJet pT cut for object selection (in MeV). Default 150 GeV.", "150000."); + registerParameter("LargeRJetEta", "Absolute large-R jet eta cut for object selection. Default 2.0.", "2.0"); + registerParameter("LargeRJetSubstructureVariables", "List of substructure variables stored in the output separated by commas. By default no variable is added to output.", " "); + registerParameter("LargeRJetUncertainties_NPModel", + "AllNuisanceParameters, CategoryReduction (default), GlobalReduction, - for LCTopo Large-R Jet Uncertainties or Scale_TCC_all - for TCC Large-R Jet Uncertainties", + "CategoryReduction"); + registerParameter("AdvancedUsage_LargeRJetUncertaintiesConfigDir", + "Path to directory containing large-R jet uncertainties config", + "rel21/Summer2019"); registerParameter("LargeRJESJMSConfig", - "Calibration for large-R JES/JMS. CombinedMass or CaloMass (default CombinedMass).", - "CombinedMass"); - - registerParameter("TrackJetPt", "Track Jet pT cut for object selection (in MeV). Default 7 GeV.", "7000."); - registerParameter("TrackJetEta", "Absolute Track Jet eta cut for object selection. Default 2.5.", "2.5" ); - - registerParameter("RCJetPt", "Reclustered Jet pT cut for object selection (in MeV). Default 100000 MeV.", "100000."); - registerParameter("RCJetEta", "Reclustered Jet eta cut for object selection. Default 2.0.", "2.0"); - registerParameter("RCJetTrim", "Reclustered Jet trimming cut for object selection. Default 0.05.", "0.05"); - registerParameter("RCJetRadius", "Reclustered Jet radius for object selection. Default 1.0", "1.0"); - registerParameter("UseRCJets", "Use Reclustered Jets. Default False.", "False"); - - registerParameter("VarRCJetPt", "Reclustered Jet (variable-R) pT cut for object selection (in MeV). Default 100000 MeV.", "100000."); - registerParameter("VarRCJetEta", "Reclustered Jet (variable-R) eta cut for object selection. Default 2.0.", "2.0"); - registerParameter("VarRCJetTrim", "Reclustered Jet (variable-R) trimming cut for object selection. Default 0.05.", "0.05"); - registerParameter("VarRCJetMaxRadius", "Reclustered Jet (variable-R) max. radius cut for object selection. Default 1.0", "1.0"); - registerParameter("VarRCJetRho", "Reclustered Jet (variable-R) list of rho values (). Default 2.", "2"); - registerParameter("VarRCJetMassScale", "Reclustered Jet (variable-R) list of mass scale values (m_w,m_z,m_h,m_t). By default use all.", "m_w,m_z,m_h,m_t"); - registerParameter("UseVarRCJets", "Use Reclustered Jets (Variable-R Jets). Default False.", "False"); + "Calibration for large-R JES/JMS. CombMass, CaloMass or TCCMass (default CombMass).", + "CombMass"); + registerParameter("BoostedJetTagging", + "Boosted jet taggers to use in the analysis, separated by commas or white spaces." + " By default, no tagger is used.", + " "); + + registerParameter("TrackJetPt", "Track Jet pT cut for object selection (in MeV). Default 10 GeV.", "10000."); + registerParameter("TrackJetEta", "Absolute Track Jet eta cut for object selection. Default 2.5.", "2.5"); + + registerParameter("TrackPt", "Track pT cut for object selection (in MeV). Default 0.5 GeV.", "0.5"); + registerParameter("TrackEta", "Absolute Track eta cut for object selection. Default 2.5.", "2.5"); + registerParameter("TrackQuality", + "Track quality cut for object selection. Options are TightPrimary,...", + "TightPrimary"); + + + registerParameter("RCJetPt", "Reclustered Jet pT cut for object selection (in MeV). Default 100000 MeV.", + "100000."); + registerParameter("RCJetEta", "Reclustered Jet eta cut for object selection. Default 2.0.", "2.0"); + registerParameter("RCInputJetPtMin", "Min Pt cut for RC jet inputs collection. Parameter is shared between RC and VarRC jets. Default 30000. [MeV]", "30000."); + registerParameter("RCInputJetEtaMax", "Max |Eta| cut for RC jet inputs collection. Parameter is shared between RC and VarRC jets. Default 2.5", "2.5"); + registerParameter("RCJetTrim", "Reclustered Jet trimming cut for object selection. Default 0.05.", "0.05"); + registerParameter("RCJetRadius", "Reclustered Jet radius for object selection. Default 1.0", "1.0"); + registerParameter("UseRCJetSubstructure", "Calculate Reclustered Jet Substructure Variables. Default False", + "False"); + registerParameter("UseRCJetAdditionalSubstructure", + "Calculate Additional Reclustered Jet Substructure Variables. Default False", "False"); + + registerParameter("UseRCJets", "Use Reclustered Jets. Default False.", "False"); + + registerParameter("VarRCJetPt", + "Reclustered Jet (variable-R) pT cut for object selection (in MeV). Default 100000 MeV.", + "100000."); + registerParameter("VarRCJetEta", "Reclustered Jet (variable-R) eta cut for object selection. Default 2.0.", "2.0"); + registerParameter("VarRCJetTrim", "Reclustered Jet (variable-R) trimming cut for object selection. Default 0.05.", + "0.05"); + registerParameter("VarRCJetMaxRadius", + "Reclustered Jet (variable-R) max. radius cut for object selection. Default 1.0", "1.0"); + registerParameter("VarRCJetRho", "Reclustered Jet (variable-R) list of rho values (). Default 2.", "2"); + registerParameter("VarRCJetMassScale", + "Reclustered Jet (variable-R) list of mass scale values (m_w,m_z,m_h,m_t). By default use all.", + "m_w,m_z,m_h,m_t"); + registerParameter("UseVarRCJets", "Use Reclustered Jets (Variable-R Jets). Default False.", "False"); + registerParameter("UseVarRCJetSubstructure", + "Calculate Variable-R Reclustered Jet Substructure Variables. Default False", "False"); + registerParameter("UseVarRCJetAdditionalSubstructure", + "Calculate Additional Variable-R Reclustered Jet Substructure Variables. Default False", "False"); registerParameter("TauPt", - "Pt cut applied to both tight and loose taus (in MeV)." - "Default 25 GeV.", - "25000"); + "Pt cut applied to both tight and loose taus (in MeV)." + "Default 25 GeV.", + "25000"); + registerParameter("TauEtaRegions", + "Eta regions used for both tight and loose taus." + "Default vetoing crack region [0., 1.37, 1.52, 2.5]", + "[0., 1.37, 1.52, 2.5]"); registerParameter("TauJetIDWP", - "Tau jet IDWP (None, Loose, Medium, Tight, LooseNotMedium, LooseNotTight, MediumNotTight, NotLoose)." - "Default Medium.", - "Medium"); + "Tau jet IDWP (None, Loose, Medium, Tight, LooseNotMedium, LooseNotTight, MediumNotTight, NotLoose, RNNLoose, RNNMedium, RNNTight)." + "Default RNNMedium.", + "RNNMedium"); registerParameter("TauJetIDWPLoose", - "Loose Tau jet IDWP (None, Loose, Medium, Tight, LooseNotMedium, LooseNotTight, MediumNotTight, NotLoose)." - "Default None.", - "Medium"); + "Loose Tau jet IDWP (None, Loose, Medium, Tight, LooseNotMedium, LooseNotTight, MediumNotTight, NotLoose)." + "Default RNNLoose.", + "RNNLoose"); registerParameter("TauEleBDTWP", - "Tau electron BDT WP (None, Loose, Medium, Tight)." + "Tau electron BDT WP (None, Loose, Medium, Tight, OldLoose, OldMedium)." "Default Loose.", "Loose"); registerParameter("TauEleBDTWPLoose", - "Loose Tau electron BDT WP (None, Loose, Medium, Tight)." + "Loose Tau electron BDT WP (None, Loose, Medium, Tight, OldLoose, OldMedium)." "Default Loose.", "Loose"); registerParameter("TauEleOLR", - "Apply tau-electron overlap removal (True/False)." - "Default False", - "False"); + "Apply tau-electron overlap removal (True/False)." + "Default False", + "False"); registerParameter("TauEleOLRLoose", - "Apply loose tau-electron overlap removal (True/False)." - "Default False", - "False"); + "Apply loose tau-electron overlap removal (True/False)." + "Default False", + "False"); registerParameter("TauJetConfigFile", - "Config file to configure tau selection. " - "If anything other than 'Default'" - "then all cuts are taken from the " - "config file rather than other options.", - "Default"); + "Config file to configure tau selection. " + "If anything other than 'Default'" + "then all cuts are taken from the " + "config file rather than other options.", + "Default"); registerParameter("TauJetConfigFileLoose", - "Config file to configure loose tau selection. " - "If anything other than 'Default'" - "then all cuts are taken from the " - "config file rather than other options.", - "Default"); + "Config file to configure loose tau selection. " + "If anything other than 'Default'" + "then all cuts are taken from the " + "config file rather than other options.", + "Default"); registerParameter("ApplyTauMVATES", - "Apply new Tau energy calibration based on substructure information and regression, True or False (default).", + "Apply new Tau energy calibration based on substructure information and regression. Must be True. Deprecated.", + "True"); + registerParameter("TauSFDoRNNID", + "Save SF for RNN tau ID True/False", + "True"); + registerParameter("TauSFDoBDTID", + "Save SF for BDT tau ID True/False", "False"); - - registerParameter("Systematics", "What to run? Nominal (just the nominal), All(do all systematics) " , "Nominal"); + + registerParameter("Systematics", "What to run? Nominal (just the nominal), All(do all systematics) ", "Nominal"); registerParameter("LibraryNames", "Names of any libraries that need loading"); - registerParameter("UseAodMetaData", "Whether to read xAOD meta-data from input files (default: False)", "False"); + registerParameter("UseAodMetaData", "Whether to read xAOD meta-data from input files (default: True)", "True"); + registerParameter("WriteTrackingData", "Whether to generate and store analysis-tracking data (default: True)", + "True"); registerParameter("ObjectSelectionName", "Code used to define objects, e.g. ObjectLoaderStandardCuts"); registerParameter("OutputFormat", "Format, can be user defined, e.g. top::EventSaverFlatNtuple"); - registerParameter("OutputEvents", "AllEvents (saves all events + decison bits), SelectedEvents (saves only the events passing your cuts)"); + registerParameter("OutputEvents", + "AllEvents (saves all events + decison bits), SelectedEvents (saves only the events passing your cuts)"); registerParameter("OutputFilename", "The file that will contain the output histograms and trees"); - registerParameter("OutputFileSetAutoFlushZero", "setAutoFlush(0) on EventSaverFlatNtuple for ANALYSISTO-44 workaround. Default False","False"); - - registerParameter("EventVariableSaveList", "The list of event variables to save (EventSaverxAODNext only).", "runNumber.eventNumber.eventTypeBitmask.averageInteractionsPerCrossing"); - registerParameter("PhotonVariableSaveList", "The list of photon variables to save (EventSaverxAODNext only).", "pt.eta.phi.m.charge.ptvarcone20.topoetcone20.passPreORSelection"); - registerParameter("ElectronVariableSaveList", "The list of electron variables to save (EventSaverxAODNext only).", "pt.eta.phi.m.charge.ptvarcone20.topoetcone20.passPreORSelection"); - registerParameter("MuonVariableSaveList", "The list of muon variables to save (EventSaverxAODNext only).", "pt.eta.phi.m.author.charge.ptvarcone30.topoetcone20.muonType.passPreORSelection"); - registerParameter("TauVariableSaveList", "The list of tau variables to save (EventSaverxAODNext only).", "pt.eta.phi.m.charge.passPreORSelection"); - registerParameter("JetVariableSaveList", "The list of jet variables to save (EventSaverxAODNext only).", "pt.eta.phi.m.passPreORSelection.btaggingLink.HadronConeExclTruthLabelID"); - registerParameter("BTagVariableSaveList", "The list of b-tag variables to save (EventSaverxAODNext only).", "MV2c20_discriminant"); - - registerParameter("NEvents", "The number of events that you want to run on (for testing). If 0 then all events are run.", "0"); - registerParameter("FirstEvent", "The number of events that you want to skip (for testing). If 0 then no events are skipped.", "0"); - registerParameter("PerfStats"," I/O Performance printouts. None, Summary or Full" , "None"); + registerParameter("OutputFileSetAutoFlushZero", + "setAutoFlush(0) on EventSaverFlatNtuple for ANALYSISTO-44 workaround. (default: False)", + "False"); + registerParameter("OutputFileNEventAutoFlush", + "Set the number of events after which the TTree cache is optimised, ie setAutoFlush(nEvents). (default: 1000)", + "1000"); + registerParameter("OutputFileBasketSizePrimitive", + "Set the TTree basket size for primitive objects (int, float, ...). (default: 4096)", "4096"); + registerParameter("OutputFileBasketSizeVector", "Set the TTree basket size for vector objects. (default: 40960)", + "40960"); + registerParameter("RecomputeCPVariables", + "Run the CP tools to force computation of variables that may already exist in derivations? (default: True)", + "True"); + registerParameter("EventVariableSaveList", "The list of event variables to save (EventSaverxAODNext only).", + "runNumber.eventNumber.eventTypeBitmask.averageInteractionsPerCrossing"); + registerParameter("PhotonVariableSaveList", "The list of photon variables to save (EventSaverxAODNext only).", + "pt.eta.phi.m.charge.ptvarcone20.topoetcone20.passPreORSelection"); + registerParameter("ElectronVariableSaveList", "The list of electron variables to save (EventSaverxAODNext only).", + "pt.eta.phi.m.charge.ptvarcone20.topoetcone20.passPreORSelection"); + registerParameter("MuonVariableSaveList", "The list of muon variables to save (EventSaverxAODNext only).", + "pt.eta.phi.m.author.charge.ptvarcone30.topoetcone20.muonType.passPreORSelection"); + registerParameter("TauVariableSaveList", "The list of tau variables to save (EventSaverxAODNext only).", + "pt.eta.phi.m.charge.passPreORSelection"); + registerParameter("JetVariableSaveList", "The list of jet variables to save (EventSaverxAODNext only).", + "pt.eta.phi.m.passPreORSelection.btaggingLink.HadronConeExclTruthLabelID"); + registerParameter("BTagVariableSaveList", "The list of b-tag variables to save (EventSaverxAODNext only).", + "MV2c20_discriminant"); + + registerParameter("NEvents", + "The number of events that you want to run on (for testing). If 0 then all events are run.", "0"); + registerParameter("FirstEvent", + "The number of events that you want to skip (for testing). If 0 then no events are skipped.", + "0"); + registerParameter("PerfStats", " I/O Performance printouts. None, Summary or Full", "None"); registerParameter("IsAFII", "Define if you are running over a fastsim sample: True or False", " "); + registerParameter("FilterBranches", + "Comma separated list of names of the branches that will be removed from the output", " "); + registerParameter("FilterPartonLevelBranches", + "Comma separated list of names of the parton-level branches that will be removed from the output", " "); + registerParameter("FilterParticleLevelBranches", + "Comma separated list of names of the particle-level branches that will be removed from the output", " "); + registerParameter("FilterNominalLooseBranches", + "Comma separated list of names of the nominal_Loose tree branches that will be removed from the output", " "); + registerParameter("FilterTrees", + "Comma separated list of names of the trees that will be removed from the output", " "); + + registerParameter("FakesMMWeightsIFF", + "Calculate matrix-method weights for fake leptons estimate using FakeBkgTools from IFF: True (calculate weights), False (does nothing)", + "False"); + registerParameter("FakesMMConfigIFF", + "Configurations for fake leptons estimate using FakeBkgTools from IFF: - default is $ROOTCOREBIN/data/TopFakes/efficiencies.xml:1T:1F[T]. Use as \n <ROOT/XML FILE>:<DEFNINITION>:<PROCESS>;<ROOT/XML FILE 2>:<DEFNINITION 2>:<PROCESS 2>; ...", + "$ROOTCOREBIN/data/TopFakes/efficiencies.xml:1T:1F[T]"); + registerParameter("FakesMMIFFDebug", + "Enables debug mode for matrix-method weight calculation using FakeBkgTools from IFF: True, False (default)", + "False"); - registerParameter("FakesControlRegionDoLooseMC","Run Loose events on MC : True (study fakes control regions), False (regular analysis)", "False"); - - registerParameter("FakesMMWeights","Calculate matrix-method weights for fake prompt leptons estimate : True (calculate weights), False (does nothing)", "False"); - registerParameter("FakesMMDir","Directory of files containing efficiencies for fake prompt leptons estimate - default is $ROOTCOREBIN/data/TopFakes", "$ROOTCOREBIN/data/TopFakes"); - registerParameter("FakesMMDebug","Enables debug mode for matrix-method weight calculation: True, False (default)", "False"); + registerParameter("DoTight", "Dumps the normal non-\"*_Loose\" trees : Data, MC, Both (default), False", "Both"); + registerParameter("DoLoose", "Run Loose selection and dumps the Loose trees : Data (default), MC, Both, False", + "Data"); + registerParameter("DoSysts", "Run systematics on given selection: Both (default), Tight, Loose", "Both"); + + registerParameter("UseLooseObjectsInMETInLooseTree","Experimental: use loose objects when rebuilding the MET for the loose tree : True or False (default = False)","False"); + registerParameter("UseLooseObjectsInMETInNominalTree","Experimental: use loose objects when rebuilding the MET for the nominal tree : True or False (default = False)","False"); + + registerParameter("WriteMETBuiltWithLooseObjects","Write a separate branch with the met built with loose objects in the output for tests: True or False (default = False)","False"); - registerParameter("OverlapRemovalLeptonDef","Run overlap removal on : Tight (top default) or Loose (not top default) lepton definitions", "Tight"); - registerParameter("DoLooseTreeOnly","Only dumps the Loose trees (and activate them for MC): True or False (default)", "False"); - registerParameter("ApplyTightSFsInLooseTree","In Loose trees, calculate lepton SFs with tight leptons only, and considering they are tight: True or False (default)", "False"); - registerParameter("ApplyElectronInJetSubtraction","Subtract electrons close to jets for boosted analysis : True or False(top default)", "False"); - registerParameter("TopPartonHistory","ttbar, tb, False (default)", "False"); + registerParameter("OverlapRemovalLeptonDef", + "Special: run overlap removal on : Tight (top default) or Loose (not top default) lepton definitions", + "Tight"); + registerParameter("ApplyTightSFsInLooseTree", + "Special: in Loose trees, calculate lepton SFs with tight leptons only, and considering they are tight: True or False (default)", + "False"); - registerParameter("TopParticleLevel", "Perform particle level selection? True or False", "False"); + registerParameter("ApplyElectronInJetSubtraction", + "Subtract electrons close to jets for boosted analysis : True or False(top default)", "False"); + registerParameter("TopPartonHistory", "ttbar, tb, Wtb, ttz, ttgamma, tHq, False (default)", "False"); + registerParameter("TopPartonLevel", "Perform parton level analysis (stored in truth tree)? True or False", "True"); + + registerParameter("TopParticleLevel", "Perform particle level selection (stored in particleLevel tree)? True or False", "False"); registerParameter("DoParticleLevelOverlapRemoval", "Perform overlap removal at particle level? True (default), False, or any combination (comma separated) of MuonJet, ElectronJet, JetPhoton", "True"); - registerParameter("PDFInfo","Do you want the PDF info? True (in truth tree), Nominal (save to the nominal tree if passes selection) or False (nothing, default)", "False"); - registerParameter("MCGeneratorWeights","Do you want the OTF-computed MC generator weights (if available)? True (in truth tree), Nominal (save to the nominal tree if passes selection) or False (nothing, default)", "False"); - registerParameter("TruthBlockInfo","Do you want to dump the full Truth block info? True or False", "False"); + registerParameter("PDFInfo", + "Do you want the PDF info? True (in truth tree), Nominal (save to the nominal tree if passes selection) or False (nothing, default)", + "False"); + registerParameter("MCGeneratorWeights", + "Do you want the OTF-computed MC generator weights (if available)? True (in truth tree), Nominal (save to the nominal tree if passes selection) or False (nothing, default)", + "False"); + registerParameter("NominalWeightNames", + "List of nominal weight names to attempt to retrieve. Attempts are made in the order as specified. If none of the names can be found, we will crash with error message. Use index instead in such case.", + "\" nominal \",\"nominal\",\"Default\",\"Weight\",\"1001\",\" muR=0.10000E+01 muF=0.10000E+01 \",\"\",\" \",\" dyn= 3 muR=0.10000E+01 muF=0.10000E+01 \",\" mur=1 muf=1 \""); + registerParameter("NominalWeightFallbackIndex", + "Index of nominal weight in MC weights vector. This option is only used in case the MC sample has broken metadata. (Default: -1 means no fallback index specified, rely on metadata and crash if metadata cannot be read)", + "-1"); + registerParameter("ForceNominalWeightFallbackIndex", + "Force usage of NominalWeightFallbackIndex, even if MC sample metadata is correct. (Default: False)", + "False"); - registerParameter("TruthElectronPt", "Electron pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000"); - registerParameter("TruthElectronEta", "Absolute electron eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5" ); + registerParameter("TruthBlockInfo", "Do you want to dump the full Truth block info? True or False", "False"); - registerParameter("TruthMuonPt", "Muon pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000"); - registerParameter("TruthMuonEta", "Absolute Muon eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5" ); + registerParameter("TruthElectronPt", + "Electron pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", + "25000"); + registerParameter("TruthElectronEta", + "Absolute electron eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5"); + registerParameter("TruthMuonPt", + "Muon pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000"); + registerParameter("TruthMuonEta", + "Absolute Muon eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5"); + + registerParameter("TruthSoftMuonPt", + "Soft Muon pT cut for [Particle Level / Truth] object selection (in MeV). Default 4 GeV.", "4000"); + registerParameter("TruthSoftMuonEta", + "Absolute Soft Muon eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5"); + registerParameter("TruthPhotonPt", "Photon pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000"); registerParameter("TruthPhotonEta", "Absolute Photon eta cut for [Particle Level / Truth] object selection. Default 2.5.", - "2.5" ); + "2.5"); registerParameter("TruthPhotonOrigin", "Potential origin of [Particle Level / Truth] photons. Comma separated list of particle origin values as given by MCTruthClassifier (string names).", - "WBoson,ZBoson,SinglePhot,Higgs,HiggsMSSM,WZMSSM,PromptPhot,SUSY,UndrPhot,FSRPhot" ); + "WBoson,ZBoson,SinglePhot,Higgs,HiggsMSSM,WZMSSM,PromptPhot,SUSY,UndrPhot,FSRPhot"); registerParameter("TruthPhotonIsolation", "Configuration option for isolation applied to [Particle Level / Truth] photons. " "This can be False / None (isolation requirement disabled), " "True (use default isolation), " "or a configuration in the format `VAR CUT`, where VAR is one of the isolation variables and CUT is the cut applied as `VAR / pt < CUT`.", - "ptcone30 0.1"); + "ptcone20 0.1"); - registerParameter("TruthJetPt", "Jet pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000"); - registerParameter("TruthJetEta", "Absolute Jet eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5" ); + registerParameter("TruthJetPt", + "Jet pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000"); + registerParameter("TruthJetEta", "Absolute Jet eta cut for [Particle Level / Truth] object selection. Default 2.5.", + "2.5"); - registerParameter("TruthLargeRJetPt", "Large R Jet pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000"); - registerParameter("TruthLargeRJetEta", "Absolute Large R Jet eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5" ); - - registerParameter("LHAPDFSets", "List of PDF sets to calculate weights for, seperated by spaces, use LHAPDF names e.g CT10nlo NNPDF30_nlo_as_0118 MMHT2014nlo68cl", " " ); - registerParameter("LHAPDFEventWeights", "Save per event weights for all PDF sets/members: True (lots of info in truth tree!), Nominal (save to the nominal tree if passes selection) or False (nothing, default).", "False" ); - registerParameter("LHAPDFBaseSet", "Base PDF set used to recalculate XF1,XF2 values if they are zero. Will be added to LHAPDFSets.", " " ); + registerParameter("TruthLargeRJetPt", + "Large R Jet pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", + "25000"); + registerParameter("TruthLargeRJetEta", + "Absolute Large R Jet eta cut for [Particle Level / Truth] object selection. Default 2.5.", + "2.5"); + + registerParameter("TruthTauPt", + "Tau pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000"); + registerParameter("TruthTauEta", "Tau eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5"); + + registerParameter("LHAPDFSets", + "List of PDF sets to calculate weights for, seperated by spaces, use LHAPDF names e.g CT10nlo NNPDF30_nlo_as_0118 MMHT2014nlo68cl", + " "); + registerParameter("LHAPDFEventWeights", + "Save per event weights for all PDF sets/members: True (lots of info in truth tree!), Nominal (save to the nominal tree if passes selection) or False (nothing, default).", + "False"); + registerParameter("LHAPDFBaseSet", + "Base PDF set used to recalculate XF1,XF2 values if they are zero. Will be added to LHAPDFSets.", + " "); + registerParameter("BTagCDIPath", "Path to the b-tagging CDI file. Default: Using the hardcoded path.", "Default"); registerParameter("BTaggingWP", - "b-tagging WPs to calculate SF for." - " Can be either a list of cut values written as in " - "the CDI files e.g. -0_4434 (default), or as -0.4434." - " More conviniently it can be a percentage: e.g. 77%.", - "-0_4434"); + "DEPRECATED OPTION, use BTaggingCaloJetWP and BTaggingTrackJetWP for specifying b-tagging WPs for jet collections using calorimeter information and for track jets respectively.", + " "); + + registerParameter("BTaggingTrackJetWP", + "b-tagging WPs to use for track jet collection in the analysis, separated by commas." + " The format should follow the convention of the b-tagging CP group, e.g. FixedCutBEff_60, FlatBEff_77, Continuous, etc." + " For fixed-cut WPs, the simpler format 60%, instead of FixedCutBEff_60, is also tolerated." + " The specified WPs which are calibrated for all flavours will have scale-factors computed." + " By default, no WP is used.", + " "); + + registerParameter("BTaggingCaloJetWP", + "b-tagging WPs to use for calorimeter jet collection (e.g. EMTopo, EMPFlow) in the analysis, separated by commas." + " The format should follow the convention of the b-tagging CP group, e.g. FixedCutBEff_60, FlatBEff_77, Continuous, etc." + " For fixed-cut WPs, the simpler format 60%, instead of FixedCutBEff_60, is also tolerated." + " The specified WPs which are calibrated for all flavours will have scale-factors computed." + " By default, no WP is used.", + " "); registerParameter("BTaggingSystExcludedFromEV", "User-defined list of b-tagging systematics to be dextracted from eigenvector decomposition, separated by semi-colons (none by default)", @@ -260,233 +535,442 @@ ConfigurationSettings::ConfigurationSettings() : m_configured(false) { " Default 'default'", "default"); - registerParameter("PRWConfigFiles", "List of PU config files, seperated by spaces (nothing by default)", " "); + registerParameter("PRWConfigFiles", + "List of PU config files, seperated by spaces (nothing by default) - Not compatible with FS/AF options", + " "); + registerParameter("PRWConfigFiles_FS", + "List of PU config files only for full sim samples, seperated by spaces (nothing by default)", + " "); + registerParameter("PRWConfigFiles_AF", + "List of PU config files only for fast sim samples, seperated by spaces (nothing by default)", + " "); + registerParameter("PRWActualMu_FS", + "List of actual mu files for full sim samples, seperated by spaces (nothing by default)", " "); + registerParameter("PRWActualMu_AF", + "List of actual mu files only for fast sim samples, seperated by spaces (nothing by default)", + " "); registerParameter("PRWLumiCalcFiles", "List of PU lumicalc files, seperated by spaces (nothing by default)", " "); registerParameter("PRWUseGRLTool", "Pass the GRL tool to the PU reweighting tool (False by default)", "False"); registerParameter("PRWMuDependent", "Use mu dependent random run numbers for MC. " "True or False (default True)", "True"); + registerParameter("PRWCustomScaleFactor", + "Specify custom scale-factor and up/down variations, for specific studies." + "Format is \'nominal:up:down\'." + "If nothing is set, the default values will be used (recommended).", + " "); + registerParameter("PRWUnrepresentedDataTolerance", + "Specify value between 0 and 1 to represent acceptable fraction of unrepresented data in PRW [default: 0.05]", + "0.05"); + registerParameter("PRWPeriodAssignments", + "Specify period number assignments to run numbers ranges in this form: \"XXX:XXX:XXX\", where XXX are runnumbers, first number is the associated run number, second number is the period block start, the third number is the period block end. You can pass any number of these sets (total number of provided RunNumbers needs to be divisible by 3). Default is used if not specified", + " "); registerParameter("MuonTriggerSF", "Muon trigger SFs to calculate", "HLT_mu20_iloose_L1MU15_OR_HLT_mu50"); - - registerParameter("KLFitterTransferFunctionsPath","Select the transfer functions to use","mc12a/akt4_LCtopo_PP6"); - registerParameter("KLFitterJetSelectionMode","kLeadingFour , kLeadingFive , kBtagPriorityFourJets , kBtagPriorityFiveJets","kBtagPriorityFourJets"); - registerParameter("KLFitterBTaggingMethod","Recommend use kNotag or kVetoNoFit - see KLFitter TWiki","kNotag"); - registerParameter("KLFitterLH", "Select likelihood depending on signal, ttbar or ttH.", "ttbar"); - registerParameter("KLFitterTopMassFixed","Fix the mass of the top quark? True or False","True"); - registerParameter("KLFitterSaveAllPermutations","Save All permutations to the output file (False will save only the best)","False"); + + registerParameter("KLFitterTransferFunctionsPath", "Select the transfer functions to use", "mc12a/akt4_LCtopo_PP6"); + registerParameter("KLFitterOutput", "Select the KLFitter output (FULL, FITTEDTOPS_ONLY, JETPERM_ONLY)", "FULL"); + registerParameter("KLFitterJetSelectionMode", + "kLeadingThree , kLeadingFour , kLeadingFive , kLeadingSix , kLeadingSeven , kLeadingEight , kBtagPriorityThreeJets , kBtagPriorityFourJets , kBtagPriorityFiveJets, kBtagPrioritySixJets , kBtagPrioritySevenJets , kBtagPriorityEightJets", + "kBtagPriorityFourJets"); + registerParameter("KLFitterBTaggingMethod", "Recommend use kNotag or kVetoNoFit - see KLFitter TWiki", "kNotag"); + registerParameter("KLFitterLH", + "Select likelihood depending on signal, ttbar, ttbar_angles, ttH, ttZTrilepton, ttbar_AllHadronic, ttbar_BoostedLJets", + "ttbar"); + registerParameter("KLFitterTopMassFixed", "Fix the mass of the top quark? True or False", "True"); + registerParameter("KLFitterSaveAllPermutations", + "Save All permutations to the output file (False will save only the best)", "False"); + registerParameter("KLFitterFailOnLessThanXJets", + "Fail if kLeadingX or kBtagPriorityXJets is set and the number of jets in the event is less than X (Default is False)", + "False"); registerParameter("DynamicKeys", "Additional dynamic key list seperated by ,", ""); registerParameter("OverlapRemovalProcedure", "Overlap removal procedure to be used. Options include:" - " recommended [default], jetmuApplyRelPt, harmonized," - " Boosted, BoostedSlidingDREl, BoostedSlidingDRMu, BoostedSlidingDRElMu, noTauJetOLR", + " recommended [default], jetmuApplyRelPt, harmonized," + " Boosted, BoostedSlidingDREl, BoostedSlidingDRMu, BoostedSlidingDRElMu, noTauJetOLR, " + " noPhotonMuOR, noPhotonMuOrJetOR", "recommended" - ); + ); + + registerParameter("OverlapRemovalSlidingInnerDRel", + "Overlap removal inner radius to be used for electron SlidingDR ,", "0.2"); + registerParameter("OverlapRemovalSlidingInnerDRmu", "Overlap removal inner radius to be used for muon SlidingDR ,", + "0.2"); - registerParameter("LargeJetOverlapRemoval", "Perform overlap removal including large-R jets. True or False (default: False).", "False"); + registerParameter("LargeJetOverlapRemoval", + "Perform overlap removal including large-R jets. True or False (default: False).", "False"); registerParameter("HLLHC", - "Set to run HL-LHC studies," - "True or False (default False)", - "False"); -} + "Set to run HL-LHC studies," + "True or False (default False)", + "False"); + + registerParameter("HLLHCFakes", + "Set to enable Fakes HL-LHC studies," + "True or False (default False)", + "False"); -ConfigurationSettings* ConfigurationSettings::get() { - if (!m_instance) - m_instance = new ConfigurationSettings(); + registerParameter("SaveBootstrapWeights", "Set to true in order to save Poisson bootstrap weights," + "True or False (default False)", "False"); + + registerParameter("NumberOfBootstrapReplicas", "Define integer number of replicas to be stored with bootstrapping, " + "Default 100", "100"); + + registerParameter("UseBadBatmanCleaning", "Switch to turn on BadBatman cleanig.", "False"); + registerParameter("BadBatmanCleaningRange", + "Set a range of RunNumbers where the cleaning is applied in the form of XXXXX:YYYYY", + "276262:311481"); + registerParameter("UseEventLevelJetCleaningTool", + "Switch to turn on event-level jet cleaning tool (for testing), True or False (default False)", + "False"); + + registerParameter("UseGlobalLeptonTriggerSF", + "Switch to activate event-level trigger scale factors allowing multiple OR of single-, di-, tri- lepton triggers, True or False (default False)", + "False"); + registerParameter("GlobalTriggers", + "Trigger list for GlobalLeptonTriggerSF - Format as 2015@trig1,trig2 2016@trig3,trig4 : Separate periods defined with @ using whitespace, triggers with comma (default: None)", + "None"); + registerParameter("GlobalTriggersLoose", + "Trigger list for GlobalLeptonTriggerSF - Format as 2015@trig1,trig2 2016@trig3,trig4 : Separate periods defined with @ using whitespace, triggers with comma (default: None)", + "None"); + registerParameter("ElectronTriggers", "Deprecated, use GlobalTriggers instead.", "None"); + registerParameter("ElectronTriggersLoose", "Deprecated, use GlobalTriggersLoose instead.", "None"); + registerParameter("MuonTriggers", "Deprecated, use GlobalTriggers instead.", "None"); + registerParameter("MuonTriggersLoose", "Deprecated, use GlobalTriggersLoose instead.", "None"); + + registerParameter("DemandPrimaryVertex", "Wether at least one primary vertex in event is required. Default True. For debugging purposes only!", "True"); + + registerParameter("KillExperimental", "Disable some specific experimental feature.", " "); + registerParameter("RedefineMCMCMap", "Dictionary for translating the shower names from TopDataPreparation. Format: \"shower1:shower2,shower3:shower4\".", " "); + } + + ConfigurationSettings* ConfigurationSettings::get() { + if (!m_instance) m_instance = new ConfigurationSettings(); return m_instance; -} + } -void ConfigurationSettings::loadFromFile(const std::string& filename) { + void ConfigurationSettings::loadFromFile(const std::string& filename) { std::ifstream input(filename.c_str()); if (!input) { - std::cout << "Configuration file does not exist, " << filename << std::endl; - std::cout << "Can't continue" << std::endl; - exit(1); + throw std::runtime_error("Configuration file does not exist: " + filename); } struct SelectionData { - std::string name; - bool isSub; - std::vector<std::string> cuts; + std::string name; + bool isSub; + std::vector<std::string> cuts; }; std::string line; std::vector<SelectionData> selections; //for the key-value pairs - while (std::getline( input, line )) { - std::string newstring(line); - //std::cout << newstring << '\n'; - - if (newstring.find("#") != std::string::npos) - newstring = newstring.substr(0, newstring.find("#")); - - // remove (multiple) spaces hanging around relevant information - boost::algorithm::trim_all(newstring); - if (newstring.empty()) - continue; - - // handle start of a (sub)selection (implies end of key-value section) - if (boost::algorithm::starts_with(newstring, "SELECTION ")) { - selections.push_back({newstring.substr(10), false, {}}); - continue; + while (std::getline(input, line)) { + std::string newstring(line); + + // search for '#' character to discard commented-out part of line + // however ignore '\#' -- used to be able to type # in our config + // and not be recognized as commenting character + size_t commentpos = size_t(-1); + while (true) { + // find next occurence of '#' -- after the already scanned chars + commentpos = newstring.find("#", commentpos+1); + if (commentpos == std::string::npos) + break; + if (commentpos == 0) { // the whole line is a comment, to be ignored + newstring = ""; + break; } - if (boost::algorithm::starts_with(newstring, "SUB ")) { - selections.push_back({newstring.substr(4), true, {}}); + // if it's '\#', then do not erase this part, but remove the '\' + if (newstring.compare(commentpos-1, 1, "\\") == 0) { + newstring.erase(commentpos-1, 1); + --commentpos; // the position of the '#' shifted after removing '\' continue; + } else { + newstring = newstring.substr(0, commentpos); + break; + } + } + + // remove (multiple) spaces hanging around relevant information + // if a pair of "" appears, the spaces in "" won't be touched + bool hasquote = (newstring.find("\"",0) != std::string::npos); + if (!hasquote) boost::algorithm::trim_all(newstring); + else { + //split the string into segments, separated by pairs of quotes + //e.g. the string "abc \"def\" ghi" + // becomes a vector of 3 strings: "abc", "\"def\"", "ghi" + std::vector<std::string> segments; + std::vector<bool> segments_isquote; + std::size_t strsize = newstring.size(); + std::size_t tmppos = 0; + bool leftquote = true; + while (tmppos <= strsize-1) { + // find the position of the 1st quote after newstring[tmppos] + std::size_t tmppos2 = newstring.find_first_of("\"",tmppos); + + // when the quote found has \ ahead of it, jump over and update tmppos2 + std::size_t tmppos3 = newstring.find_first_of("\\\"",tmppos); + while (tmppos2 == tmppos3+1) { + tmppos3 = newstring.find_first_of("\\\"",tmppos2+1); + tmppos2 = newstring.find_first_of("\"",tmppos2+1); + } + + // when no more quote found, save the segment from the last rightquote to the end, then quit the loop + if (tmppos2 == std::string::npos) { + segments.push_back(newstring.substr(tmppos,strsize-tmppos)); + segments_isquote.push_back(false); + break; + } + + // check it's a left quote or right quote + if (leftquote) { + segments.push_back(newstring.substr(tmppos,tmppos2-tmppos)); + segments_isquote.push_back(false); + + // update the position indicator and leftquote flag + tmppos = tmppos2+1; + leftquote = false; + } else { + segments.push_back(newstring.substr(tmppos-1,tmppos2-(tmppos-1)+1)); // have to include the two quotes, which is why +/-1 adjustment is introduced + segments_isquote.push_back(true); + + // update the position indicator and leftquote flag + tmppos = tmppos2+1; + leftquote = true; + } + } + + // sanity check: if leftquote = false after the loop, it means a left quote is found but not its associated rightquote + // in this case, crash the code + if (!leftquote) { + std::string message = "Problematic configuration line\n"; + message.append(newstring.c_str()); + throw std::invalid_argument(message); } - if (!selections.empty()) { - // read body of (sub)selection - auto & sel = selections.back(); - if (boost::algorithm::starts_with(newstring, ". ")) { - // source another (sub)selection here - auto subselName = newstring.substr(2); - auto subselIt = std::find_if(selections.rbegin(), selections.rend(), - [subselName](SelectionData const & sel){ return (subselName == sel.name); }); - if (subselIt == selections.rend()) - throw std::invalid_argument("ConfigurationSettings: unknown selection: " + subselName); - sel.cuts.insert(sel.cuts.end(), subselIt->cuts.begin(), subselIt->cuts.end()); + //run the original trim_all for each segment that is NOT a quote + for (uint i = 0; i < segments.size(); i++) { + std::string seg = segments.at(i); + if (seg.size() == 0) continue; + if (segments_isquote.at(i)) continue; + boost::algorithm::trim_all(seg); + + // if the segment has a space in the end and it's not the last segment, add the space back + if (i+1 != segments.size()) { + if (segments.at(i).at(segments.at(i).size()-1) == ' ') { + seg += " "; } - else { - sel.cuts.push_back(newstring); + } + // if the segment has a space in the head and it's not the first segment, add the space back + if (i != 0) { + if (segments.at(i).at(0) == ' ') { + seg = " " + seg; } - continue; + } + + // update the segment + segments.at(i) = seg; } - // parse key-value pair - std::istringstream liness(newstring); - std::string key; - std::string value; + // combine the segments back to newstring + newstring = ""; + for (uint i = 0; i < segments.size(); i++) { + newstring += segments.at(i); + } + } + + if (newstring.empty()) continue; + + // handle start of a (sub)selection (implies end of key-value section) + if (boost::algorithm::starts_with(newstring, "SELECTION ")) { + selections.push_back({newstring.substr(10), false, {}}); + continue; + } + if (boost::algorithm::starts_with(newstring, "SUB ")) { + selections.push_back({newstring.substr(4), true, {}}); + continue; + } + + if (!selections.empty()) { + // read body of (sub)selection + auto& sel = selections.back(); + if (boost::algorithm::starts_with(newstring, ". ")) { + // source another (sub)selection here + auto subselName = newstring.substr(2); + auto subselIt = std::find_if(selections.rbegin(), selections.rend(), + [subselName](SelectionData const& sel) { + return(subselName == sel.name); + }); + if (subselIt == selections.rend()) throw std::invalid_argument( + "ConfigurationSettings: unknown selection: " + subselName); + sel.cuts.insert(sel.cuts.end(), subselIt->cuts.begin(), subselIt->cuts.end()); + } else { + sel.cuts.push_back(newstring); + } + continue; + } + + // parse key-value pair + std::istringstream liness(newstring); + std::string key; + std::string value; + + std::getline(liness, key, ' '); //to the space + std::getline(liness, value); //to the end of the line + + auto its = strings_.find(key); + if (its != strings_.end()) { + its->second.m_data = value; + its->second.m_set = true; + } + + //// add dynamic keys + if ("DynamicKeys" == key) { + std::vector<std::string> listofkeys; + std::string separator = ","; + std::string::size_type start = 0, end = 0; + while ((end = value.find(separator, start)) != std::string::npos) { + std::string token = value.substr(start, end - start); + if (token.size()) listofkeys.push_back(token); + start = end + 1; + } - std::getline(liness, key, ' '); //to the space - std::getline(liness, value); //to the end of the line + std::string lasttoken = value.substr(start); + if (lasttoken.size()) listofkeys.push_back(lasttoken); - auto its = m_strings.find(key); - if (its != m_strings.end()) { - its->second.m_data = value; - its->second.m_set = true; + for (auto par : listofkeys) { + registerParameter(par, "Dynamic parameter", ""); } + } + } - //// add dynamic keys - if("DynamicKeys" == key) { - std::vector<std::string> listofkeys; - std::string separator = ","; - std::string::size_type start = 0, end = 0; - while ((end = value.find(separator, start)) != std::string::npos) { - std::string token = value.substr(start, end - start); - if(token.size()) listofkeys.push_back(token); - start = end + 1; - } - - std::string lasttoken = value.substr(start); - if(lasttoken.size()) listofkeys.push_back(lasttoken); - - for(auto par : listofkeys) { - registerParameter(par, "Dynamic parameter", ""); - } - } + for (auto& sel : selections) { + if (sel.isSub) continue; + m_selections.push_back({sel.name, sel.cuts}); } - for (auto & sel : selections) { - if (sel.isSub) - continue; - m_selections.push_back({sel.name, sel.cuts}); + { + auto const& it = strings_.find("KillExperimental"); + m_killedFeatures.clear(); + if (it != strings_.end() && it->second.m_set) { + std::string strValue(it->second.m_data); + boost::trim(strValue); + boost::split(m_killedFeatures, strValue, boost::is_any_of(" ")); + } } input.close(); m_configured = true; -} + } - void ConfigurationSettings::registerParameter(const std::string& name, const std::string& message, const std::string& default_val) { + void ConfigurationSettings::registerParameter(const std::string& name, const std::string& message, + const std::string& default_val) { StringData data; + data.m_data = default_val; data.m_human_explanation = message; data.m_set = (default_val.empty() ? false : true); - m_strings[name] = data; -} + strings_[name] = data; + } -const std::string& ConfigurationSettings::value(const std::string& key) const { + const std::string& ConfigurationSettings::value(const std::string& key) const { //This class never has loadFromFile called if (!m_configured) { - std::string message = "ConfigurationSettings: Not correctly configured\n"; - message.append("You need to call top::ConfigurationSettings::get()->loadFromFile(filename)\n"); - message.append("Early in your program\n"); - throw std::invalid_argument(message); + std::string message = "ConfigurationSettings: Not correctly configured\n"; + message.append("You need to call top::ConfigurationSettings::get()->loadFromFile(filename)\n"); + message.append("Early in your program\n"); + throw std::invalid_argument(message); } - std::map<std::string, StringData>::const_iterator its = m_strings.find(key); + std::map<std::string, StringData>::const_iterator its = strings_.find(key); //The string is not in the map - if (its == m_strings.end()) { - throw std::invalid_argument("ConfigurationSettings: The variable doesn't exist in the code " + key); + if (its == strings_.end()) { + throw std::invalid_argument("ConfigurationSettings: The variable doesn't exist in the code " + key); } //In the map, but never set to anything if (!its->second.m_set) { - throw std::invalid_argument("ConfigurationSettings: You never set a value for " + key); + throw std::invalid_argument("ConfigurationSettings: You never set a value for " + key); } return its->second.m_data; -} + } -bool ConfigurationSettings::configured() const { + bool ConfigurationSettings::configured() const { return m_configured; -} + } -const std::map<std::string, StringData>& ConfigurationSettings::stringData() const { - return m_strings; -} + const std::map<std::string, StringData>& ConfigurationSettings::stringData() const { + return strings_; + } -const std::vector<SelectionConfigurationData> ConfigurationSettings::selections() const { + const std::vector<SelectionConfigurationData> ConfigurationSettings::selections() const { return m_selections; -} + } -bool ConfigurationSettings::retrieve(std::string const & key, bool & value) const { + void ConfigurationSettings::retrieve(std::string const& key, bool& value) const { using boost::trim; using boost::equals; using boost::iequals; auto stringValue = ConfigurationSettings::get()->value(key); trim(stringValue); - if (equals(stringValue, "")) { - return false; - } - if (iequals(stringValue, "false") or iequals(stringValue, "0") or iequals(stringValue, "n") or iequals(stringValue, "no") or iequals(stringValue, "off")) { - value = false; - return true; + + if (iequals(stringValue, "false") or iequals(stringValue, "0") or iequals(stringValue, "n") or iequals(stringValue, + "no") or + iequals(stringValue, "off")) { + value = false; + return; } - if (iequals(stringValue, "true") or iequals(stringValue, "1") or iequals(stringValue, "y") or iequals(stringValue, "yes") or iequals(stringValue, "on")) { - value = true; - return true; + if (iequals(stringValue, "true") or iequals(stringValue, "1") or iequals(stringValue, "y") or iequals(stringValue, + "yes") or + iequals(stringValue, "on")) { + value = true; + return; } throw std::invalid_argument(std::string("expected boolean value for configuration setting ") + key); -} - -} - -std::ostream& operator<<(std::ostream& os, const top::SelectionConfigurationData& data) { + } + + bool ConfigurationSettings::retrieve(std::string const& key) const { + bool result=false; + retrieve(key,result); + return result; + } + + bool ConfigurationSettings::feature(std::string const& name) const { + /* We search a list of strings, not a particularly efficient implementation. + * If need be, we could abuse the aux registry and use integers instead of + * strings. Anyhow, in most cases, the list should be empty. */ + return(m_killedFeatures.empty() || + std::find(m_killedFeatures.begin(), m_killedFeatures.end(), name) == m_killedFeatures.end()); + } + + std::ostream& operator << (std::ostream& os, const SelectionConfigurationData& data) { os << " - " << data.m_name << "\n"; for (const auto& cutname : data.m_cutnames) - os << " " << cutname << "\n"; + os << " " << cutname << "\n"; return os; -} - -std::ostream& operator<<(std::ostream& os, const top::ConfigurationSettings& settings) { - for (std::map<std::string, top::StringData >::const_iterator its = settings.stringData().begin(); its != settings.stringData().end(); ++its) { - std::stringstream s; - s << "\"" << its->first << "\""; - - std::stringstream s2; - s2 << "\"" << its->second.m_data << "\""; - os << std::setw(40) << std::left << s.str() << " : " << std::setw(35) << s2.str() << " - " << std::right << its->second.m_human_explanation << "\n"; + } + + std::ostream& operator << (std::ostream& os, const ConfigurationSettings& settings) { + for (std::map<std::string, top::StringData >::const_iterator its = settings.stringData().begin(); + its != settings.stringData().end(); ++its) { + std::stringstream s; + s << "\"" << its->first << "\""; + + std::stringstream s2; + s2 << "\"" << its->second.m_data << "\""; + os << std::setw(40) << std::left << s.str() << " : " << std::setw(35) << s2.str() << " - " << std::right << + its->second.m_human_explanation << "\n"; } //for (const auto& selection : settings.selections()) // os << selection << "\n"; return os; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/JsonUtils.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/JsonUtils.cxx new file mode 100644 index 000000000000..0bde4b13d88f --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/JsonUtils.cxx @@ -0,0 +1,97 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopConfiguration/JsonUtils.h" + +#include "AsgTools/TProperty.h" + +#include <stdexcept> + +namespace top { + std::string json_dump(std::string const& value) { + std::string out; + out.reserve(value.size() + value.size() / 8 + 8); + char const* hexalphabet = "0123456789abcdef"; + out.push_back('"'); + for (auto it = value.cbegin(); it != value.cend(); it++) { + char c = *it; + if (0x00 <= c && c < 0x20) { + out.push_back('\\'); + switch (c) { + case '\b': out.push_back('b'); + break; + + case '\f': out.push_back('f'); + break; + + case '\n': out.push_back('n'); + break; + + case '\r': out.push_back('r'); + break; + + case '\t': out.push_back('t'); + break; + + default: + out.push_back('x'); + out.push_back(hexalphabet[c >> 4]); + out.push_back(hexalphabet[c & 0xf]); + break; + } + } else { + if (c == '"' || c == '\\') out.push_back('\\'); + out.push_back(c); + } + } + out.push_back('"'); + return out; + } + + namespace { +/** + * @brief Convert values of TProperty<T> instances to JSON. + */ + template<typename T> + class TPropertyValueJsonDumper: public PropertyValueJsonDumper::ISpecializedDumper { + public: + TPropertyValueJsonDumper() : + m_convprop(createProperty(m_value)) { + } + + virtual std::string operator () (Property* prop) override { + if (m_convprop->setFrom(*prop) != 0) throw std::logic_error( + "TPropertyValueJsonDumper called with wrong type of argument"); + return json_dump(m_value); + } + + private: + T m_value; + std::unique_ptr<Property> m_convprop; + }; + } + + + PropertyValueJsonDumper::PropertyValueJsonDumper() { + m_dispatch.emplace_back(Property::BOOL, std::make_unique<TPropertyValueJsonDumper<bool> >()); + m_dispatch.emplace_back(Property::INT, std::make_unique<TPropertyValueJsonDumper<int> >()); + m_dispatch.emplace_back(Property::FLOAT, std::make_unique<TPropertyValueJsonDumper<float> >()); + m_dispatch.emplace_back(Property::DOUBLE, std::make_unique<TPropertyValueJsonDumper<double> >()); + m_dispatch.emplace_back(Property::STRING, std::make_unique<TPropertyValueJsonDumper<std::string> >()); + } + + PropertyValueJsonDumper::~PropertyValueJsonDumper() { + } + + boost::optional<std::string> PropertyValueJsonDumper::operator () (Property* prop) const { + Property::Type propType = prop->type(); + for (auto&& kv : m_dispatch) { + if (kv.first == propType) return (*kv.second)(prop); + } + return boost::none; + } + + PropertyValueJsonDumper::ISpecializedDumper::~ISpecializedDumper() { + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/LinkDef.h index 28d0ad31aa1c..9e5c4faac143 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/LinkDef.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/LinkDef.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #include "TopConfiguration/TopPersistentSettings.h" diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/MsgCategory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/MsgCategory.cxx new file mode 100644 index 000000000000..61251b912f6a --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/MsgCategory.cxx @@ -0,0 +1,6 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#include "TopConfiguration/MsgCategory.h" + +ANA_MSG_SOURCE(TopConfiguration, "TopConfiguration") diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TopConfig.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TopConfig.cxx index 1df5df617329..7f645d967c33 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TopConfig.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TopConfig.cxx @@ -1,22 +1,25 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyrightf (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ -// $Id: TopConfig.cxx 803103 2017-04-18 17:30:51Z tpelzer $ #include "TopConfiguration/TopConfig.h" #include "TopConfiguration/AodMetaDataAccess.h" #include "TopConfiguration/ConfigurationSettings.h" #include <algorithm> +#include <cassert> #include <iterator> #include <sstream> #include <stdexcept> #include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/replace.hpp> #include "TopConfiguration/Tokenize.h" -namespace top{ +#include "TopConfiguration/MsgCategory.h" +using namespace TopConfiguration; +namespace top { TopConfig::TopConfig() : // Prevent any more configuration m_configFixed(false), @@ -25,7 +28,9 @@ namespace top{ // Use which objects m_usePhotons(false), m_useElectrons(false), + m_useFwdElectrons(false), m_useMuons(false), + m_useSoftMuons(false), m_useAntiMuons(false), m_useTaus(false), m_useJets(false), @@ -34,7 +39,7 @@ namespace top{ m_useRCJets(false), m_useVarRCJets(false), m_useJetGhostTrack(false), - + m_useTracks(false), m_useTruthParticles(false), m_useTruthElectrons(false), m_useTruthMuons(false), @@ -45,41 +50,58 @@ namespace top{ m_applyTTVACut(true), + m_demandPriVtx(true), + m_jetSubstructureName("None"), + m_recomputeCPvars(true), + // Do systematics? - this needs many more configuration options m_systematics("SetMe"), /// special syst config m_nominalSystName("Nominal"), m_allSystName("All"), - + m_DSID(-1), m_MapIndex(0), + m_showeringAlgo(SampleXsection::unknown), // Is MC m_isMC(false), // Is AFII m_isAFII(false), + // Generators + m_generators("SetMe"), + // AMITag + m_AMITag("SetMe"), // Is Primary xAOD m_isPrimaryxAOD(false), // Is Truth xAOD m_isTruthDxAOD(false), // Derivation name m_derivationStream("SetMe"), - // Do loose events - m_doLooseEvents(false), - // Do fakes MM weights calculation - m_doFakesMMWeights(false), - // Directory of efficiency files for MM fake estimate - m_FakesMMDir("$ROOTCOREBIN/data/TopFakes"), - // Directory of efficiency files for MM fake estimate - m_doFakesMMDebug(false), + // Do fakes MM weights calculation using FakeBkgTools from IFF + m_doFakesMMWeightsIFF(false), + // Configurations for MM fake estimate using FakeBkgTools from IFF + m_FakesMMConfigIFF("$ROOTCOREBIN/data/TopFakes/efficiencies.xml:1T:1F[T]"), + // Debug level for MM fake estimate using FakeBkgTools from IFF + m_doFakesMMIFFDebug(false), + //options to select if you want to use loose objects for MET rebuilding instead of the tight ones + m_useLooseObjectsInMETInLooseTree(false), + m_useLooseObjectsInMETInNominalTree(false), + //this will write a separate branch with the met built using loose objects + m_writeMETBuiltWithLooseObjects(false), // Apply overlap removal on loose lepton definitons - not the top recommendation, for studies only m_doOverlapRemovalOnLooseLeptonDef(false), // do overlap removal also with large-R jets // (using whatever procedure is used in the official tools) m_doLargeJetOverlapRemoval(false), - // Only dumps the *_Loose trees - also on MC - m_doLooseTreeOnly(false), + // Dumps the normal non-"*_Loose" trees + m_doTightEvents(true), + // Runs Loose selection and dumps the "*_Loose" trees + m_doLooseEvents(false), + // Runs systematics on the given selection + m_doTightSysts(true), + m_doLooseSysts(true), // In the *_Loose trees, lepton SFs are calculated considering // tight ID and isolation instead of loose // Only tight leptons are considered in the event SF calculation @@ -94,9 +116,15 @@ namespace top{ // Write MC generator weights m_doMCGeneratorWeights(false), m_doMCGeneratorWeightsInNominalTrees(false), + m_nominalWeightNames(), + m_nominalWeightName("SetMe"), + m_nominalWeightIndex(-1), + m_MCweightsSize(-1), + m_forceWeightIndex(false), // Top Parton History m_doTopPartonHistory(false), m_isTopPartonHistoryRegisteredInNtuple(false), + m_doTopPartonLevel(true), m_doTopParticleLevel(false), m_doParticleLevelOverlapRemovalMuJet(true), @@ -106,11 +134,13 @@ namespace top{ // KLFitter m_doKLFitter(false), m_KLFitterTransferFunctionsPath("SetMe"), + m_KLFitterOutput("SetMe"), m_KLFitterJetSelectionMode("SetMe"), m_KLFitterBTaggingMethod("SetMe"), m_KLFitterLH("SetMe"), m_KLFitterTopMassFixed(true), m_KLFitterSaveAllPermutations(false), + m_KLFitterFailOnLessThanXJets(false), // PseudoTop m_doPseudoTop(false), @@ -121,14 +151,17 @@ namespace top{ m_sgKeyPrimaryVertices("PrimaryVertices"), m_sgKeyPhotons("SetMe"), m_sgKeyElectrons("SetMe"), + m_sgKeyFwdElectrons("SetMe"), m_sgKeyMuons("SetMe"), + m_sgKeySoftMuons("SetMe"), m_sgKeyTaus("SetMe"), m_sgKeyJets("SetMe"), + m_sgKeyJetsType("SetMe"), m_sgKeyLargeRJets("SetMe"), m_sgKeyTrackJets("SetMe"), + m_sgKeyTrackJetsType("SetMe"), m_sgKeyMissingEt("MET"), m_sgKeyMissingEtLoose("LooseMET"), - m_sgKeyInDetTrackParticles("InDetTrackParticles"), m_sgKeyTruthEvent("TruthEvents"), m_sgKeyMCParticle("SetMe"), @@ -145,81 +178,165 @@ namespace top{ m_sgKeyTopSystematicEventsLoose("TopSystematicEventsLoose"), m_passEventSelectionDecoration("passEventSelection"), m_decoKeyJetGhostTrack("GhostTrack"), + m_sgKeyInDetTrackParticles("InDetTrackParticles"), + m_sgKeyTracks("SetMe"), + + + m_jetResponseMatchingDeltaR(-1), // special: allow to dump the systematics-shifted b-tagging SFs in the systematics trees m_dumpBtagSystsInSystTrees(false), + m_storePerJetBtagSFs(false), + // Electron configuration m_egammaSystematicModel("1NP_v1"), + m_electronEfficiencySystematicModel("TOTAL"), + m_electronEfficiencySystematicModelEtaBinning(""), + m_electronEfficiencySystematicModelEtBinning(""), m_electronID("SetMe"), m_electronIDLoose("SetMe"), m_electronVetoLArCrack(true), m_electronPtcut(25000.), m_electronIsolation("SetMe"), m_electronIsolationLoose("SetMe"), + m_electronIsolationSF("SetMe"), + m_electronIsolationSFLoose("SetMe"), m_electronIsoSFs(true), m_electronIDDecoration("SetMe"), m_electronIDLooseDecoration("SetMe"), + m_useElectronChargeIDSelection(false), + m_useEgammaLeakageCorrection(true), + m_enablePromptLeptonImprovedVetoStudies(false), + + // Fwd electron configuration + m_fwdElectronPtcut(25000.), + m_fwdElectronMinEtacut(2.5), + m_fwdElectronMaxEtacut(4.9), + m_fwdElectronID("SetMe"), + m_fwdElectronIDLoose("SetMe"), + m_fwdElectronBCIDCleaningMinRun(266904), + m_fwdElectronBCIDCleaningMaxRun(311481), // Muon configuration m_muonPtcut(25000.), m_muonEtacut(2.5), m_muonQuality("SetMe"), + m_muonUseMVALowPt(false), + m_muonUse2stationMuonsHighPt(true), m_muonQualityLoose("SetMe"), + m_muonUseMVALowPtLoose(false), + m_muonUse2stationMuonsHighPtLoose(true), m_muonIsolation("SetMe"), m_muonIsolationLoose("SetMe"), + m_muonIsolationSF("SetMe"), + m_muonIsolationSFLoose("SetMe"), + m_muonMuonDoSmearing2stationHighPt(true), + m_muonMuonDoExtraSmearingHighPt(false), + + // Soft Muon configuration + m_softmuonPtcut(4000.), + m_softmuonEtacut(2.5), + m_softmuonQuality("SetMe"), + m_softmuonUseMVALowPt(false), + m_softmuonDRJetcut(0.4), + m_softmuonDRJetcutUseRapidity(false), + m_softmuonAdditionalTruthInfo(false), + m_softmuonAdditionalTruthInfoCheckPartonOrigin(false), + m_softmuonAdditionalTruthInfoDoVerbose(false), // Jet configuration m_jetPtcut(25000.), m_jetEtacut(2.5), - m_fwdJetAndMET("Default"), - m_jetUncertainties_BunchSpacing("25ns"), + m_jetPtGhostTracks(30000.), + m_jetEtaGhostTracks(2.5), m_jetUncertainties_NPModel("AllNuisanceParameters"), + m_jetUncertainties_QGFracFile("None"), + m_jetUncertainties_QGHistPatterns(), m_doMultipleJES(false), m_jetJERSmearingModel("Simple"), m_jetCalibSequence("GSC"), + m_jetStoreTruthLabels("True"), m_doJVTInMETCalculation(true), + m_saveFailJVTJets(false), + m_JVTWP("Default"), + m_doForwardJVTInMETCalculation(false), + m_saveFailForwardJVTJets(false), + m_fJVTWP("None"), + + // MET configuration + m_METUncertaintiesConfigDir("SetMe"), + + // Ghost Track Configuration + m_ghostTrackspT(500.), + m_ghostTracksVertexAssociation("nominal"), + m_ghostTracksQuality("TightPrimary"), m_largeRJetPtcut(25000.), m_largeRJetEtacut(2.5), - m_largeRJESUncertaintyConfig("SetMe"), + m_largeRJetUncertainties_NPModel("CategoryReduction"), + m_largeRJetUncertaintiesConfigDir("SetMe"), m_largeRJESJMSConfig("SetMe"), m_trackJetPtcut(7000.0), m_trackJetEtacut(2.5), + + m_RCJetPtcut(100000.), + m_RCJetEtacut(2.0), + m_RCInputJetPtMin(0.), + m_RCInputJetEtaMax(999.), + m_RCJetTrimcut(0.05), + m_RCJetRadius(1.0), + m_useRCJetSubstructure(false), + m_useRCJetAdditionalSubstructure(false), + + m_VarRCJetPtcut(100000.), + m_VarRCJetEtacut(2.0), + m_VarRCJetTrimcut(0.05), + m_VarRCJetMaxRadius(1.0), + m_VarRCJetRho("2"), + m_VarRCJetMassScale("m_w,m_z,m_h,m_t"), + m_useVarRCJetSubstructure(false), + m_useVarRCJetAdditionalSubstructure(false), + + m_trackQuality("SetMe"), m_JSF(1.0), m_bJSF(1.0), - // Tau configuration + // Tau configuration /** - m_tauJetID("SetMe"), - m_tauJetIDBkg("SetMe"), - m_tauEVetoID("SetMe"), - m_tauVetoLArCrack(false), - m_tauPtcut(20000.), - **/ - // Applying new tau energy calibration - m_applyTauMVATES(false), + m_tauJetID("SetMe"), + m_tauJetIDBkg("SetMe"), + m_tauEVetoID("SetMe"), + m_tauVetoLArCrack(false), + m_tauPtcut(20000.), + **/ // [[[----------------------------------------------- // Particle Level / Truth Configuration - m_truth_electron{ 25000., 2.5, true, false }, - m_truth_muon{ 25000., 2.5, true, false }, - m_truth_photon{ 25000., 2.5, "SET_ME", "SET_ME" }, - m_truth_jet{ 25000., 2.5 }, + m_truth_electron{25000., 2.5, true, false}, + m_truth_muon{25000., 2.5, true, false}, + m_truth_softmuon{4000., 2.5}, + m_truth_photon{25000., 2.5, "SET_ME", "SET_ME"}, + m_truth_jet{25000., 2.5}, // -----------------------------------------------]]] // HL LHC studies m_HLLHC(false), + m_HLLHCFakes(false), // Selections m_allSelectionNames(nullptr), // Trigger - m_allTriggers(nullptr), - m_electronTriggers(nullptr), - m_muonTriggers(nullptr), - m_tauTriggers(nullptr), + m_allTriggers_Tight(nullptr), + m_electronTriggers_Tight(nullptr), + m_muonTriggers_Tight(nullptr), + m_tauTriggers_Tight(nullptr), + m_allTriggers_Loose(nullptr), + m_electronTriggers_Loose(nullptr), + m_muonTriggers_Loose(nullptr), + m_tauTriggers_Loose(nullptr), // Where the sum of event weights // before derivation framework is kept @@ -233,7 +350,9 @@ namespace top{ m_outputEvents("SetMe"), m_saveOnlySelectedEvents(true), m_outputFileSetAutoFlushZero(false), - + m_outputFileNEventAutoFlush(1000), // 1000 events + m_outputFileBasketSizePrimitive(4096), // 4kB + m_outputFileBasketSizeVector(40960), // 40kB // Number of events to run on (only for testing) m_numberOfEventsToRun(0), @@ -247,11 +366,14 @@ namespace top{ m_systHashPhotons(nullptr), m_systHashElectrons(nullptr), + m_systHashFwdElectrons(nullptr), m_systHashMuons(nullptr), + m_systHashSoftMuons(nullptr), m_systHashTaus(nullptr), m_systHashJets(nullptr), m_systHashLargeRJets(nullptr), m_systHashTrackJets(nullptr), + m_systHashTracks(nullptr), m_systHashMET(nullptr), m_systHashAll(nullptr), @@ -262,31 +384,40 @@ namespace top{ m_systMapPhotons(nullptr), m_systMapElectrons(nullptr), + m_systMapFwdElectrons(nullptr), m_systMapMuons(nullptr), + m_systMapSoftMuons(nullptr), m_systMapTaus(nullptr), m_systMapJets(nullptr), m_systMapLargeRJets(nullptr), m_systMapTrackJets(nullptr), + m_systMapTracks(nullptr), m_systMapMET(nullptr), m_systSgKeyMapPhotons(nullptr), m_systSgKeyMapElectrons(nullptr), + m_systSgKeyMapFwdElectrons(nullptr), m_systSgKeyMapMuons(nullptr), + m_systSgKeyMapSoftMuons(nullptr), m_systSgKeyMapTaus(nullptr), m_systSgKeyMapJets(nullptr), m_systSgKeyMapJets_electronInJetSubtraction(nullptr), m_systSgKeyMapJetsLoose_electronInJetSubtraction(nullptr), m_systSgKeyMapLargeRJets(nullptr), m_systSgKeyMapTrackJets(nullptr), + m_systSgKeyMapTracks(nullptr), m_systSgKeyMapMET(nullptr), m_systAllSgKeyMapPhotons(nullptr), m_systAllSgKeyMapElectrons(nullptr), + m_systAllSgKeyMapFwdElectrons(nullptr), m_systAllSgKeyMapMuons(nullptr), + m_systAllSgKeyMapSoftMuons(nullptr), m_systAllSgKeyMapTaus(nullptr), m_systAllSgKeyMapJets(nullptr), m_systAllSgKeyMapLargeRJets(nullptr), m_systAllSgKeyMapTrackJets(nullptr), + m_systAllSgKeyMapTracks(nullptr), m_systAllSgKeyMapElectrons_electronInJetSubtraction(nullptr), m_systAllSgKeyMapJets_electronInJetSubtraction(nullptr), m_systAllSgKeyMapJetsLoose_electronInJetSubtraction(nullptr), @@ -295,8 +426,12 @@ namespace top{ m_systAllSgKeyMapPhotonsTDSAux(nullptr), m_systAllSgKeyMapElectronsTDS(nullptr), m_systAllSgKeyMapElectronsTDSAux(nullptr), + m_systAllSgKeyMapFwdElectronsTDS(nullptr), + m_systAllSgKeyMapFwdElectronsTDSAux(nullptr), m_systAllSgKeyMapMuonsTDS(nullptr), m_systAllSgKeyMapMuonsTDSAux(nullptr), + m_systAllSgKeyMapSoftMuonsTDS(nullptr), + m_systAllSgKeyMapSoftMuonsTDSAux(nullptr), m_systAllSgKeyMapTausTDS(nullptr), m_systAllSgKeyMapTausTDSAux(nullptr), m_systAllSgKeyMapJetsTDS(nullptr), @@ -305,6 +440,8 @@ namespace top{ m_systAllSgKeyMapLargeRJetsTDSAux(nullptr), m_systAllSgKeyMapTrackJetsTDS(nullptr), m_systAllSgKeyMapTrackJetsTDSAux(nullptr), + m_systAllSgKeyMapTracksTDS(nullptr), + m_systAllSgKeyMapTracksTDSAux(nullptr), m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS(nullptr), m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux(nullptr), m_systAllSgKeyMapJets_electronInJetSubtractionTDS(nullptr), @@ -321,484 +458,1162 @@ namespace top{ m_sgKeyPseudoTop("PseudoTopResult"), m_systSgKeyMapPseudoTop(nullptr), + m_systSgKeyMapPseudoTopLoose(nullptr), m_systMapJetGhostTrack(nullptr), m_systDecoKeyMapJetGhostTrack(nullptr), m_systAllTTreeNames(nullptr), m_systPersistantAllTTreeNames(nullptr), m_systAllTTreeIndex(nullptr), - m_systAllTTreeLooseIndex(nullptr) - { - m_allSelectionNames = std::shared_ptr<std::vector<std::string>> ( new std::vector<std::string> ); - - m_systHashPhotons = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_systHashElectrons = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_systHashMuons = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_systHashTaus = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_systHashJets = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_systHashLargeRJets = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_systHashTrackJets = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_systHashMET = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - - m_systHashAll = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_list_systHashAll = std::shared_ptr<std::list<std::size_t>> ( new std::list<std::size_t> ); - m_systHash_electronInJetSubtraction = std::shared_ptr<std::unordered_set<std::size_t>> ( new std::unordered_set<std::size_t> ); - m_list_systHash_electronInJetSubtraction = std::shared_ptr<std::list<std::size_t>> ( new std::list<std::size_t> ); - - m_systMapPhotons = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - m_systMapElectrons = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - m_systMapMuons = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - m_systMapTaus = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - m_systMapJets = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - m_systMapLargeRJets = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - m_systMapTrackJets = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - m_systMapMET = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - - m_systSgKeyMapPhotons = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapElectrons = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapMuons = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapTaus = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapJets = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapJets_electronInJetSubtraction = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapJetsLoose_electronInJetSubtraction = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapLargeRJets = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapTrackJets = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapMET = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - - m_systAllSgKeyMapPhotons = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapElectrons = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapMuons = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapTaus = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapJets = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapLargeRJets = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapTrackJets = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); + m_systAllTTreeLooseIndex(nullptr), + m_saveBootstrapWeights(false), + m_BootstrapReplicas(100), + m_useBadBatmanCleaning(true), + m_badBatmanCleaningMin(276262), + m_badBatmanCleaningMax(311481), + m_useEventLevelJetCleaningTool(false), + m_year("UNKNOWN") { + m_allSelectionNames = std::shared_ptr<std::vector<std::string> > (new std::vector<std::string> ); + + m_systHashPhotons = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashElectrons = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashFwdElectrons = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashMuons = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashSoftMuons = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashTaus = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashJets = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashLargeRJets = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashTrackJets = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashTracks = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_systHashMET = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + + m_systHashAll = std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_list_systHashAll = std::shared_ptr<std::list<std::size_t> > (new std::list<std::size_t> ); + m_systHash_electronInJetSubtraction = + std::shared_ptr<std::unordered_set<std::size_t> > (new std::unordered_set<std::size_t> ); + m_list_systHash_electronInJetSubtraction = std::shared_ptr<std::list<std::size_t> > (new std::list<std::size_t> ); + + m_systMapPhotons = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + m_systMapElectrons = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + m_systMapFwdElectrons = std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > ( + new std::unordered_map<std::size_t, CP::SystematicSet> ); + m_systMapMuons = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + m_systMapSoftMuons = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + m_systMapTaus = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + m_systMapJets = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + m_systMapLargeRJets = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + m_systMapTrackJets = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + m_systMapTracks = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + + + + m_systMapMET = + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > (new std::unordered_map<std::size_t, + CP::SystematicSet> ); + + m_systSgKeyMapPhotons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapElectrons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapFwdElectrons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapMuons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapSoftMuons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapTaus = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapJets = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapJets_electronInJetSubtraction = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systSgKeyMapJetsLoose_electronInJetSubtraction = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systSgKeyMapLargeRJets = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapTrackJets = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + + m_systSgKeyMapTracks = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + + + m_systSgKeyMapMET = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + + m_systAllSgKeyMapPhotons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapElectrons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapFwdElectrons = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapMuons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapSoftMuons = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapTaus = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapJets = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapLargeRJets = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapTrackJets = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapTracks = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); m_systAllSgKeyMapElectrons_electronInJetSubtraction - = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); + = std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); m_systAllSgKeyMapJets_electronInJetSubtraction - = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); + = std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); m_systAllSgKeyMapJetsLoose_electronInJetSubtraction - = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - - m_systAllSgKeyMapPhotonsTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapPhotonsTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapElectronsTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapElectronsTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapMuonsTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapMuonsTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapTausTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapTausTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapJetsTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapJetsTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapLargeRJetsTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapLargeRJetsTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapTrackJetsTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapTrackJetsTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapJets_electronInJetSubtractionTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - - - m_systSgKeyMapMissingET = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapMissingETLoose = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - - m_systSgKeyMapKLFitter = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systSgKeyMapKLFitterLoose = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - - m_systSgKeyMapPseudoTop = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - - m_systMapJetGhostTrack = std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> ( new std::unordered_map<std::size_t,CP::SystematicSet> ); - m_systDecoKeyMapJetGhostTrack = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - - m_systAllTTreeNames = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systPersistantAllTTreeNames = std::shared_ptr<std::unordered_map<std::size_t,std::string>> ( new std::unordered_map<std::size_t,std::string> ); - m_systAllTTreeIndex = std::shared_ptr<std::unordered_map<std::size_t,unsigned int>> ( new std::unordered_map<std::size_t,unsigned int> ); - m_systAllTTreeLooseIndex = std::shared_ptr<std::unordered_map<std::size_t,unsigned int>> ( new std::unordered_map<std::size_t,unsigned int> ); + = std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + + m_systAllSgKeyMapPhotonsTDS = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapPhotonsTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapElectronsTDS = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapElectronsTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapFwdElectronsTDS = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapFwdElectronsTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapMuonsTDS = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapMuonsTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapSoftMuonsTDS = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapSoftMuonsTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapTausTDS = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapTausTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapJetsTDS = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapJetsTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapLargeRJetsTDS = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapLargeRJetsTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapTrackJetsTDS = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapTrackJetsTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapTracksTDS = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapTracksTDSAux = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + + m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapJets_electronInJetSubtractionTDS = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + + + m_systSgKeyMapMissingET = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapMissingETLoose = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + + m_systSgKeyMapKLFitter = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapKLFitterLoose = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + + m_systSgKeyMapPseudoTop = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systSgKeyMapPseudoTopLoose = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + + m_systMapJetGhostTrack = std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > ( + new std::unordered_map<std::size_t, CP::SystematicSet> ); + m_systDecoKeyMapJetGhostTrack = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + + + m_systAllTTreeNames = + std::shared_ptr<std::unordered_map<std::size_t, std::string> > (new std::unordered_map<std::size_t, + std::string> ); + m_systPersistantAllTTreeNames = std::shared_ptr<std::unordered_map<std::size_t, std::string> > ( + new std::unordered_map<std::size_t, std::string> ); + m_systAllTTreeIndex = + std::shared_ptr<std::unordered_map<std::size_t, unsigned int> > (new std::unordered_map<std::size_t, + unsigned int> ); + m_systAllTTreeLooseIndex = + std::shared_ptr<std::unordered_map<std::size_t, unsigned int> > (new std::unordered_map<std::size_t, + unsigned int> ); // Nominal has value CP::SystematicSet nominal; m_nominalHashValue = nominal.hash(); + + m_treeFilter = std::make_shared<TreeFilter>(); } - void TopConfig::setConfigSettings( top::ConfigurationSettings* const& settings ) - { + void TopConfig::setConfigSettings(top::ConfigurationSettings* const& settings) { // Selections const std::vector<top::SelectionConfigurationData> allSelections = settings->selections(); + for (auto sel : allSelections) { - m_allSelectionNames->push_back( sel.m_name ); + m_allSelectionNames->push_back(sel.m_name); } // set GRL file - this->setGrlDir( settings->value("GRLDir") ); - this->setGrlFile( settings->value("GRLFile") ); + this->setGrlDir(settings->value("GRLDir")); + this->setGrlFile(settings->value("GRLFile")); + + // Set TDP file name + this->setTDPPath(settings->value("TDPPath")); + + m_treeFilter->init(settings->value("FilterTrees")); + //we need storegate keys so people can pick different collections / met / jets etc. - this->sgKeyPhotons( settings->value("PhotonCollectionName") ); - this->sgKeyElectrons( settings->value("ElectronCollectionName") ); - this->sgKeyMuons( settings->value("MuonCollectionName") ); - this->sgKeyTaus( settings->value("TauCollectionName") ); - this->sgKeyJets( settings->value("JetCollectionName") ); - this->sgKeyLargeRJets( settings->value("LargeJetCollectionName") ); - this->sgKeyTrackJets( settings->value("TrackJetCollectionName") ); - this->jetSubstructureName( settings->value("LargeJetSubstructure") ); - this->decoKeyJetGhostTrack( settings->value("JetGhostTrackDecoName") ); - - if(settings->value("applyTTVACut") == "False") - this->m_applyTTVACut = false; + this->sgKeyPhotons(settings->value("PhotonCollectionName")); + this->sgKeyElectrons(settings->value("ElectronCollectionName")); + this->sgKeyFwdElectrons(settings->value("FwdElectronCollectionName")); + this->sgKeyMuons(settings->value("MuonCollectionName")); + //small trick for the soft muons + if (settings->value("UseSoftMuons") == "True") this->sgKeySoftMuons("Soft" + settings->value("MuonCollectionName")); + + else this->sgKeySoftMuons("None"); + this->sgKeyTaus(settings->value("TauCollectionName")); + this->sgKeyJets(settings->value("JetCollectionName")); + this->sgKeyLargeRJets(settings->value("LargeJetCollectionName")); + this->sgKeyTrackJets(settings->value("TrackJetCollectionName")); + this->sgKeyTracks(settings->value("TrackCollectionName")); + this->jetSubstructureName(settings->value("LargeJetSubstructure")); + this->decoKeyJetGhostTrack(settings->value("JetGhostTrackDecoName")); + + // check that jets use tagged collection name for new derivations + // this is due to b-tagging breaking changes in derivations + if (m_aodMetaData->valid()) { + try { + std::string deriv_rel_name = m_aodMetaData->get("/TagInfo", "AtlasRelease_AODtoDAOD"); + ATH_MSG_INFO("Checking jet collection name compatibility, reading (MetaData->TagInfo): " << deriv_rel_name); + size_t pos = deriv_rel_name.find('-'); + if (pos != std::string::npos) { + deriv_rel_name = deriv_rel_name.substr(pos + 1); + int deriv_rel; + std::sscanf(deriv_rel_name.c_str(), "21.2.%d", &deriv_rel); + // check for derivation version due to format breakage with calo jet b-tagging + if (deriv_rel >= 72) { // 21.2.72.0: release where we need tagged jet collection + if (this->sgKeyJets() == this->sgKeyJetsType()) { // jet collection is NOT tagged + throw std::runtime_error( + "TopConfig: You are using derivation with release 21.2.72.0 or newer and did not specify tagged small-R jet collection, e.g. \"AntiKt4EMPFlowJets_BTagging201903\". This is necessary for b-tagging to work!"); + } + } else { // release does NOT have tagged jet collection + if (this->sgKeyJets() != this->sgKeyJetsType()) { // jet collection is NOT tagged + throw std::runtime_error( + "TopConfig: You are using derivation with release older than 21.2.72.0 so you cannot use tagged jet containers as you specified: \"" + this->sgKeyJets() + "\". Use \"" + this->sgKeyJetsType() + + "\" instead."); + } + } + // check for derivation version due to format breakage with track jet b-tagging + if (this->useTrackJets()) { + if (deriv_rel >= 87) { // 21.2.87.0: release where we need tagged track jet collection + if (this->sgKeyTrackJets() == this->sgKeyTrackJetsType()) { // jet collection is NOT tagged + throw std::runtime_error( + "TopConfig: You are using derivation with release 21.2.87.0 or newer and did not specify tagged track jet collection, e.g. \"AntiKtVR30Rmax4Rmin02TrackJets_BTagging201903\". This is necessary for b-tagging to work!"); + } + } else { // release does NOT have tagged jet collection + if (this->sgKeyTrackJets() != this->sgKeyTrackJetsType()) { // jet collection is NOT tagged + throw std::runtime_error( + "TopConfig: You are using derivation with release older than 21.2.87.0 so you cannot use tagged track jet containers as you specified: \"" + this->sgKeyTrackJets() + "\". Use \"" + this->sgKeyTrackJetsType() + + "\" instead."); + } + } + } + // check derivation version due to fJVT info needed at derivation level for PFlow + if (this->useParticleFlowJets() && (settings->retrieve("ForwardJVTinMETCalculation") || settings->value("ForwardJVTWP") != "None")){ //fJVT requested for PFlow + if (deriv_rel < 97) { //21.2.97.0 + throw std::runtime_error( + "TopConfig: You are using derivation with release 21.2.96.0 or older and requested fJVT for particle-flow jets. The necessary information for PFlow fjvt is only present from release 21.2.97.0 and newer, you will need to switch to newer derivations or turn off fJVT (ForwardJVTWP = \"None\" && ForwardJVTinMETCalculation = \"False\")"); + } + } + } else { + ATH_MSG_WARNING("Could not parse derivation release from the file metadata. We cannot check that correct jet and/or track jet collection is used for b-tagging, or that a new enough derivation is used for PFlow fJVT. You are on your own."); + } + // try to parse the derivation release, we need the release number + } catch (std::logic_error& e) { + ATH_MSG_WARNING(e.what()); + ATH_MSG_WARNING("Could not obtain derivation release from the file metadata. We cannot check that correct jet and/or track jet collection is used for b-tagging, or that a new enough derivation is used for PFlow fJVT. You are on your own."); + } + } + + // ROOTCORE/Analysis release series + this->setReleaseSeries(); + + if (settings->value("applyTTVACut") == "False") this->m_applyTTVACut = false; if (this->isMC()) { - this->sgKeyMCParticle( settings->value("TruthCollectionName") ); - this->sgKeyTruthElectrons( settings->value("TruthElectronCollectionName") ); - this->sgKeyTruthMuons( settings->value("TruthMuonCollectionName") ); - this->sgKeyTruthPhotons( settings->value("TruthPhotonCollectionName") ); - this->sgKeyTruthMET( settings->value("TruthMETCollectionName") ); - this->sgKeyTruthJets( settings->value("TruthJetCollectionName") ); - this->sgKeyTruthLargeRJets( settings->value("TruthLargeRJetCollectionName") ); + this->sgKeyMCParticle(settings->value("TruthCollectionName")); + this->sgKeyTruthElectrons(settings->value("TruthElectronCollectionName")); + this->sgKeyTruthMuons(settings->value("TruthMuonCollectionName")); + this->sgKeyTruthPhotons(settings->value("TruthPhotonCollectionName")); + this->sgKeyTruthMET(settings->value("TruthMETCollectionName")); + this->sgKeyTruthJets(settings->value("TruthJetCollectionName")); + this->sgKeyTruthLargeRJets(settings->value("TruthLargeRJetCollectionName")); + this->sgKeyTruthTaus(settings->value("TruthTauCollectionName")); // Dump truth block - if (settings->value("TruthBlockInfo") == "True") - this->setTruthBlockInfo(); + if (settings->value("TruthBlockInfo") == "True") this->setTruthBlockInfo(); // Save the Truth PDF information if (settings->value("PDFInfo") == "True") { - this->setTruthPDFInfo(); - } - else if (settings->value("PDFInfo") == "Nominal") { - // Save the Truth PDF information in the reco-level tree instead of the truth-level one - this->setTruthPDFInfo(); - this->setTruthPDFInfoInNominalTrees(); + this->setTruthPDFInfo(); + } else if (settings->value("PDFInfo") == "Nominal") { + // Save the Truth PDF information in the reco-level tree instead of the truth-level one + this->setTruthPDFInfo(); + this->setTruthPDFInfoInNominalTrees(); } // Save the MC generator weights if (settings->value("MCGeneratorWeights") == "True") { - this->setMCGeneratorWeights(); + this->setMCGeneratorWeights(); + } else if (settings->value("MCGeneratorWeights") == "Nominal") { + // Save the Truth PDF information in the reco-level tree instead of the truth-level one + this->setMCGeneratorWeights(); + this->setMCGeneratorWeightsInNominalTrees(); + } + + // load the nominal weight names that we should try to get the real nominal weight name + const std::string& tmp = settings->value("NominalWeightNames"); + + // Remove the whitespaces between the names but keep + // the whitespaces within quotation marks + std::string trimmedName = ""; + bool deleteSpaces = true; + bool start = false; + for(unsigned int i = 0; i < tmp.size(); ++i) { + if(tmp[i] == '\"') { + start ? start = false : start = true; + if(start) { + deleteSpaces = false; + } + } + if(!start) { + deleteSpaces = true; + } + if(deleteSpaces) { + if(tmp[i] != ' ') { + trimmedName += tmp[i]; + } + } else { + trimmedName += tmp[i]; + } } - else if (settings->value("MCGeneratorWeights") == "Nominal") { - // Save the Truth PDF information in the reco-level tree instead of the truth-level one - this->setMCGeneratorWeights(); - this->setMCGeneratorWeightsInNominalTrees(); + boost::split(m_nominalWeightNames, trimmedName, boost::is_any_of(",")); + // now remove all occurences of '"' + for (std::string& iname : m_nominalWeightNames) { + iname.erase(std::remove(iname.begin(), iname.end(), '"'), iname.end()); + // and check if we have newline characters (some weight have those...) + // and parse them properly + boost::replace_all(iname, "\\n", "\n"); } - // Save the Top Parton History - if (this->useTruthParticles() && settings->value("TopPartonHistory") != "False") - this->setTopPartonHistory(); + try { + m_nominalWeightIndex = std::stoi(settings->value("NominalWeightFallbackIndex")); + } catch (std::invalid_argument &e) { + std::cout << "Failed to parse NominalWeightFallbackIndex value: " << settings->value("NominalWeightFallbackIndex") << std::endl; + throw; + } + settings->retrieve("ForceNominalWeightFallbackIndex", m_forceWeightIndex); + + // Save the Top Parton History + if (settings->value("TopPartonHistory") != "False") this->setTopPartonHistory(); + + // Perform parton-level selection and save particle level objects + bool topPartonLevel=true; + settings->retrieve("TopPartonLevel",topPartonLevel); + this->setTopPartonLevel(topPartonLevel); + // Perform particle-level selection and save particle level objects - if ( settings->value("TopParticleLevel") == "True" ){ - this->setTopParticleLevel(); - } + bool topParticleLevel=true; + settings->retrieve("TopParticleLevel",topParticleLevel); + this->setTopParticleLevel(topParticleLevel); + // Particle-level OR - if (settings->value("DoParticleLevelOverlapRemoval") == "True"){ - // Value True -> Do all ORs - this->setParticleLevelOverlapRemovalElJet(true); - this->setParticleLevelOverlapRemovalMuJet(true); - this->setParticleLevelOverlapRemovalJetPhoton(true); - } else if (settings->value("DoParticleLevelOverlapRemoval") == "False"){ - // Value False -> Do not perform any OR. - this->setParticleLevelOverlapRemovalElJet(false); - this->setParticleLevelOverlapRemovalMuJet(false); - this->setParticleLevelOverlapRemovalJetPhoton(false); + if (settings->value("DoParticleLevelOverlapRemoval") == "True") { + // Value True -> Do all ORs + this->setParticleLevelOverlapRemovalElJet(true); + this->setParticleLevelOverlapRemovalMuJet(true); + this->setParticleLevelOverlapRemovalJetPhoton(true); + } else if (settings->value("DoParticleLevelOverlapRemoval") == "False") { + // Value False -> Do not perform any OR. + this->setParticleLevelOverlapRemovalElJet(false); + this->setParticleLevelOverlapRemovalMuJet(false); + this->setParticleLevelOverlapRemovalJetPhoton(false); } else { - // Explicitly specify the possible OR values. - std::vector<std::string> tokens; - tokenize(settings->value("DoParticleLevelOverlapRemoval"), tokens, ","); - while (tokens.size()){ - const auto & token = tokens.back(); - - if (token == "MuonJet"){ - this->setParticleLevelOverlapRemovalMuJet(true); - } else if (token == "ElectronJet"){ - this->setParticleLevelOverlapRemovalElJet(true); - } else if (token == "JetPhoton"){ - this->setParticleLevelOverlapRemovalJetPhoton(true); - } else { - throw std::runtime_error{"TopConfig: Option DoParticleLevelOverlapRemoval: Invalid Token"}; - } - - // Remove the last token in the container. - tokens.pop_back(); + // Explicitly specify the possible OR values. + std::vector<std::string> tokens; + tokenize(settings->value("DoParticleLevelOverlapRemoval"), tokens, ","); + while (tokens.size()) { + const auto& token = tokens.back(); + + if (token == "MuonJet") { + this->setParticleLevelOverlapRemovalMuJet(true); + } else if (token == "ElectronJet") { + this->setParticleLevelOverlapRemovalElJet(true); + } else if (token == "JetPhoton") { + this->setParticleLevelOverlapRemovalJetPhoton(true); + } else { + throw std::runtime_error { + "TopConfig: Option DoParticleLevelOverlapRemoval: Invalid Token" + }; } - } + // Remove the last token in the container. + tokens.pop_back(); + } + } // check if you are running over AFII samples // only check the configuration file if the AodMetaData is not instatiated - if(m_aodMetaData->valid()){ - try{ - auto simulatorName = m_aodMetaData->get("/Simulation/Parameters","Simulator"); - bool aodMetaDataIsAFII = m_aodMetaData->isAFII(); - std::cout << "AodMetaData :: Simulation Type " << simulatorName << " -> " << "Setting IsAFII to " << aodMetaDataIsAFII << std::endl; - this->setIsAFII(aodMetaDataIsAFII); - } - catch(std::logic_error aodMetaDataError){ - std::cout << "An error was encountered handling AodMetaData : " << aodMetaDataError.what() << std::endl; - std::cout << "We will attempt to read the IsAFII flag from your config." << std::endl; - this->ReadIsAFII(settings); - } - } - else{ - this->ReadIsAFII(settings); - } - // Special mode to run Loose events on MC for the purposes - // of determining the Fakes control regions - // Not for regular analysis users - // If you use this option, and are not part of the Fakes sub-group, you just joined! - // Please report your studies in the top-fakes meetings! - if (settings->value("FakesControlRegionDoLooseMC") == "True") - this->FakesControlRegionDetermination_setDoLooseEventsOnMC_notForRegularUsers(); - } - - if (!this->isMC()) { - m_doLooseEvents = true; - if (settings->value("FakesMMWeights") == "True") { - this->setFakesMMWeightsCalculation(); - std::string dir = settings->value("FakesMMDir"); - if (dir != "") - this->setFakesMMDir(dir); - if (settings->value("FakesMMDebug") == "True") - this->setFakesMMDebug(); + if (m_aodMetaData->valid()) { + try{ + auto simulatorName = m_aodMetaData->get("/Simulation/Parameters", "Simulator"); + bool aodMetaDataIsAFII = m_aodMetaData->isAFII(); + ATH_MSG_INFO("AodMetaData :: Simulation Type " << simulatorName << " -> " << "Setting IsAFII to " << + aodMetaDataIsAFII); + this->setIsAFII(aodMetaDataIsAFII); + auto generatorsName = m_aodMetaData->get("/TagInfo", "generators"); + ATH_MSG_INFO("AodMetaData :: Generators Type " << generatorsName); + this->setGenerators(generatorsName); + auto AMITagName = m_aodMetaData->get("/TagInfo", "AMITag"); + ATH_MSG_INFO("AodMetaData :: AMITag " << AMITagName); + this->setAMITag(AMITagName); + } + catch (const std::logic_error& aodMetaDataError) { + ATH_MSG_WARNING("An error was encountered handling AodMetaData : " << aodMetaDataError.what()); + ATH_MSG_WARNING("We will attempt to read the IsAFII flag from your config."); + this->ReadIsAFII(settings); + ATH_MSG_WARNING("Unfortunately, we can not read MC generators and AMITag without valid MetaData."); + this->setGenerators("unknown"); + this->setAMITag("unknown"); + } + } else { + this->ReadIsAFII(settings); + } + } + + // Get list of branches to be filtered + if (settings->value("FilterBranches") != " ") { + std::vector<std::string> branches; + tokenize(settings->value("FilterBranches"), branches, ","); + + if (branches.size() == 0) { + ATH_MSG_WARNING("You provided \"FilterBranches\" option but you did not provide any meaningful values. Ignoring"); + } + this->setFilterBranches(branches); + } + + // Get list of PartonLevel branches to be filtered + if (settings->value("FilterPartonLevelBranches") != " ") { + std::vector<std::string> branches; + tokenize(settings->value("FilterPartonLevelBranches"), branches, ","); + + if (branches.size() == 0) { + ATH_MSG_WARNING("You provided \"FilterPartonLevelBranches\" option but you did not provide any meaningful values. Ignoring"); + } + this->setFilterPartonLevelBranches(branches); + } + + // Get list of ParticleLevel branches to be filtered + if (settings->value("FilterParticleLevelBranches") != " ") { + std::vector<std::string> branches; + tokenize(settings->value("FilterParticleLevelBranches"), branches, ","); + + if (branches.size() == 0) { + ATH_MSG_WARNING("You provided \"FilterParticleLevelBranches\" option but you did not provide any meaningful values. Ignoring"); } + this->setFilterParticleLevelBranches(branches); + } + + // Get list of nominal_Loose branches to be filtered + if (settings->value("FilterNominalLooseBranches") != " ") { + std::vector<std::string> branches; + tokenize(settings->value("FilterNominalLooseBranches"), branches, ","); + + if (branches.size() == 0) { + ATH_MSG_WARNING("You provided \"FilterNominalLooseBranches\" option but you did not provide any meaningful values. Ignoring"); + } + this->setFilterNominalLooseBranches(branches); + } + + // Force recomputation of CP variables? + if (settings->value("RecomputeCPVariables") == "False") m_recomputeCPvars = false; + + // Bootstrapping weights (permitted in MC and Data) + if (settings->value("SaveBootstrapWeights") == "True") { + this->setSaveBootstrapWeights(true); + this->setNumberOfBootstrapReplicas(std::atoi(settings->value("NumberOfBootstrapReplicas").c_str())); + } + + settings->retrieve("UseLooseObjectsInMETInLooseTree", m_useLooseObjectsInMETInLooseTree); + settings->retrieve("UseLooseObjectsInMETInNominalTree", m_useLooseObjectsInMETInNominalTree); + settings->retrieve("WriteMETBuiltWithLooseObjects", m_writeMETBuiltWithLooseObjects); + + if (this->isMC()) { + m_doLooseEvents = (settings->value("DoLoose") == "MC" || settings->value("DoLoose") == "Both"); + m_doTightEvents = (settings->value("DoTight") == "MC" || settings->value("DoTight") == "Both"); + m_doLooseSysts = (settings->value("DoSysts") == "Loose" || settings->value("DoSysts") == "Both") && + m_doLooseEvents; + m_doTightSysts = (settings->value("DoSysts") == "Tight" || settings->value("DoSysts") == "Both") && + m_doTightEvents; + } else { + m_doLooseEvents = (settings->value("DoLoose") == "Data" || settings->value("DoLoose") == "Both"); + if (m_doLooseEvents) { + if (settings->value("FakesMMWeightsIFF") == "True") { + this->setFakesMMWeightsCalculationIFF(); + std::string configIFF = settings->value("FakesMMConfigIFF"); + if (configIFF != "") { + this->setFakesMMConfigIFF(configIFF); + } + if (settings->value("FakesMMIFFDebug") == "True") { + this->setFakesMMIFFDebug(); + } + } + } + m_doTightEvents = (settings->value("DoTight") == "Data" || settings->value("DoTight") == "Both"); + } + + // Switch to set event BadBatman cleaning + if (settings->value("UseBadBatmanCleaning") == "False") { + this->setUseBadBatmanCleaning(false); + } else if (settings->value("UseBadBatmanCleaning") == "True") { + this->setUseBadBatmanCleaning(true); + } else { + throw std::invalid_argument { + "TopConfig: Option UseBadBatmanCleaning unknown value, only True or False (default) is allowed" + }; + } + + // now check the ranges of the batman cleaning + { + std::vector<std::string> tokens; + tokenize(settings->value("BadBatmanCleaningRange"), tokens, ":"); + if (tokens.size() != 2) { + throw std::runtime_error { + "TopConfig: Option BadBatmanCleaningRange should be of the form \'RunNumber1:RunNumber2\'" + }; + } + unsigned int minRunNumber = 999999; + unsigned int maxRunNumber = 0; + try { // convert the values from string to unsigned int + minRunNumber = std::stoul(tokens.at(0)); + maxRunNumber = std::stoul(tokens.at(1)); + } catch (...) { + throw std::invalid_argument { + "TopConfig: Option BadBatmanCleaningRange cannot convert the RunNumbers into unsigned int" + }; + } + + // check if the first value is not larger than the second value + if (maxRunNumber < minRunNumber) { + throw std::invalid_argument { + "TopConfig: Option BadBatmanCleaningRange: the first RunNumber cannot be larger than the second!" + }; + } + + // check if there is an overlap with data 2017 as this option should not be used for this period + static const unsigned int data17_begin = 325713; + static const unsigned int data17_end = 348835; + + if (std::max(minRunNumber, data17_begin) <= std::min(maxRunNumber, data17_end)) { + throw std::invalid_argument { + "TopConfig: Option BadBatmanCleaningRange cannot include RunNumbers from 2017 data taking (325713-348835)" + }; + } + + this->setBadBatmanCleaningMin(minRunNumber); + this->setBadBatmanCleaningMax(maxRunNumber); + } + + // Switch to set event level jet cleaning tool [false by default] + if (settings->value("UseEventLevelJetCleaningTool") == "True") { + this->setUseEventLevelJetCleaningTool(true); } // Object Selection Name - this->objectSelectionName( settings->value("ObjectSelectionName") ); + this->objectSelectionName(settings->value("ObjectSelectionName")); // Output Format - this->outputFormat( settings->value("OutputFormat") ); + this->outputFormat(settings->value("OutputFormat")); // Output Events - this->outputEvents( settings->value("OutputEvents") ); + this->outputEvents(settings->value("OutputEvents")); // SetAutoFlush(0) on EventSaverFlatNtuple for ANALYSISTO-44 workaround m_outputFileSetAutoFlushZero = false; - if (settings->value( "OutputFileSetAutoFlushZero" ) == "True") - m_outputFileSetAutoFlushZero = true; + if (settings->value("OutputFileSetAutoFlushZero") != "False") { + ATH_MSG_WARNING("OutputFileSetAutoFlushZero is deprecated in favour of more custom memory options"); + } + // Configurable TTree options (ANALYSISTO-463) + if (settings->value("OutputFileNEventAutoFlush") != "") { + m_outputFileNEventAutoFlush = std::stoi(settings->value("OutputFileNEventAutoFlush")); + } + if (settings->value("OutputFileBasketSizePrimitive") != "") { + m_outputFileBasketSizePrimitive = std::stoi(settings->value("OutputFileBasketSizePrimitive")); + } + if (settings->value("OutputFileBasketSizeVector") != "") { + m_outputFileBasketSizeVector = std::stoi(settings->value("OutputFileBasketSizeVector")); + } // The systematics want much much more configuration options..... - this->systematics( settings->value("Systematics") ); + this->systematics(settings->value("Systematics")); // special: allow to dump the systematics-shifted b-tagging SFs in the systematics trees - if (settings->value( "DumpBtagSystsInSystTrees" ) == "True") - this->dumpBtagSystsInSystTrees(true); + if (settings->value("DumpBtagSystsInSystTrees") == "True") this->dumpBtagSystsInSystTrees(true); + + // special: store per-jet btag SFs + if (settings->value("StorePerJetBtagSFs") == "True") this->storePerJetBtagSFs(true); // Electron configuration - this->egammaSystematicModel( settings->value("EgammaSystematicModel") ); - this->electronID( settings->value("ElectronID") ); - this->electronIDLoose( settings->value("ElectronIDLoose") ); - this->electronIsolation( settings->value("ElectronIsolation") ); - this->electronIsolationLoose( settings->value("ElectronIsolationLoose") ); - this->electronPtcut( std::stof(settings->value("ElectronPt")) ); - if( settings->value("ElectronIsoSFs") == "False" ) - this->m_electronIsoSFs = false; + this->egammaSystematicModel(settings->value("EgammaSystematicModel")); + this->electronEfficiencySystematicModel(settings->value("ElectronEfficiencySystematicModel")); + this->electronEfficiencySystematicModelEtaBinning(settings->value("ElectronEfficiencySystematicModelEtaBinning")); + this->electronEfficiencySystematicModelEtBinning(settings->value("ElectronEfficiencySystematicModelEtBinning")); + this->electronID(settings->value("ElectronID")); + this->electronIDLoose(settings->value("ElectronIDLoose")); + { + std::string const& cut_wp = settings->value("ElectronIsolation"); + std::string const& sf_wp = settings->value("ElectronIsolationSF"); + this->electronIsolation(cut_wp); + this->electronIsolationSF(sf_wp == " " ? cut_wp : sf_wp); + } + { + std::string const& cut_wp = settings->value("ElectronIsolationLoose"); + std::string const& sf_wp = settings->value("ElectronIsolationSFLoose"); + this->electronIsolationLoose(cut_wp); + this->electronIsolationSFLoose(sf_wp == " " ? cut_wp : sf_wp); + } + this->useElectronChargeIDSelection(settings->value("UseElectronChargeIDSelection")); + this->useEgammaLeakageCorrection(settings->value("UseEgammaLeakageCorrection")); + this->electronPtcut(std::stof(settings->value("ElectronPt"))); + this->enablePromptLeptonImprovedVetoStudies(settings->value("EnablePromptLeptonImprovedVetoStudies")); + + m_electronIDDecoration = "AnalysisTop_" + m_electronID; m_electronIDLooseDecoration = "AnalysisTop_" + m_electronIDLoose; - // Photon configuration - this->photonPtcut( std::stof(settings->value("PhotonPt")) ); - this->photonEtacut( std::stof(settings->value("PhotonEta")) ); - this->photonIdentification( settings->value("PhotonID") ); - this->photonIdentificationLoose( settings->value("PhotonIDLoose") ); - this->photonIsolation( settings->value("PhotonIsolation") ); - this->photonIsolationLoose( settings->value("PhotonIsolationLoose") ); - if( settings->value("PhotonUseRadiativeZ") == "True" ) - this->m_photon_configuration.useRadiativeZ = true; + //Fwd electron configuration + this->fwdElectronID(settings->value("FwdElectronID")); + this->fwdElectronIDLoose(settings->value("FwdElectronIDLoose")); + double fwdElPtCut = 99999999.; + try{ + fwdElPtCut = std::stof(settings->value("FwdElectronPt")); + } + catch (...) { + throw std::invalid_argument { + "TopConfig: cannot convert Option FwdElectronPt into float" + }; + } + this->fwdElectronPtcut(fwdElPtCut); + double fwdElMinEtaCut = 2.5; + try{ + fwdElMinEtaCut = std::stof(settings->value("FwdElectronMinEta")); + } + catch (...) { + throw std::invalid_argument { + "TopConfig: cannot convert Option FwdElectronMinEta into float" + }; + } + this->fwdElectronMinEtacut(fwdElMinEtaCut); + double fwdElMaxEtaCut = 2.5; + try{ + fwdElMaxEtaCut = std::stof(settings->value("FwdElectronMaxEta")); + } + catch (...) { + throw std::invalid_argument { + "TopConfig: cannot convert Option FwdElectronMaxEta into float" + }; + } + this->fwdElectronMaxEtacut(fwdElMaxEtaCut); - // Muon configuration - this->muonPtcut( std::stof(settings->value("MuonPt")) ); - this->muonEtacut( std::stof(settings->value("MuonEta")) ); - this->muonQuality( settings->value("MuonQuality") ); - this->muonQualityLoose( settings->value("MuonQualityLoose") ); - this->muonIsolation( settings->value("MuonIsolation") ); - this->muonIsolationLoose( settings->value("MuonIsolationLoose") ); + int fwdElectronBCIDCleaningMinRun = 0; + int fwdElectronBCIDCleaningMaxRun = 0; + std::vector<std::string> fwd_bcid_tokens; + tokenize(settings->value("FwdElectronBCIDCleaningRunRange"), fwd_bcid_tokens, ":"); + if (fwd_bcid_tokens.size() != 2) { + throw std::invalid_argument( + "TopConfig: Option FwdElectronBCIDCleaningRunRange requires values in the form of \'XXX:YYY\'. The number of values needs to be exactly 2."); + } + try{ + fwdElectronBCIDCleaningMinRun = std::stoi(fwd_bcid_tokens[0]); + fwdElectronBCIDCleaningMaxRun = std::stoi(fwd_bcid_tokens[1]); + } + catch (...) { + throw std::invalid_argument( + "TopConfig: Cannot convert the strings into integers for the run numbers in Option FwdElectronBCIDCleaningRunRange"); + } - if (settings->value("UseAntiMuons") == "True") - this->m_useAntiMuons = true; + this->fwdElectronBCIDCleaningMinRun(fwdElectronBCIDCleaningMinRun); + this->fwdElectronBCIDCleaningMaxRun(fwdElectronBCIDCleaningMaxRun); + + // Photon configuration + this->photonPtcut(std::stof(settings->value("PhotonPt"))); + this->photonEtacut(std::stof(settings->value("PhotonEta"))); + this->photonIdentification(settings->value("PhotonID")); + this->photonIdentificationLoose(settings->value("PhotonIDLoose")); + this->photonIsolation(settings->value("PhotonIsolation")); + this->photonIsolationLoose(settings->value("PhotonIsolationLoose")); + // Muon configuration + this->muonPtcut(std::stof(settings->value("MuonPt"))); + this->muonEtacut(std::stof(settings->value("MuonEta"))); + this->muonQuality(settings->value("MuonQuality")); + this->muonQualityLoose(settings->value("MuonQualityLoose")); + { + std::string const& cut_wp = settings->value("MuonIsolation"); + std::string const& sf_wp = settings->value("MuonIsolationSF"); + this->muonIsolation(cut_wp); + this->muonIsolationSF(sf_wp == " " ? cut_wp : sf_wp); + } + bool muonUse2stationHighPt = true; + settings->retrieve("MuonUse2stationHighPt", muonUse2stationHighPt); + if (settings->value("MuonQuality") != "HighPt") muonUse2stationHighPt = false; + this->muonUse2stationMuonsHighPt(muonUse2stationHighPt); + bool muonUseMVALowPt = false; + settings->retrieve("MuonUseMVALowPt", muonUseMVALowPt); + if (settings->value("MuonQuality") != "LowPt" && muonUseMVALowPt) { + ATH_MSG_WARNING("Could not set MuonUseMVALowPt True without using the LowPt muon WP. MuonUseMVALowPt is now setted to the default value (False)"); + muonUseMVALowPt = false; + } + this->muonUseMVALowPt(muonUseMVALowPt); + bool muonUse2stationHighPtLoose = true; + settings->retrieve("MuonUse2stationHighPtLoose", muonUse2stationHighPtLoose); + if (settings->value("MuonQualityLoose") != "HighPt") muonUse2stationHighPtLoose = false; + this->muonUse2stationMuonsHighPtLoose(muonUse2stationHighPtLoose); + bool muonUseMVALowPtLoose = false; + settings->retrieve("MuonUseMVALowPtLoose", muonUseMVALowPtLoose); + if (settings->value("MuonQualityLoose") != "LowPt" && muonUseMVALowPtLoose) { + ATH_MSG_WARNING("Could not set MuonUseMVALowPtLoose True without using the LowPt muon WP. MuonUseMVALowPtLoose is now setted to the default value (False)"); + muonUseMVALowPtLoose = false; + } + this->muonUseMVALowPtLoose(muonUseMVALowPtLoose); + { + std::string const& cut_wp = settings->value("MuonIsolationLoose"); + std::string const& sf_wp = settings->value("MuonIsolationSFLoose"); + this->muonIsolationLoose(cut_wp); + this->muonIsolationSFLoose(sf_wp == " " ? cut_wp : sf_wp); + } + bool muonDoSmearing2stationHighPt = false; + settings->retrieve("MuonDoSmearing2stationHighPt", muonDoSmearing2stationHighPt); + if (settings->value("MuonQuality") != "HighPt" ) muonDoSmearing2stationHighPt = false; + else if ( !muonUse2stationHighPt && muonDoSmearing2stationHighPt ) { + ATH_MSG_WARNING("Could not set MuonDoSmearing2stationHighPt True without MuonUse2stationHighPt. MuonDoSmearing2stationHighPt is now setted to False"); + muonDoSmearing2stationHighPt = false; + } + this->muonMuonDoSmearing2stationHighPt(muonDoSmearing2stationHighPt); + bool muonDoExtraSmearingHighPt = false; + settings->retrieve("MuonDoExtraSmearingHighPt", muonDoExtraSmearingHighPt); + if ( settings->value("MuonQuality") != "HighPt" && muonDoExtraSmearingHighPt ) { + ATH_MSG_WARNING("Could not set MuonDoExtraSmearingHighPt True without using the HighPt muon WP. MuonDoExtraSmearingHighPt is now setted to the default value (False)"); + muonDoExtraSmearingHighPt = false; + } + this->muonMuonDoExtraSmearingHighPt( muonDoExtraSmearingHighPt ); + + if (settings->value("UseAntiMuons") == "True") this->m_useAntiMuons = true; + + // Soft Muon configuration + this->softmuonPtcut(readFloatOption(settings, "SoftMuonPt")); + this->softmuonEtacut(readFloatOption(settings, "SoftMuonEta")); + this->softmuonQuality(settings->value("SoftMuonQuality")); + bool softmuonUseMVALowPtSoftMuon = false; + settings->retrieve("SoftMuonUseMVALowPt", softmuonUseMVALowPtSoftMuon); + if (settings->value("SoftMuonQuality") != "LowPt" && softmuonUseMVALowPtSoftMuon) { + ATH_MSG_WARNING("Could not set SoftMuonUseMVALowPt True without using the LowPt softmuon WP. SoftMuonUseMVALowPt is now setted to the default value (False)"); + softmuonUseMVALowPtSoftMuon = false; + } + this->softmuonUseMVALowPt(softmuonUseMVALowPtSoftMuon); + this->softmuonDRJetcut(readFloatOption(settings, "SoftMuonDRJet")); + this->softmuonDRJetcutUseRapidity(settings->retrieve("SoftMuonDRJetUseRapidity")); + this->softmuonAdditionalTruthInfo(settings->retrieve("SoftMuonAdditionalTruthInfo")); + this->softmuonAdditionalTruthInfoCheckPartonOrigin(settings->retrieve("SoftMuonAdditionalTruthInfoCheckPartonOrigin")); + this->softmuonAdditionalTruthInfoDoVerbose(settings->retrieve("SoftMuonAdditionalTruthInfoDoVerbose") ); //tau configuration this->tauPtcut(std::stof(settings->value("TauPt"))); + this->tauEtaRegions(settings->value("TauEtaRegions")); this->tauJetIDWP(settings->value("TauJetIDWP")); this->tauJetIDWPLoose(settings->value("TauJetIDWPLoose")); this->tauEleBDTWP(settings->value("TauEleBDTWP")); this->tauEleBDTWPLoose(settings->value("TauEleBDTWPLoose")); this->tauEleOLR((settings->value("TauEleOLR") == "True")); this->tauEleOLRLoose((settings->value("TauEleOLRLoose") == "True")); + this->tauSFDoRNNID((settings->value("TauSFDoRNNID") == "True")); + this->tauSFDoBDTID((settings->value("TauSFDoBDTID") == "True")); this->tauJetConfigFile(settings->value("TauJetConfigFile")); this->tauJetConfigFileLoose(settings->value("TauJetConfigFileLoose")); - this->applyTauMVATES((settings->value("ApplyTauMVATES") == "True")); + if (settings->value("ApplyTauMVATES") != "True") throw std::runtime_error { + "TopConfig: ApplyTauMVATES must be True" + }; // Jet configuration - this->jetPtcut( std::stof(settings->value("JetPt")) ); - this->jetEtacut( std::stof(settings->value("JetEta")) ); - this->fwdJetAndMET( settings->value("FwdJetAndMET") ); - this->jetUncertainties_BunchSpacing( settings->value("JetUncertainties_BunchSpacing") ); - this->jetUncertainties_NPModel( settings->value("JetUncertainties_NPModel") ); - this->jetJERSmearingModel( settings->value("JetJERSmearingModel") ); - this->jetCalibSequence( settings->value("JetCalibSequence") ); - this->doJVTinMET( (settings->value("JVTinMETCalculation") == "True" ? true : false) ); - this->m_largeRSmallRCorrelations = settings->value("LargeRSmallRCorrelations") == "True" ? true : false; - - this->largeRJetPtcut( std::stof(settings->value("LargeRJetPt")) ); - this->largeRJetEtacut( std::stof(settings->value("LargeRJetEta")) ); - this->largeRJESUncertaintyConfig( settings->value("LargeRJESUncertaintyConfig") ); - this->largeRJESJMSConfig( settings->value("LargeRJESJMSConfig") ); - - this->trackJetPtcut( std::stof(settings->value("TrackJetPt")) ); - this->trackJetEtacut( std::stof(settings->value("TrackJetEta")) ); + this->jetPtcut(std::stof(settings->value("JetPt"))); + this->jetEtacut(std::stof(settings->value("JetEta"))); + this->jetPtGhostTracks(std::stof(settings->value("JetPtGhostTracks")),std::stof(settings->value("JetPt"))); + if ( m_jetPtcut <= std::stof(settings->value("JetPtGhostTracks"))+5000){ + ATH_MSG_WARNING("jetPtGhostTracks set to " << m_jetPtGhostTracks <<" to ensure that all the selected jets have the ghost tracks associated"); + } + this->jetEtaGhostTracks(std::stof(settings->value("JetEtaGhostTracks"))); + this->jetUncertainties_NPModel(settings->value("JetUncertainties_NPModel")); + this->jetUncertainties_QGFracFile(settings->value("JetUncertainties_QGFracFile")); + this->jetUncertainties_QGHistPatterns(settings->value("JetUncertainties_QGHistPatterns")); + this->jetJERSmearingModel(settings->value("JetJERSmearingModel")); + this->jetCalibSequence(settings->value("JetCalibSequence")); + this->doJVTinMET(settings->retrieve("JVTinMETCalculation")); + this->saveFailJVTJets(settings->retrieve("SaveFailJVTJets")); + this->setJVTWP(settings->value("JVTWP")); + this->doForwardJVTinMET(settings->retrieve("ForwardJVTinMETCalculation")); + this->saveFailForwardJVTJets(settings->retrieve("SaveFailForwardJVTJets")); + this->setfJVTWP(settings->value("ForwardJVTWP")); + if (settings->value("ForwardJVTWP") == "Medium" && settings->retrieve("ForwardJVTinMETCalculation")){ + ATH_MSG_WARNING("TopConfig::setConfigSettings: fJVT WP set to Medium and fJVT in MET requested, MET working point will be changed to Tenacious to maintain compatibility with fJVT!!!"); + } + + + this->largeRJetPtcut(std::stof(settings->value("LargeRJetPt"))); + this->largeRJetEtacut(std::stof(settings->value("LargeRJetEta"))); + + + // now get all substructure variables from the config file. + std::string strSubstructure = settings->value("LargeRJetSubstructureVariables"); + // Making vector of strings with "," used as separator + std::vector<std::string> helpvecStr; + tokenize(strSubstructure, helpvecStr, ","); + + std::vector<std::string> vecSubstructure; + // Removing empty spaces + for (const std::string& x : helpvecStr) { + std::istringstream istrSubstructure(x); + std::copy(std::istream_iterator<std::string>(istrSubstructure), + std::istream_iterator<std::string>(), std::back_inserter(vecSubstructure)); + } + // Making map + for (const std::string& key: vecSubstructure) { + std::vector<std::string> pairs; + tokenize(key,pairs,":"); + if(pairs.size() == 1) m_largeRJetSubstructureVariables[pairs[0]]=pairs[0]; + else if(pairs.size() == 2) m_largeRJetSubstructureVariables[pairs[0]]=pairs[1]; + else throw std::runtime_error { + "TopConfig: Options in LargeRJetSubstructureVariables should be of the form \'x:y\' or \'y\'." + }; + } + + this->largeRJetUncertainties_NPModel(settings->value("LargeRJetUncertainties_NPModel")); + this->largeRJetUncertaintiesConfigDir(settings->value("AdvancedUsage_LargeRJetUncertaintiesConfigDir")); + this->largeRJESJMSConfig(settings->value("LargeRJESJMSConfig")); + + this->trackJetPtcut(std::stof(settings->value("TrackJetPt"))); + this->trackJetEtacut(std::stof(settings->value("TrackJetEta"))); + + //Ghost track associated to jets quality + this->ghostTrackspT(std::stof(settings->value("GhostTrackspT"))); + this->ghostTracksVertexAssociation(settings->value("GhostTracksVertexAssociation")); + this->ghostTracksQuality(settings->value("GhostTracksQuality")); + + this->trackPtcut(std::stof(settings->value("TrackPt"))); + this->trackEtacut(std::stof(settings->value("TrackEta"))); + this->trackQuality(settings->value("TrackQuality")); // Jet configuration reclustered jets - this->RCJetPtcut(std::stof(settings->value("RCJetPt")) ); - this->RCJetEtacut(std::stof(settings->value("RCJetEta")) ); - this->RCJetTrimcut(std::stof(settings->value("RCJetTrim")) ); - this->RCJetRadius(std::stof(settings->value("RCJetRadius")) ); - if (settings->value("UseRCJets") == "True" || settings->value("UseRCJets") == "true") - this->m_useRCJets = true; - - this->VarRCJetPtcut(std::stof(settings->value("VarRCJetPt")) ); - this->VarRCJetEtacut(std::stof(settings->value("VarRCJetEta")) ); - this->VarRCJetTrimcut(std::stof(settings->value("VarRCJetTrim")) ); - this->VarRCJetMaxRadius(std::stof(settings->value("VarRCJetMaxRadius")) ); + this->RCJetPtcut(std::stof(settings->value("RCJetPt"))); + this->RCJetEtacut(std::stof(settings->value("RCJetEta"))); + this->RCInputJetPtMin(std::stof(settings->value("RCInputJetPtMin"))); + this->RCInputJetEtaMax(std::stof(settings->value("RCInputJetEtaMax"))); + this->RCJetTrimcut(std::stof(settings->value("RCJetTrim"))); + this->RCJetRadius(std::stof(settings->value("RCJetRadius"))); + if (settings->value("UseRCJets") == "True" || settings->value("UseRCJets") == "true") this->m_useRCJets = true; + if (settings->value("UseRCJetSubstructure") == "True" || + settings->value("UseRCJetSubstructure") == "true") this->m_useRCJetSubstructure = true; + else this->m_useRCJetSubstructure = false; + + if (settings->value("UseRCJetAdditionalSubstructure") == "True" || + settings->value("UseRCJetAdditionalSubstructure") == "true") this->m_useRCJetAdditionalSubstructure = true; + else this->m_useRCJetAdditionalSubstructure = false; + + this->VarRCJetPtcut(std::stof(settings->value("VarRCJetPt"))); + this->VarRCJetEtacut(std::stof(settings->value("VarRCJetEta"))); + this->VarRCJetTrimcut(std::stof(settings->value("VarRCJetTrim"))); + this->VarRCJetMaxRadius(std::stof(settings->value("VarRCJetMaxRadius"))); this->VarRCJetRho(settings->value("VarRCJetRho")); this->VarRCJetMassScale(settings->value("VarRCJetMassScale")); - if (settings->value("UseVarRCJets") == "True" || settings->value("UseVarRCJets") == "true") - this->m_useVarRCJets = true; + if (settings->value("UseVarRCJets") == "True" || + settings->value("UseVarRCJets") == "true") this->m_useVarRCJets = true; + if (settings->value("UseVarRCJetSubstructure") == "True" || + settings->value("UseVarRCJetSubstructure") == "true") this->m_useVarRCJetSubstructure = true; + else this->m_useVarRCJetSubstructure = false; + if (settings->value("UseVarRCJetAdditionalSubstructure") == "True" || + settings->value("UseVarRCJetAdditionalSubstructure") == + "true") this->m_useVarRCJetAdditionalSubstructure = true; + else this->m_useVarRCJetAdditionalSubstructure = false; + + if (settings->value("StoreJetTruthLabels") == "False") { + this->jetStoreTruthLabels(false); + } else if (settings->value("StoreJetTruthLabels") == "True") { + this->jetStoreTruthLabels(true); + } else { + ATH_MSG_WARNING("TopConfig::setConfigSettings: Unrecognized option for \"StoreJetTruthLabels\", assuming True"); + this->jetStoreTruthLabels(true); + } + + // MET Configuration + this->METUncertaintiesConfigDir(settings->value("AdvancedUsage_METUncertaintiesConfigDir")); // for top mass analysis, per default set to 1.0! - m_JSF = std::stof(settings->value("JSF")); + m_JSF = std::stof(settings->value("JSF")); m_bJSF = std::stof(settings->value("bJSF")); // If parameter exists remove electron crack veto - if (settings->value("ElectronVetoLArCrack") == "False") - this->removeElectronVetoLArCrack(); + if (settings->value("ElectronVetoLArCrack") == "False") this->removeElectronVetoLArCrack(); // By default the top group does overlap removal on the tight lepton definitions // If you use this you are going off piste and need to report // your findings to the top reconstruction meeting - if (settings->value("OverlapRemovalLeptonDef") == "Loose") - this->setOverlapRemovalOnLooseLeptonDef(); + if (settings->value("OverlapRemovalLeptonDef") == "Loose") this->setOverlapRemovalOnLooseLeptonDef(); m_overlap_removal_procedure = settings->value("OverlapRemovalProcedure"); // do overlap removal also with large-R jets // (using whatever procedure is used in the official tools) if (settings->value("LargeJetOverlapRemoval") == "True") { - this->setLargeJetOverlapRemoval();// only usefull in case of MC - } - - // Only dumps the *_Loose trees - also on MC - // Usefull if you want your tight selection to be a subset of loose - if (settings->value("DoLooseTreeOnly") == "True") { - this->setLooseTreeOnly(); - if (this->isMC())// in case of MC *_Loose trees have to be activated - this->FakesControlRegionDetermination_setDoLooseEventsOnMC_notForRegularUsers(); + this->setLargeJetOverlapRemoval();// only usefull in case of MC } // In the *_Loose trees, lepton SFs are calculated considering // tight ID and isolation instead of loose // Only tight leptons are considered in the event SF calculation - if (settings->value("ApplyTightSFsInLooseTree") == "True") { - if (this->isMC()) - this->setApplyTightSFsInLooseTree();// only usefull in case of MC - } + // only usefull in case of MC + if (settings->value("ApplyTightSFsInLooseTree") == "True" && this->isMC()) this->setApplyTightSFsInLooseTree(); // Apply Electron In Jet Subtraction - boosted analysis - if (settings->value("ApplyElectronInJetSubtraction") == "True") - this->setApplyElectronInJetSubtraction(); + if (settings->value("ApplyElectronInJetSubtraction") == "True") this->setApplyElectronInJetSubtraction(); // Set Number of events to run on (for testing) - this->numberOfEventsToRun( std::stoi(settings->value("NEvents")) ); + this->numberOfEventsToRun(std::stoi(settings->value("NEvents"))); // Set Number of the first Event to run skip (for testing) - this->numberOfEventsToSkip( std::stoi(settings->value("FirstEvent")) ); + this->numberOfEventsToSkip(std::stoi(settings->value("FirstEvent"))); // [[[----------------------------------------------- //; Particle Level / Truth Configuration - this->truth_electron_PtCut( std::stof( settings->value( "TruthElectronPt" ) ) ); - this->truth_electron_EtaCut( std::stof( settings->value( "TruthElectronEta" ) ) ); + this->truth_electron_PtCut(std::stof(settings->value("TruthElectronPt"))); + this->truth_electron_EtaCut(std::stof(settings->value("TruthElectronEta"))); - this->truth_muon_PtCut( std::stof( settings->value( "TruthMuonPt" ) ) ); - this->truth_muon_EtaCut( std::stof( settings->value( "TruthMuonEta" ) ) ); + this->truth_muon_PtCut(std::stof(settings->value("TruthMuonPt"))); + this->truth_muon_EtaCut(std::stof(settings->value("TruthMuonEta"))); + + float truth_softmu_ptcut=4000.; + try{ + truth_softmu_ptcut=std::stof(settings->value("TruthSoftMuonPt")); + } + catch (...) { + throw std::runtime_error { + "TopConfig: can't convert provided TruthSoftMuonPt into float" + }; + } + + float truth_softmu_etacut=2.5; + try{ + truth_softmu_etacut=std::stof(settings->value("TruthSoftMuonEta")); + } + catch (...) { + throw std::runtime_error { + "TopConfig: can't convert provided TruthSoftMuonEta into float" + }; + } + + this->truth_softmuon_PtCut(truth_softmu_ptcut); + this->truth_softmuon_EtaCut(truth_softmu_etacut); - this->truth_photon_PtCut( std::stof( settings->value( "TruthPhotonPt" ) ) ); - this->truth_photon_EtaCut( std::stof( settings->value( "TruthPhotonEta" ) ) ); + this->truth_photon_PtCut(std::stof(settings->value("TruthPhotonPt"))); + this->truth_photon_EtaCut(std::stof(settings->value("TruthPhotonEta"))); // The TruthPhoton Origin and Isolation parameters are validated inside the // TopParticleLevel Loader Class. - this->truth_photon_Origin( settings->value( "TruthPhotonOrigin" ) ); - this->truth_photon_Isolation( settings->value( "TruthPhotonIsolation" ) ); + this->truth_photon_Origin(settings->value("TruthPhotonOrigin")); + this->truth_photon_Isolation(settings->value("TruthPhotonIsolation")); + + this->truth_jet_PtCut(std::stof(settings->value("TruthJetPt"))); + this->truth_jet_EtaCut(std::stof(settings->value("TruthJetEta"))); - this->truth_jet_PtCut( std::stof( settings->value( "TruthJetPt" ) ) ); - this->truth_jet_EtaCut( std::stof( settings->value( "TruthJetEta" ) ) ); + this->truth_jet_largeR_PtCut(std::stof(settings->value("TruthLargeRJetPt"))); + this->truth_jet_largeR_EtaCut(std::stof(settings->value("TruthLargeRJetEta"))); - this->truth_jet_largeR_PtCut( std::stof( settings->value( "TruthLargeRJetPt" ) ) ); - this->truth_jet_largeR_EtaCut( std::stof( settings->value( "TruthLargeRJetEta" ) ) ); + this->truth_tau_PtCut(std::stof(settings->value("TruthTauPt"))); + this->truth_tau_EtaCut(std::stof(settings->value("TruthTauEta"))); // -----------------------------------------------]]] // Upgrade studies - if(settings->value("HLLHC")=="True") this->HLLHC( true ); + if (settings->value("HLLHC") == "True") { + this->HLLHC(true); + if (settings->value("TDPPath").compare("dev/AnalysisTop/TopDataPreparation/XSection-MC15-13TeV.data") == 0) { + ATH_MSG_WARNING("TopConfig::setConfigSettings HLLHC is set to True, but the TDPPath is set to default " << + settings->value("TDPPath") << ". Changing to dev/AnalysisTop/TopDataPreparation/XSection-MC15-14TeV.data"); + this->setTDPPath("dev/AnalysisTop/TopDataPreparation/XSection-MC15-14TeV.data"); + } + } + if (settings->value("HLLHCFakes") == "True") this->HLLHCFakes(true); // LHAPDF Reweighting configuration - std::istringstream lha_pdf_ss(settings->value( "LHAPDFSets" )); - std::copy( std::istream_iterator<std::string>(lha_pdf_ss), - std::istream_iterator<std::string>(), - std::back_inserter(m_lhapdf_options.pdf_set_names) ); + std::istringstream lha_pdf_ss(settings->value("LHAPDFSets")); + std::copy(std::istream_iterator<std::string>(lha_pdf_ss), + std::istream_iterator<std::string>(), + std::back_inserter(m_lhapdf_options.pdf_set_names)); // if provided, it will be used to recompute XF1,XF2 (if any is zero) const std::string LHAPDFBase = settings->value("LHAPDFBaseSet"); - if( LHAPDFBase.find_first_not_of(' ') != std::string::npos ) { + if (LHAPDFBase.find_first_not_of(' ') != std::string::npos) { // should only set one base PDF set - if( LHAPDFBase.find(' ') != std::string::npos ) - std::cout << "LHAPDFBaseSet: " << LHAPDFBase - << " <<<<< only one PDF set allowed for recomputing XF1,XF2 !!!" << std::endl; + if (LHAPDFBase.find(' ') != std::string::npos) + ATH_MSG_WARNING("LHAPDFBaseSet: " << LHAPDFBase << " -- only one PDF set allowed for recomputing XF1,XF2 !!!"); m_lhapdf_options.baseLHAPDF = LHAPDFBase; } // if not already present, add to the list of PDF sets - if( ! m_lhapdf_options.baseLHAPDF.empty() && - !(std::find(m_lhapdf_options.pdf_set_names.begin(), - m_lhapdf_options.pdf_set_names.end(), - m_lhapdf_options.baseLHAPDF) != m_lhapdf_options.pdf_set_names.end()) ) - m_lhapdf_options.pdf_set_names.push_back(m_lhapdf_options.baseLHAPDF); + if (!m_lhapdf_options.baseLHAPDF.empty() && + !(std::find(m_lhapdf_options.pdf_set_names.begin(), + m_lhapdf_options.pdf_set_names.end(), + m_lhapdf_options.baseLHAPDF) != + m_lhapdf_options.pdf_set_names.end())) m_lhapdf_options.pdf_set_names.push_back(m_lhapdf_options.baseLHAPDF); - if( m_lhapdf_options.pdf_set_names.size() && this->isMC() ) - m_lhapdf_options.doLHAPDF = true; + if (m_lhapdf_options.pdf_set_names.size() && this->isMC()) m_lhapdf_options.doLHAPDF = true; - if( m_lhapdf_options.pdf_set_names.size() && this->isMC() && settings->value("LHAPDFEventWeights") == "True" ) { + if (m_lhapdf_options.pdf_set_names.size() && this->isMC() && settings->value("LHAPDFEventWeights") == "True") { m_lhapdf_options.save_per_event = true; - } - else if( m_lhapdf_options.pdf_set_names.size() && this->isMC() && settings->value("LHAPDFEventWeights") == "Nominal" ) { + } else if (m_lhapdf_options.pdf_set_names.size() && this->isMC() && + settings->value("LHAPDFEventWeights") == "Nominal") { m_lhapdf_options.save_per_event = true; m_lhapdf_options.doLHAPDFInNominalTrees = true; } + // now get all Boosted jet taggers from the config file. + std::string str_boostedJetTagger = settings->value("BoostedJetTagging"); + std::vector<std::string> helpvec_str; + tokenize(str_boostedJetTagger, helpvec_str, ","); - // now get all Btagging WP from the config file, and store them properly in a map. - // Need function to compare the cut value with the WP and vice versa + std::vector<std::string> vec_boostedJetTaggers; - std::istringstream str_btagging_WP(settings->value( "BTaggingWP" )); + for (const std::string& x : helpvec_str) { + std::istringstream istr_boostedJetTaggers(x); + std::copy(std::istream_iterator<std::string>(istr_boostedJetTaggers), + std::istream_iterator<std::string>(), std::back_inserter(vec_boostedJetTaggers)); + } - std::vector<std::string> all_btagging_WP; - std::copy( std::istream_iterator<std::string>(str_btagging_WP), - std::istream_iterator<std::string>(), - std::back_inserter(all_btagging_WP) ); + for (const std::string& tagger : vec_boostedJetTaggers) { + std::vector<std::string> helpvec; + tokenize(tagger, helpvec, ":"); + if (helpvec.size() != 2) throw std::runtime_error { + "TopConfig: Options in BoostedJetTagging should be of the form \'x:y\' where x is tagging type and y is shortened tagger name." + }; + m_chosen_boostedJetTaggers.push_back(std::make_pair(helpvec[0], helpvec[1])); + } - // loop through all btagging WPs requested - for (auto tag : all_btagging_WP) { - std::cout << "TopConfig: ==================================================> " << tag << std::endl; - std::string formatedWP = FormatedWP(tag); - // take care that no WP is taken twice - if ( std::find(m_chosen_btaggingWP.begin(), m_chosen_btaggingWP.end(), formatedWP) == m_chosen_btaggingWP.end() ) { - m_chosen_btaggingWP.push_back(formatedWP); - std::cout << "chosen btagging WP ===============================================> " << m_chosen_btaggingWP.back() << std::endl; + m_btagging_cdi_path = settings->value("BTagCDIPath"); + + // now get all Btagging WP from the config file, and store them properly in a map. + // Need function to compare the cut value with the WP and vice versa + parse_bTagWPs(settings->value("BTaggingWP"), m_chosen_btaggingWP, m_sgKeyJets + ", " + m_sgKeyTrackJets); + parse_bTagWPs(settings->value("BTaggingCaloJetWP"), m_chosen_btaggingWP_caloJet, m_sgKeyJets); + parse_bTagWPs(settings->value("BTaggingTrackJetWP"), m_chosen_btaggingWP_trkJet, m_sgKeyTrackJets); + + // check whether user is using the deprecated BTaggingWP option + if (m_chosen_btaggingWP.size() > 0) { + ATH_MSG_WARNING("You specified b-tagging WPs via BTaggingWP which is obsolete. Please switch to options BTaggingCaloJetWP for specifying EMTopo/EMPFlow b-tagging, and BTaggingTrackJetWP for track-jet b-tagging."); + if (m_chosen_btaggingWP_caloJet.size() > 0 || m_chosen_btaggingWP_trkJet.size() > 0) { + ATH_MSG_ERROR("You specified b-tagging WPs both via BTaggingWP as well as BTaggingCaloJetWP or BTaggingTrackJetWP. The BTaggingWP option is deprecated and conflicts with the other two options!"); + throw std::runtime_error("TopConfig: Failed to determine what b-tagging WPs to configure."); } else { - std::cout << "WP " << formatedWP << " aldready choosen" << std::endl; + // if deprecated option used, assume both calo and track jet WPs are the same + m_chosen_btaggingWP_caloJet = m_chosen_btaggingWP; + m_chosen_btaggingWP_trkJet = m_chosen_btaggingWP; } } m_btagging_calibration_B = settings->value("BTaggingCalibrationB"); m_btagging_calibration_C = settings->value("BTaggingCalibrationC"); m_btagging_calibration_Light = settings->value("BTaggingCalibrationLight"); - m_bTagSystsExcludedFromEV = settings->value( "BTaggingSystExcludedFromEV" ); + m_bTagSystsExcludedFromEV = settings->value("BTaggingSystExcludedFromEV"); + + // Set translatio ndictionary for MCMC maps + if (settings->value("RedefineMCMCMap") != " ") { + std::vector<std::string> tmp; + tokenize(settings->value("RedefineMCMCMap"), tmp, ","); + for (const std::string& dictionaries : tmp) { + std::vector<std::string> dictionary; + tokenize(dictionaries, dictionary, ":"); + if (dictionary.size() != 2) { + throw std::invalid_argument{"Wrong input argument for RedefineMCMCMap. Expected format is: \"shower1:shower2,shower3:shower4\""}; + } + + m_showerMCMCtranslator.insert({dictionary.at(0), dictionary.at(1)}); + } + } /************************************************************ * @@ -809,62 +1624,214 @@ namespace top{ * ***********************************************************/ - std::istringstream pileup_config_ss(settings->value( "PRWConfigFiles" )); - std::copy( std::istream_iterator<std::string>(pileup_config_ss), - std::istream_iterator<std::string>(), - std::back_inserter(m_pileup_reweighting.config_files) ); + std::istringstream pileup_config_ss(settings->value("PRWConfigFiles")); + std::copy(std::istream_iterator<std::string>(pileup_config_ss), + std::istream_iterator<std::string>(), + std::back_inserter(m_pileup_reweighting.config_files)); + + std::istringstream pileup_lumi_ss(settings->value("PRWLumiCalcFiles")); + std::copy(std::istream_iterator<std::string>(pileup_lumi_ss), + std::istream_iterator<std::string>(), + std::back_inserter(m_pileup_reweighting.lumi_calc_files)); + + std::istringstream pileup_config_FS_ss(settings->value("PRWConfigFiles_FS")); + std::copy(std::istream_iterator<std::string>(pileup_config_FS_ss), + std::istream_iterator<std::string>(), + std::back_inserter(m_pileup_reweighting.config_files_FS)); + + std::istringstream pileup_config_AF_ss(settings->value("PRWConfigFiles_AF")); + std::copy(std::istream_iterator<std::string>(pileup_config_AF_ss), + std::istream_iterator<std::string>(), + std::back_inserter(m_pileup_reweighting.config_files_AF)); - std::istringstream pileup_lumi_ss(settings->value( "PRWLumiCalcFiles" )); - std::copy( std::istream_iterator<std::string>(pileup_lumi_ss), - std::istream_iterator<std::string>(), - std::back_inserter(m_pileup_reweighting.lumi_calc_files) ); + std::istringstream actual_mu_FS_ss(settings->value("PRWActualMu_FS")); + std::copy(std::istream_iterator<std::string>(actual_mu_FS_ss), + std::istream_iterator<std::string>(), + std::back_inserter(m_pileup_reweighting.actual_mu_FS)); + + std::istringstream actual_mu_AF_ss(settings->value("PRWActualMu_AF")); + std::copy(std::istream_iterator<std::string>(actual_mu_AF_ss), + std::istream_iterator<std::string>(), + std::back_inserter(m_pileup_reweighting.actual_mu_AF)); + + m_pileup_reweighting.unrepresented_data_tol = std::stof(settings->value("PRWUnrepresentedDataTolerance")); m_pileup_reweighting.mu_dependent = (settings->value("PRWMuDependent") == "True"); // now even if the user don't provide a PRWConfigFiles, PRW is done on MC, using the default calibration file - if ( m_pileup_reweighting.lumi_calc_files.size() > 0 ) { + if (m_pileup_reweighting.lumi_calc_files.size() > 0) { m_pileup_reweighting.apply = true; } - if ( m_pileup_reweighting.apply && m_grlFile.size() > 0 && settings->value("PRWUseGRLTool") == "True" ) - m_pileup_reweighting.use_grl_tool = true; + if (m_pileup_reweighting.apply && m_grlFile.size() > 0 && + settings->value("PRWUseGRLTool") == "True") m_pileup_reweighting.use_grl_tool = true; + + // if provided, using custom Data Scale-Factors for pile-up reweighting + // nominal:up:down + // also allowing to specify under this form: 1/1.2:1.0:1/1.4 + if (m_pileup_reweighting.apply && settings->value("PRWCustomScaleFactor") != " ") { + std::vector<std::string> SFs_tokens; + tokenize(settings->value("PRWCustomScaleFactor"), SFs_tokens, ":"); + if (SFs_tokens.size() != 3) throw std::runtime_error { + "TopConfig: Option PRWCustomScaleFactor should be of the form \'nominal:up:down\'" + }; + try { + std::vector<std::string> nomSF_tokens; + tokenize(SFs_tokens[0], nomSF_tokens, "/"); + if (nomSF_tokens.size() == 1) m_pileup_reweighting.custom_SF.push_back(std::stof(nomSF_tokens[0])); + else if (nomSF_tokens.size() == 2) m_pileup_reweighting.custom_SF.push_back(std::stof( + nomSF_tokens[0]) / + std::stof(nomSF_tokens[1])); + else throw std::runtime_error { + "TopConfig: issue in division" + }; + } catch (...) { + throw std::runtime_error { + "TopConfig: can't convert provided PRW nominal Data SF into float" + }; + } + try { + std::vector<std::string> upSF_tokens; + tokenize(SFs_tokens[1], upSF_tokens, "/"); + if (upSF_tokens.size() == 1) m_pileup_reweighting.custom_SF.push_back(std::stof(upSF_tokens[0])); + else if (upSF_tokens.size() == 2) m_pileup_reweighting.custom_SF.push_back(std::stof( + upSF_tokens[0]) / + std::stof(upSF_tokens[1])); + else throw std::runtime_error { + "TopConfig: issue in division" + }; + } catch (...) { + throw std::runtime_error { + "TopConfig: can't convert provided PRW up Data SF into float" + }; + } + try { + std::vector<std::string> downSF_tokens; + tokenize(SFs_tokens[2], downSF_tokens, "/"); + if (downSF_tokens.size() == 1) m_pileup_reweighting.custom_SF.push_back(std::stof(downSF_tokens[0])); + else if (downSF_tokens.size() == 2) m_pileup_reweighting.custom_SF.push_back(std::stof( + downSF_tokens[0]) / + std::stof(downSF_tokens[1])); + else throw std::runtime_error { + "TopConfig: issue in division" + }; + } catch (...) { + throw std::runtime_error { + "TopConfig: can't convert provided PRW down Data SF into float" + }; + } + ATH_MSG_INFO("Custom PRW scale-factors - nominal:" << SFs_tokens[0] << "=" << m_pileup_reweighting.custom_SF[0] << + " up:" << SFs_tokens[1] << "=" << m_pileup_reweighting.custom_SF[1] << " down:" << SFs_tokens[2] << "=" << + m_pileup_reweighting.custom_SF[2]); + } + + if (m_pileup_reweighting.apply && settings->value("PRWPeriodAssignments") != " ") { + std::vector<std::string> period_tokens; + tokenize(settings->value("PRWPeriodAssignments"), period_tokens, ":"); + if (period_tokens.size() % 3 != 0) { + throw std::invalid_argument( + "TopConfig: Option PRWPeriodAssignments requires values in the form of \'value:value:value\'. The number of values needs to be divisible by 3."); + } + try { + for (const std::string& per : period_tokens) { + m_pileup_reweighting.periodAssignments.emplace_back(std::stoi(per)); + } + } catch (...) { + throw std::invalid_argument( + "TopConfig: Cannot convert the strings into integers for the run numbers in Option PRWPeriodAssignments"); + } + } // TRUTH derivations do not contain pile-up weights - if(m_isTruthDxAOD) - m_pileup_reweighting.apply = false; + if (m_isTruthDxAOD) m_pileup_reweighting.apply = false; /************************************************************ - * - * Muon trigger SF configuration - * see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15#How_to_retrieve_the_SF - * for the various trigger strings allowed - * - ************************************************************/ + * + * Muon trigger SF configuration + * see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15#How_to_retrieve_the_SF + * for the various trigger strings allowed + * + ************************************************************/ + + m_muon_trigger_SF = settings->value("MuonTriggerSF"); - m_muon_trigger_SF = settings->value( "MuonTriggerSF" ); + if (settings->value("DemandPrimaryVertex") == "False") + m_demandPriVtx = false; ///-- KLFitter settings --/// - m_KLFitterTransferFunctionsPath = settings->value( "KLFitterTransferFunctionsPath" ); - m_KLFitterJetSelectionMode = settings->value( "KLFitterJetSelectionMode" ); - m_KLFitterBTaggingMethod = settings->value( "KLFitterBTaggingMethod" ); - m_KLFitterLH = settings->value( "KLFitterLH" ); - - if (settings->value( "KLFitterTopMassFixed" ) == "True") - m_KLFitterTopMassFixed = true; - if (settings->value( "KLFitterTopMassFixed" ) == "False") - m_KLFitterTopMassFixed = false; - if (settings->value( "KLFitterSaveAllPermutations" ) == "True") - m_KLFitterSaveAllPermutations = true; - if (settings->value( "KLFitterSaveAllPermutations" ) == "False") - m_KLFitterSaveAllPermutations = false; + m_KLFitterTransferFunctionsPath = settings->value("KLFitterTransferFunctionsPath"); + m_KLFitterOutput = settings->value("KLFitterOutput"); + m_KLFitterJetSelectionMode = settings->value("KLFitterJetSelectionMode"); + m_KLFitterBTaggingMethod = settings->value("KLFitterBTaggingMethod"); + m_KLFitterLH = settings->value("KLFitterLH"); + + if (settings->value("KLFitterTopMassFixed") == "True") m_KLFitterTopMassFixed = true; + if (settings->value("KLFitterTopMassFixed") == "False") m_KLFitterTopMassFixed = false; + if (settings->value("KLFitterSaveAllPermutations") == "True") m_KLFitterSaveAllPermutations = true; + if (settings->value("KLFitterSaveAllPermutations") == "False") m_KLFitterSaveAllPermutations = false; + if (settings->value("KLFitterFailOnLessThanXJets") == "True") m_KLFitterFailOnLessThanXJets = true; + if (settings->value("KLFitterFailOnLessThanXJets") == "False") m_KLFitterFailOnLessThanXJets = false; + + //--- Check for configuration on the global lepton triggers ---// + if (settings->value("UseGlobalLeptonTriggerSF") == "True") { + auto parseTriggerString = + [settings](std::unordered_map<std::string, std::vector<std::string> >& triggersByPeriod, + std::string const& key) { + /* parse a string of the form "2015@triggerfoo,triggerbar,... 2016@triggerfoo,triggerbaz,... ..." */ + std::unordered_map<std::string, std::vector<std::string> > result; + std::vector<std::string> pairs; + boost::split(pairs, settings->value(key), boost::is_any_of(" ")); + for (std::string const& pair : pairs) { + if (pair.empty() || pair == "None") continue; + auto i = pair.find('@'); + if (!(i != std::string::npos && + pair.find('@', i + 1) == std::string::npos)) throw std::invalid_argument( + std::string() + "Malformed trigger list in configuration item `" + key + "'"); + auto&& period = pair.substr(0, i), triggerstr = pair.substr(i + 1); + auto&& triggers = result[period]; + if (!triggers.empty()) throw std::invalid_argument( + std::string() + "Period `" + period + "' appears multiple times in configuration item `" + key + + "'"); + boost::split(triggers, triggerstr, boost::is_any_of(",")); + } + /* merge trigger map from this configuration line into triggersByPeriod */ + for (auto&& kv : result) { + auto&& src = kv.second; + auto&& dst = triggersByPeriod[kv.first]; + for (std::string const& trigger : src) { + if (std::find(dst.begin(), dst.end(), + trigger) != dst.end()) throw std::invalid_argument( + std::string() + "Trigger `" + trigger + "' was specified multiple times"); + dst.push_back(trigger); + } + } + }; + m_trigGlobalConfiguration.isActivated = true; + parseTriggerString(m_trigGlobalConfiguration.trigger, "ElectronTriggers"); + parseTriggerString(m_trigGlobalConfiguration.trigger_loose, "ElectronTriggersLoose"); + parseTriggerString(m_trigGlobalConfiguration.trigger, "MuonTriggers"); + parseTriggerString(m_trigGlobalConfiguration.trigger_loose, "MuonTriggersLoose"); + parseTriggerString(m_trigGlobalConfiguration.trigger, "GlobalTriggers"); + parseTriggerString(m_trigGlobalConfiguration.trigger_loose, "GlobalTriggersLoose"); + } + } - + float TopConfig::readFloatOption(top::ConfigurationSettings* const& settings, std::string instring) const { + float invalue = 99999999.; + try{ + invalue = std::stof(settings->value(instring)); + } + catch (...) { + throw std::invalid_argument { + "TopConfig: cannot convert Option " + instring + "into float" + }; + } + return invalue; } - void TopConfig::setGrlDir( const std::string& s ) - { + void TopConfig::setGrlDir(const std::string& s) { if (!m_configFixed) { m_grlDir = s; m_grlDir.erase(remove_if(m_grlDir.begin(), m_grlDir.end(), isspace), m_grlDir.end()); @@ -886,206 +1853,262 @@ namespace top{ } } - void TopConfig::jetUncertainties_NPModel( const std::string& s ) - { + void TopConfig::setTDPPath(const std::string& s) { + if (!m_configFixed) { + m_topDataPreparationPath = s; + } + } + + void TopConfig::jetUncertainties_NPModel(const std::string& s) { if (!m_configFixed) { m_jetUncertainties_NPModel = s; m_doMultipleJES = false; - if (m_jetUncertainties_NPModel == "3NP") { + if (m_jetUncertainties_NPModel == "StrongReduction") { m_doMultipleJES = true; } } } - void TopConfig::sgKeyMCParticle(const std::string& s) - { + void TopConfig::jetUncertainties_QGFracFile(const std::string& s) { if (!m_configFixed) { - m_useTruthParticles = false; - if (s != "None") - m_useTruthParticles = true; + m_jetUncertainties_QGFracFile = s; + } + } - m_sgKeyMCParticle = s; + void TopConfig::jetUncertainties_QGHistPatterns(const std::string& s) { + if (!m_configFixed) { + std::vector<std::string> outVector; + if (s.find(" ") != std::string::npos) { + throw std::runtime_error { + "TopConfig: jetUncertainties_QGHistPatterns string can't contain white spaces" + }; + } + if (s != "None") { + tokenize(s, outVector, ","); // list of DSIDs separated by commas + if (outVector.size() != 1) // if size is !=1, we need to check if these are DSIDs + for (auto s : outVector) { + int i = std::atoi(s.c_str()); + if (i < 300000 || i >= 1000000) throw std::runtime_error { + "TopConfig: jetUncertainties_QGHistPatterns string doesn't look like a list of DISDs! You can either specify a single string pattern or a list of DSIDs separated by commas." + }; + } } + m_jetUncertainties_QGHistPatterns = outVector; + } } - void TopConfig::sgKeyPhotons(const std::string& s) - { + void TopConfig::sgKeyMCParticle(const std::string& s) { if (!m_configFixed) { - m_usePhotons = false; - if (s != "None") - m_usePhotons = true; + m_useTruthParticles = false; + if (s != "None") m_useTruthParticles = true; - m_sgKeyPhotons = s; + m_sgKeyMCParticle = s; } } - void TopConfig::sgKeyElectrons(const std::string& s) - { - if (!m_configFixed){ - m_useElectrons = false; - if (s != "None") - m_useElectrons = true; + void TopConfig::sgKeyPhotons(const std::string& s) { + if (!m_configFixed) { + m_usePhotons = false; + if (s != "None") m_usePhotons = true; - m_sgKeyElectrons = s; - } + m_sgKeyPhotons = s; + } } + void TopConfig::sgKeyElectrons(const std::string& s) { + if (!m_configFixed) { + m_useElectrons = false; + if (s != "None") m_useElectrons = true; + + m_sgKeyElectrons = s; + } + } - void TopConfig::sgKeyMuons(const std::string& s) - { - if(!m_configFixed){ - m_useMuons = false; - if (s != "None") - m_useMuons = true; + void TopConfig::sgKeyFwdElectrons(const std::string& s) { + if (!m_configFixed) { + m_useFwdElectrons = false; + if (s != "None") m_useFwdElectrons = true; - m_sgKeyMuons = s; - } + m_sgKeyFwdElectrons = s; + } } - void TopConfig::sgKeyTaus(const std::string& s) - { - if(!m_configFixed){ - m_useTaus = false; - if (s != "None") - m_useTaus = true; + void TopConfig::sgKeyMuons(const std::string& s) { + if (!m_configFixed) { + m_useMuons = false; + if (s != "None") m_useMuons = true; - m_sgKeyTaus = s; - } + m_sgKeyMuons = s; + } } - void TopConfig::sgKeyJets(const std::string& s) - { - if (!m_configFixed){ - m_useJets = false; - if (s != "None") - m_useJets = true; + void TopConfig::sgKeySoftMuons(const std::string& s) { + if (!m_configFixed) { + m_useSoftMuons = false; + if (s != "None") m_useSoftMuons = true; + + m_sgKeySoftMuons = s; + } + } - // If anti-kt4 pflow jets then... - if (s == "AntiKt4EMPFlowJets" ) - m_useParticleFlowJets = true; + void TopConfig::sgKeyTaus(const std::string& s) { + if (!m_configFixed) { + m_useTaus = false; + if (s != "None") m_useTaus = true; - m_sgKeyJets = s; - } + m_sgKeyTaus = s; + } } - void TopConfig::sgKeyLargeRJets(const std::string& s) - { - if(!m_configFixed){ - m_useLargeRJets = false; - if (s != "None") - m_useLargeRJets = true; + void TopConfig::sgKeyJets(const std::string& s) { + if (!m_configFixed) { + m_useJets = false; + if (s != "None") m_useJets = true; - m_sgKeyLargeRJets = s; - } + size_t delim_pos = s.find('_'); + // for b-tagging shallow copies, e,g. + // AntiKt4EMPFlowJets_BTagging20181003 + // we want to have quick access to base collection name + m_sgKeyJetsType = s.substr(0, delim_pos); + + // If anti-kt4 pflow jets then... + if (m_sgKeyJetsType == "AntiKt4EMPFlowJets") m_useParticleFlowJets = true; + + m_sgKeyJets = s; + } } - void TopConfig::sgKeyTrackJets(const std::string& s) - { - if(!m_configFixed){ - m_useTrackJets = false; - if (s != "None") - m_useTrackJets = true; + void TopConfig::sgKeyLargeRJets(const std::string& s) { + if (!m_configFixed) { + m_useLargeRJets = false; + if (s != "None") m_useLargeRJets = true; - m_sgKeyTrackJets = s; - } + m_sgKeyLargeRJets = s; + } } - void TopConfig::sgKeyTruthElectrons(const std::string& s) - { - if(!m_configFixed){ - m_useTruthElectrons = false; - if (s != "None") - m_useTruthElectrons = true; + void TopConfig::sgKeyTrackJets(const std::string& s) { + if (!m_configFixed) { + m_useTrackJets = false; + if (s != "None") m_useTrackJets = true; - m_sgKeyTruthElectrons = s; - } + size_t delim_pos = s.find('_'); + // for time-stamped track jet collections due to b-tagging + // AntiKtVR30Rmax4Rmin02TrackJets_BTagging201903 + // we want to have quick access to base collection name + m_sgKeyTrackJetsType = s.substr(0, delim_pos); + + m_sgKeyTrackJets = s; + } } - void TopConfig::sgKeyTruthMuons(const std::string& s) - { - if(!m_configFixed){ - m_useTruthMuons = false; - if (s != "None") - m_useTruthMuons = true; + void TopConfig::sgKeyTracks(const std::string& s) { + + if (!m_configFixed) { + m_useTracks = false; + if (s != "None") m_useTracks = true; + m_sgKeyTracks = s; + } + } - m_sgKeyTruthMuons = s; - } + void TopConfig::sgKeyTruthElectrons(const std::string& s) { + if (!m_configFixed) { + m_useTruthElectrons = false; + if (s != "None") m_useTruthElectrons = true; + + m_sgKeyTruthElectrons = s; + } } - void TopConfig::sgKeyTruthPhotons(const std::string& s) - { - if(!m_configFixed){ - m_useTruthPhotons = false; - if (s != "None"){ - m_useTruthPhotons = true; - } + void TopConfig::sgKeyTruthMuons(const std::string& s) { + if (!m_configFixed) { + m_useTruthMuons = false; + if (s != "None") m_useTruthMuons = true; + + m_sgKeyTruthMuons = s; + } + } - m_sgKeyTruthPhotons = s; + void TopConfig::sgKeyTruthPhotons(const std::string& s) { + if (!m_configFixed) { + m_useTruthPhotons = false; + if (s != "None") { + m_useTruthPhotons = true; } + + m_sgKeyTruthPhotons = s; + } } - void TopConfig::sgKeyTruthMET(const std::string& s) - { - if(!m_configFixed){ - m_useTruthMET = false; - if (s != "None") - m_useTruthMET = true; + void TopConfig::sgKeyTruthMET(const std::string& s) { + if (!m_configFixed) { + m_useTruthMET = false; + if (s != "None") m_useTruthMET = true; - m_sgKeyTruthMET = s; - } + m_sgKeyTruthMET = s; + } } - void TopConfig::sgKeyTruthJets(const std::string& s) - { - if(!m_configFixed){ - m_useTruthJets = false; - if (s != "None") - m_useTruthJets = true; + void TopConfig::sgKeyTruthJets(const std::string& s) { + if (!m_configFixed) { + m_useTruthJets = false; + if (s != "None") m_useTruthJets = true; - m_sgKeyTruthJets = s; - } + m_sgKeyTruthJets = s; + } } - void TopConfig::sgKeyTruthLargeRJets(const std::string& s) - { - if(!m_configFixed){ - m_useTruthLargeRJets = false; - if (s != "None") - m_useTruthLargeRJets = true; + void TopConfig::sgKeyTruthLargeRJets(const std::string& s) { + if (!m_configFixed) { + m_useTruthLargeRJets = false; + if (s != "None") m_useTruthLargeRJets = true; - m_sgKeyTruthLargeRJets = s; - } + m_sgKeyTruthLargeRJets = s; + } } - void TopConfig::decoKeyJetGhostTrack(const std::string & key) - { - if (!m_configFixed) { - m_useJetGhostTrack = false; - if (key != "None") - m_useJetGhostTrack = true; + void TopConfig::sgKeyTruthTaus(const std::string& s) { + if (!m_configFixed) { + m_useTruthTaus = false; + if (s != "None") m_useTruthTaus = true; - m_decoKeyJetGhostTrack = key; - } + m_sgKeyTruthTaus = s; + } + } + + void TopConfig::decoKeyJetGhostTrack(const std::string& key) { + if (!m_configFixed) { + m_useJetGhostTrack = false; + if (key != "None") m_useJetGhostTrack = true; + + m_decoKeyJetGhostTrack = key; + } } // setting the run periods for ghost track // even if configuration is fixed - could be changed later - void TopConfig::runPeriodJetGhostTrack(const std::vector<std::uint32_t> & vect) - { - if (m_useJetGhostTrack == true) - m_jetGhostTrackRunPeriods = vect; + void TopConfig::runPeriodJetGhostTrack(const std::vector<std::uint32_t>& vect) { + if (m_useJetGhostTrack == true) m_jetGhostTrackRunPeriods = vect; } - void TopConfig::setBTaggingSFSysts( std::string WP, const std::set<std::string>& btagging_SF_names, bool isTrackJet ) - { - + // setting the run periods for tracks + // even if configuration is fixed - could be changed later + void TopConfig::runPeriodTrack(const std::vector<std::uint32_t>& vect) { + if (m_useTracks) m_trackRunPeriods = vect; + } + + + void TopConfig::setBTaggingSFSysts(std::string WP, const std::set<std::string>& btagging_SF_names, bool isTrackJet) { //this avoids code duplication - std::unordered_map<std::string,std::set<std::string>>& base_names = isTrackJet ? m_bTag_base_names_trkJet : m_bTag_base_names; - std::unordered_map<std::string,std::set<std::string>>& named_systs = isTrackJet ? m_bTag_named_systs_trkJet : m_bTag_named_systs; - std::unordered_map<std::string,unsigned int>& eigen_B = isTrackJet ? m_bTag_eigen_B_trkJet : m_bTag_eigen_B; - std::unordered_map<std::string,unsigned int>& eigen_C = isTrackJet ? m_bTag_eigen_C_trkJet : m_bTag_eigen_C; - std::unordered_map<std::string,unsigned int>& eigen_light = isTrackJet ? m_bTag_eigen_light_trkJet : m_bTag_eigen_light; - + std::unordered_map<std::string, + std::set<std::string> >& base_names = isTrackJet ? bTag_base_names_trkJet : bTag_base_names; + std::unordered_map<std::string, + std::set<std::string> >& named_systs = isTrackJet ? bTag_named_systs_trkJet : bTag_named_systs; + std::unordered_map<std::string, unsigned int>& eigen_B = isTrackJet ? bTag_eigen_B_trkJet : bTag_eigen_B; + std::unordered_map<std::string, unsigned int>& eigen_C = isTrackJet ? bTag_eigen_C_trkJet : bTag_eigen_C; + std::unordered_map<std::string, + unsigned int>& eigen_light = isTrackJet ? bTag_eigen_light_trkJet : bTag_eigen_light; + //names of all systematics base_names[WP] = btagging_SF_names; //initialise named systematics to empty set @@ -1095,52 +2118,115 @@ namespace top{ eigen_C[WP] = 0; eigen_light[WP] = 0; // loop on systematic names - for( const auto& SF_name : base_names.at(WP) ){ - if ( SF_name.find("_Eigen_B_") != std::string::npos ) - eigen_B.at(WP)++; - else if ( SF_name.find("_Eigen_C_") != std::string::npos ) - eigen_C.at(WP)++; - else if ( SF_name.find("_Eigen_Light_") != std::string::npos ) - eigen_light.at(WP)++; + for (const auto& SF_name : base_names.at(WP)) { + if (SF_name.find("_Eigen_B_") != std::string::npos) eigen_B.at(WP)++; + else if (SF_name.find("_Eigen_C_") != std::string::npos) eigen_C.at(WP)++; + else if (SF_name.find("_Eigen_Light_") != std::string::npos) eigen_light.at(WP)++; else named_systs[WP].insert(SF_name); } } + void TopConfig::setCalibBoostedJetTagger(const std::string& WP, const std::string& SFname) { + m_boostedTaggerSFnames[WP] = SFname; + } + std::string TopConfig::FormatedWP(std::string raw_WP) { // just to have some backward compatibility... - if (raw_WP=="60%") return "FixedCutBEff_60"; - else if (raw_WP=="70%") return "FixedCutBEff_70"; - else if (raw_WP=="77%") return "FixedCutBEff_77"; - else if (raw_WP=="85%") return "FixedCutBEff_85"; + if (raw_WP == "60%") return "FixedCutBEff_60"; + else if (raw_WP == "70%") return "FixedCutBEff_70"; + else if (raw_WP == "77%") return "FixedCutBEff_77"; + else if (raw_WP == "85%") return "FixedCutBEff_85"; else return raw_WP; } - - void TopConfig::setBTagWP_available( std::string btagging_WP ) { + + void TopConfig::parse_bTagWPs(const std::string& btagWPsettingString, + std::vector<std::pair<std::string, std::string>>& btagWPlist, + const std::string& jetCollectionName) { + std::istringstream str_btagging_WP(btagWPsettingString); + std::vector<std::string> all_btagging_WP; + std::copy(std::istream_iterator<std::string>(str_btagging_WP), + std::istream_iterator<std::string>(), + std::back_inserter(all_btagging_WP)); + // loop through all btagging WPs requested + for (const auto& AlgTag : all_btagging_WP) { + std::vector<std::string> btagAlg_btagWP; + tokenize(AlgTag, btagAlg_btagWP, ":"); + // DEFAULT algorithm - May remove in future + std::string alg = "MV2c10"; + std::string tag = ""; + // If no ':' delimiter, assume we want default algorithm, and take the WP from the option + if (btagAlg_btagWP.size() == 2) { + alg = btagAlg_btagWP.at(0); + tag = btagAlg_btagWP.at(1); + } else if (btagAlg_btagWP.size() == 1) { + tag = btagAlg_btagWP.at(0); + } else { + ATH_MSG_ERROR("Cannot parse b-tagging ALGORITHM_NAME:WP. Incorrect format."); + continue; + } + + ATH_MSG_INFO("BTagging algorithm: " << alg << "_" << tag << " for collection: " << jetCollectionName); + std::string formatedWP = FormatedWP(tag); + std::pair<std::string, std::string> alg_tag = std::make_pair(alg, tag); + // take care that no WP is taken twice + if (std::find(btagWPlist.begin(), btagWPlist.end(), alg_tag) == btagWPlist.end()) { + btagWPlist.push_back(alg_tag); + } else { + ATH_MSG_INFO("This b-tag algorithm was already added!"); + } + } + } + + void TopConfig::setBTagWP_available(std::string btagging_WP) { m_available_btaggingWP.push_back(btagging_WP); } - - void TopConfig::setBTagWP_available_trkJet( std::string btagging_WP ) { + + void TopConfig::setBTagWP_available_trkJet(std::string btagging_WP) { m_available_btaggingWP_trkJet.push_back(btagging_WP); } - - void TopConfig::setBTagWP_calibrated( std::string btagging_WP ) { + + void TopConfig::setBTagWP_calibrated(std::string btagging_WP) { m_calibrated_btaggingWP.push_back(btagging_WP); } - - void TopConfig::setBTagWP_calibrated_trkJet( std::string btagging_WP ) { + + void TopConfig::setBTagWP_calibrated_trkJet(std::string btagging_WP) { m_calibrated_btaggingWP_trkJet.push_back(btagging_WP); } + void TopConfig::setBTagAlgo_available(std::string algo, std::string toolName) { + if (algo.find("DL1") == std::string::npos) { + if (algo.find("MV2c10") != std::string::npos) + m_MV2c10_algo_used = true; + else + ATH_MSG_WARNING("Encountered b-tagging algorithm that is not considered in the EventSaver: " << algo); + } else { + auto is_inserted = m_available_btaggingAlgos.insert(algo); + if (is_inserted.second) { + m_algo_selTools[algo] = toolName; + } + } + } - void TopConfig::addLHAPDFResult( const std::string& pdf_name, - std::vector<float> sum_of_weights ){ + void TopConfig::setBTagAlgo_available_trkJet(std::string algo, std::string toolName) { + if (algo.find("DL1") == std::string::npos) { + if (algo.find("MV2c10") != std::string::npos) + m_MV2c10_algo_used_trkJet = true; + else + ATH_MSG_WARNING("Encountered track-jet b-tagging algorithm that is not considered in the EventSaver: " << algo); + } else { + auto is_inserted = m_available_btaggingAlgos_trkJet.insert(algo); + if (is_inserted.second) { + m_algo_selTools_trkJet[algo] = toolName; + } + } + } + void TopConfig::addLHAPDFResult(const std::string& pdf_name, + std::vector<float> sum_of_weights) { m_lhapdf_options.pdf_results[ pdf_name ] = sum_of_weights; - } - void TopConfig::outputEvents(const std::string& s) - { + void TopConfig::outputEvents(const std::string& s) { if (!m_configFixed) { m_outputEvents = s; if (m_outputEvents == "AllEvents") { @@ -1150,20 +2236,19 @@ namespace top{ } /// syst helper functions - bool TopConfig::isSystNominal(const std::string& syst) const{ + bool TopConfig::isSystNominal(const std::string& syst) const { return boost::iequals(syst, m_nominalSystName); } - bool TopConfig::isSystAll(const std::string& syst) const{ + bool TopConfig::isSystAll(const std::string& syst) const { return boost::iequals(syst, m_allSystName); } - bool TopConfig::getSystematicsList(const std::string& syststr, std::set<std::string>& systList) const{ - - if(isSystAll(syststr) || isSystNominal(syststr)) return true; + bool TopConfig::getSystematicsList(const std::string& syststr, std::set<std::string>& systList) const { + if (isSystAll(syststr) || isSystNominal(syststr)) return true; - if( syststr.find(" ") != std::string::npos ){ - std::cout << "ERROR getSystematicsList: systematic string can't contain white spaces" << std::endl; + if (syststr.find(" ") != std::string::npos) { + ATH_MSG_ERROR("getSystematicsList: systematic string can't contain white spaces"); return false; } @@ -1171,45 +2256,41 @@ namespace top{ std::string::size_type start = 0, end = 0; while ((end = syststr.find(separator, start)) != std::string::npos) { std::string token = syststr.substr(start, end - start); - if(token.size()) systList.insert(token); + if (token.size()) systList.insert(token); start = end + 1; } std::string lasttoken = syststr.substr(start); - if(lasttoken.size()) systList.insert(lasttoken); + if (lasttoken.size()) systList.insert(lasttoken); return true; - } - bool TopConfig::contains(const std::set<std::string>& systList, const std::string& name) const{ + bool TopConfig::contains(const std::set<std::string>& systList, const std::string& name) const { return systList.find(name) != systList.end(); } - // set systematics - void TopConfig::systematicsPhotons( const std::list<CP::SystematicSet>& syst) - { - if( !m_configFixed ){ - for( auto s : syst ){ - m_systHashPhotons->insert( s.hash() ); - m_list_systHashAll->push_back( s.hash() ); - m_systMapPhotons->insert( std::make_pair( s.hash() , s ) ); - m_systSgKeyMapPhotons->insert( std::make_pair( s.hash() , m_sgKeyPhotons + "_" + s.name() ) ); + void TopConfig::systematicsPhotons(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (auto s : syst) { + m_systHashPhotons->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapPhotons->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapPhotons->insert(std::make_pair(s.hash(), m_sgKeyPhotons + "_" + s.name())); } m_list_systHashAll->sort(); m_list_systHashAll->unique(); } } - void TopConfig::systematicsElectrons( const std::list<CP::SystematicSet>& syst) - { - if( !m_configFixed ){ - for( auto s : syst ){ - m_systHashElectrons->insert( s.hash() ); - m_list_systHashAll->push_back( s.hash() ); - m_list_systHash_electronInJetSubtraction->push_back( s.hash() ); - m_systMapElectrons->insert( std::make_pair( s.hash() , s ) ); - m_systSgKeyMapElectrons->insert( std::make_pair( s.hash() , m_sgKeyElectrons + "_" + s.name() ) ); + void TopConfig::systematicsElectrons(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (auto s : syst) { + m_systHashElectrons->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_list_systHash_electronInJetSubtraction->push_back(s.hash()); + m_systMapElectrons->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapElectrons->insert(std::make_pair(s.hash(), m_sgKeyElectrons + "_" + s.name())); } m_list_systHashAll->sort(); m_list_systHashAll->unique(); @@ -1218,43 +2299,66 @@ namespace top{ } } - void TopConfig::systematicsMuons( const std::list<CP::SystematicSet>& syst) - { - if( !m_configFixed ){ - for( auto s : syst ){ - m_systHashMuons->insert( s.hash() ); - m_list_systHashAll->push_back( s.hash() ); - m_systMapMuons->insert( std::make_pair( s.hash() , s ) ); - m_systSgKeyMapMuons->insert( std::make_pair( s.hash() , m_sgKeyMuons + "_" + s.name() ) ); + void TopConfig::systematicsFwdElectrons(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (const auto& s : syst) { + m_systHashFwdElectrons->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapFwdElectrons->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapFwdElectrons->insert(std::make_pair(s.hash(), m_sgKeyFwdElectrons + "_" + s.name())); + } + m_list_systHashAll->sort(); + m_list_systHashAll->unique(); + } + } + + void TopConfig::systematicsMuons(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (auto s : syst) { + m_systHashMuons->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapMuons->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapMuons->insert(std::make_pair(s.hash(), m_sgKeyMuons + "_" + s.name())); } m_list_systHashAll->sort(); m_list_systHashAll->unique(); } } - void TopConfig::systematicsTaus( const std::list<CP::SystematicSet>& syst) - { - if( !m_configFixed ){ - for( auto s : syst ){ - m_systHashTaus->insert( s.hash() ); - m_list_systHashAll->push_back( s.hash() ); - m_systMapTaus->insert( std::make_pair( s.hash() , s ) ); - m_systSgKeyMapTaus->insert( std::make_pair( s.hash() , m_sgKeyTaus + "_" + s.name() ) ); + void TopConfig::systematicsSoftMuons(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (const CP::SystematicSet& s : syst) { + m_systHashSoftMuons->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapSoftMuons->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapSoftMuons->insert(std::make_pair(s.hash(), m_sgKeySoftMuons + "_" + s.name())); + } + m_list_systHashAll->sort(); + m_list_systHashAll->unique(); + } + } + + void TopConfig::systematicsTaus(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (auto s : syst) { + m_systHashTaus->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapTaus->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapTaus->insert(std::make_pair(s.hash(), m_sgKeyTaus + "_" + s.name())); } m_list_systHashAll->sort(); m_list_systHashAll->unique(); } } - void TopConfig::systematicsJets( const std::list<CP::SystematicSet>& syst) - { - if( !m_configFixed ){ - for( auto s : syst ){ - m_systHashJets->insert( s.hash() ); - m_list_systHashAll->push_back( s.hash() ); - m_list_systHash_electronInJetSubtraction->push_back( s.hash() ); - m_systMapJets->insert( std::make_pair( s.hash() , s ) ); - m_systSgKeyMapJets->insert( std::make_pair( s.hash() , m_sgKeyJets + "_" + s.name() ) ); + void TopConfig::systematicsJets(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (auto s : syst) { + m_systHashJets->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_list_systHash_electronInJetSubtraction->push_back(s.hash()); + m_systMapJets->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapJets->insert(std::make_pair(s.hash(), m_sgKeyJets + "_" + s.name())); } m_list_systHashAll->sort(); m_list_systHashAll->unique(); @@ -1263,79 +2367,94 @@ namespace top{ } } - void TopConfig::systematicsLargeRJets( const std::list<CP::SystematicSet>& syst) - { - if( !m_configFixed ){ - for( auto s : syst ){ - m_systHashLargeRJets->insert( s.hash() ); - m_list_systHashAll->push_back( s.hash() ); - m_systMapLargeRJets->insert( std::make_pair( s.hash() , s ) ); - m_systSgKeyMapLargeRJets->insert( std::make_pair( s.hash() , m_sgKeyLargeRJets + "_" + s.name() ) ); + void TopConfig::systematicsLargeRJets(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (auto s : syst) { + m_systHashLargeRJets->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapLargeRJets->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapLargeRJets->insert(std::make_pair(s.hash(), m_sgKeyLargeRJets + "_" + s.name())); } m_list_systHashAll->sort(); m_list_systHashAll->unique(); } } - void TopConfig::systematicsTrackJets( const std::list<CP::SystematicSet>& syst) - { - if( !m_configFixed ){ - for( auto s : syst ){ - m_systHashTrackJets->insert( s.hash() ); - m_list_systHashAll->push_back( s.hash() ); - m_systMapTrackJets->insert( std::make_pair( s.hash() , s ) ); - m_systSgKeyMapTrackJets->insert( std::make_pair( s.hash() , m_sgKeyTrackJets + "_" + s.name() ) ); + void TopConfig::systematicsTrackJets(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (auto s : syst) { + m_systHashTrackJets->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapTrackJets->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapTrackJets->insert(std::make_pair(s.hash(), m_sgKeyTrackJets + "_" + s.name())); } m_list_systHashAll->sort(); m_list_systHashAll->unique(); } } - void TopConfig::systematicsMET( const std::list<CP::SystematicSet>& syst) - { - if( !m_configFixed ){ - for( auto s : syst ){ - m_systHashMET->insert( s.hash() ); - m_list_systHashAll->push_back( s.hash() ); - m_systMapMET->insert( std::make_pair( s.hash() , s ) ); - m_systSgKeyMapMET->insert( std::make_pair( s.hash() , m_sgKeyLargeRJets + "_" + s.name() ) ); + void TopConfig::systematicsMET(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + for (auto s : syst) { + m_systHashMET->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapMET->insert(std::make_pair(s.hash(), s)); + m_systSgKeyMapMET->insert(std::make_pair(s.hash(), m_sgKeyLargeRJets + "_" + s.name())); } m_list_systHashAll->sort(); m_list_systHashAll->unique(); } } - void TopConfig::systematicsJetGhostTrack( const std::list<CP::SystematicSet>& syst) { - if( !m_configFixed ){ - // Add the nominal (for reporting purposes). - (* m_systMapJetGhostTrack)[m_nominalHashValue] = {}; - (* m_systDecoKeyMapJetGhostTrack)[m_nominalHashValue] = m_decoKeyJetGhostTrack; - m_jetGhostTrackSystematics.push_back(""); + void TopConfig::systematicsJetGhostTrack(const std::list<CP::SystematicSet>& syst) { + if (!m_configFixed) { + // Add the nominal (for reporting purposes). + (*m_systMapJetGhostTrack)[m_nominalHashValue] = {}; + (*m_systDecoKeyMapJetGhostTrack)[m_nominalHashValue] = m_decoKeyJetGhostTrack + "_"; + m_jetGhostTrackSystematics.push_back(""); + + for (auto s : syst) { + (*m_systMapJetGhostTrack)[s.hash()] = s; + (*m_systDecoKeyMapJetGhostTrack)[s.hash()] = m_decoKeyJetGhostTrack + "_" + s.name(); + m_list_systHashAll->push_back(s.hash()); + m_jetGhostTrackSystematics.push_back(s.name()); + } + + // Ensure that elements are unique. + std::sort(m_jetGhostTrackSystematics.begin(), + m_jetGhostTrackSystematics.end()); + auto last = std::unique(m_jetGhostTrackSystematics.begin(), + m_jetGhostTrackSystematics.end()); + m_jetGhostTrackSystematics.erase(last, + m_jetGhostTrackSystematics.end()); - for(auto s : syst){ - (* m_systMapJetGhostTrack)[s.hash()] = s; - (* m_systDecoKeyMapJetGhostTrack)[s.hash()] = m_decoKeyJetGhostTrack + "_" + s.name(); - m_jetGhostTrackSystematics.push_back(s.name()); - } + m_list_systHashAll->sort(); + m_list_systHashAll->unique(); + } + } + + void TopConfig::systematicsTracks(const std::list<CP::SystematicSet>& syst) { + + if (!m_configFixed) { + + for (auto s : syst) { + m_systHashTracks->insert(s.hash()); + m_list_systHashAll->push_back(s.hash()); + m_systMapTracks->insert(std::make_pair(s.hash(), s)); + + m_systSgKeyMapTracks->insert(std::make_pair(s.hash(), m_sgKeyTracks + "_" + s.name())); - // Ensure that elements are unique. - std::sort(m_jetGhostTrackSystematics.begin(), - m_jetGhostTrackSystematics.end()); - auto last = std::unique(m_jetGhostTrackSystematics.begin(), - m_jetGhostTrackSystematics.end()); - m_jetGhostTrackSystematics.erase(last, - m_jetGhostTrackSystematics.end()); } + + m_list_systHashAll->sort(); + m_list_systHashAll->unique(); + } + } - void TopConfig::fixConfiguration() - { - std::cout<<std::endl; - std::cout<<std::endl; - std::cout<<"TopConfig::fixConfiguration()"<<std::endl; - std::cout<<std::endl; - std::cout<<std::endl; + void TopConfig::fixConfiguration() { + ATH_MSG_INFO("TopConfig::fixConfiguration()"); // Prevent the user from changing anything // Yes, this is deliberate m_configFixed = true; @@ -1343,12 +2462,13 @@ namespace top{ // copy hash values in m_systHashAll_list // into m_systHashAll // The std::unordered_set is faster - for (std::list<std::size_t>::const_iterator i=m_list_systHashAll->begin();i!=m_list_systHashAll->end();++i) { - m_systHashAll->insert( (*i) ); + for (std::list<std::size_t>::const_iterator i = m_list_systHashAll->begin(); i != m_list_systHashAll->end(); ++i) { + m_systHashAll->insert((*i)); } // same for m_systHash_electronInJetSubtraction - for (std::list<std::size_t>::const_iterator i=m_list_systHash_electronInJetSubtraction->begin();i!=m_list_systHash_electronInJetSubtraction->end();++i) { - m_systHash_electronInJetSubtraction->insert( (*i) ); + for (std::list<std::size_t>::const_iterator i = m_list_systHash_electronInJetSubtraction->begin(); + i != m_list_systHash_electronInJetSubtraction->end(); ++i) { + m_systHash_electronInJetSubtraction->insert((*i)); } @@ -1356,108 +2476,155 @@ namespace top{ // Let's do ALL string manipulation here, never do it per event std::string nominalPhotons("SetMe"); std::string nominalElectrons("SetMe"); + std::string nominalFwdElectrons("SetMe"); std::string nominalMuons("SetMe"); + std::string nominalSoftMuons("SetMe"); std::string nominalTaus("SetMe"); std::string nominalJets("SetMe"); std::string nominalLargeRJets("SetMe"); std::string nominalTrackJets("SetMe"); + std::string nominalTracks("SetMe"); std::string nominal("nominal"); std::string tds("TDS"); std::string tdsAux("TDSAux."); // Figure out the nominal object collection names - std::unordered_map<std::size_t,std::string>::const_iterator ph = m_systSgKeyMapPhotons->find( m_nominalHashValue ); + std::unordered_map<std::size_t, std::string>::const_iterator ph = m_systSgKeyMapPhotons->find(m_nominalHashValue); if (ph != m_systSgKeyMapPhotons->end()) { nominalPhotons = (*ph).second; } - std::unordered_map<std::size_t,std::string>::const_iterator el = m_systSgKeyMapElectrons->find( m_nominalHashValue ); + std::unordered_map<std::size_t, std::string>::const_iterator el = m_systSgKeyMapElectrons->find(m_nominalHashValue); if (el != m_systSgKeyMapElectrons->end()) { nominalElectrons = (*el).second; } - std::unordered_map<std::size_t,std::string>::const_iterator mu = m_systSgKeyMapMuons->find( m_nominalHashValue ); + std::unordered_map<std::size_t, std::string>::const_iterator fwdel = m_systSgKeyMapFwdElectrons->find( + m_nominalHashValue); + if (fwdel != m_systSgKeyMapFwdElectrons->end()) { + nominalFwdElectrons = (*fwdel).second; + } + + std::unordered_map<std::size_t, std::string>::const_iterator mu = m_systSgKeyMapMuons->find(m_nominalHashValue); if (mu != m_systSgKeyMapMuons->end()) { nominalMuons = (*mu).second; } - std::unordered_map<std::size_t,std::string>::const_iterator tau = m_systSgKeyMapTaus->find( m_nominalHashValue ); + std::unordered_map<std::size_t, std::string>::const_iterator softmu = m_systSgKeyMapSoftMuons->find( + m_nominalHashValue); + if (softmu != m_systSgKeyMapSoftMuons->end()) { + nominalSoftMuons = (*softmu).second; + } + + std::unordered_map<std::size_t, std::string>::const_iterator tau = m_systSgKeyMapTaus->find(m_nominalHashValue); if (tau != m_systSgKeyMapTaus->end()) { nominalTaus = (*tau).second; } - std::unordered_map<std::size_t,std::string>::const_iterator jet = m_systSgKeyMapJets->find( m_nominalHashValue ); + std::unordered_map<std::size_t, std::string>::const_iterator jet = m_systSgKeyMapJets->find(m_nominalHashValue); if (jet != m_systSgKeyMapJets->end()) { nominalJets = (*jet).second; } - std::unordered_map<std::size_t,std::string>::const_iterator largeRJet = m_systSgKeyMapLargeRJets->find( m_nominalHashValue ); + std::unordered_map<std::size_t, std::string>::const_iterator largeRJet = m_systSgKeyMapLargeRJets->find( + m_nominalHashValue); if (largeRJet != m_systSgKeyMapLargeRJets->end()) { nominalLargeRJets = (*largeRJet).second; } - std::unordered_map<std::size_t,std::string>::const_iterator trackJet = m_systSgKeyMapTrackJets->find( m_nominalHashValue ); + std::unordered_map<std::size_t, std::string>::const_iterator trackJet = m_systSgKeyMapTrackJets->find( + m_nominalHashValue); if (trackJet != m_systSgKeyMapTrackJets->end()) { nominalTrackJets = (*trackJet).second; } + std::unordered_map<std::size_t, std::string>::const_iterator tracks = m_systSgKeyMapTracks->find(m_nominalHashValue); + if (tracks != m_systSgKeyMapTracks->end()) { + nominalTracks = (*tracks).second; + } - for (std::unordered_set<std::size_t>::const_iterator i=m_systHashAll->begin();i!=m_systHashAll->end();++i) { - std::unordered_map<std::size_t,std::string>::const_iterator ph = m_systSgKeyMapPhotons->find( *i ); + for (std::unordered_set<std::size_t>::const_iterator i = m_systHashAll->begin(); i != m_systHashAll->end(); ++i) { + std::unordered_map<std::size_t, std::string>::const_iterator ph = m_systSgKeyMapPhotons->find(*i); if (ph != m_systSgKeyMapPhotons->end()) { - m_systAllSgKeyMapPhotons->insert( std::make_pair( (*i) , (*ph).second ) ); + m_systAllSgKeyMapPhotons->insert(std::make_pair((*i), (*ph).second)); } if (ph == m_systSgKeyMapPhotons->end()) { - m_systAllSgKeyMapPhotons->insert( std::make_pair( (*i) , nominalPhotons ) ); + m_systAllSgKeyMapPhotons->insert(std::make_pair((*i), nominalPhotons)); } - std::unordered_map<std::size_t,std::string>::const_iterator el = m_systSgKeyMapElectrons->find( *i ); + std::unordered_map<std::size_t, std::string>::const_iterator el = m_systSgKeyMapElectrons->find(*i); if (el != m_systSgKeyMapElectrons->end()) { - m_systAllSgKeyMapElectrons->insert( std::make_pair( (*i) , (*el).second ) ); + m_systAllSgKeyMapElectrons->insert(std::make_pair((*i), (*el).second)); } if (el == m_systSgKeyMapElectrons->end()) { - m_systAllSgKeyMapElectrons->insert( std::make_pair( (*i) , nominalElectrons ) ); + m_systAllSgKeyMapElectrons->insert(std::make_pair((*i), nominalElectrons)); + } + + std::unordered_map<std::size_t, std::string>::const_iterator fwdel = m_systSgKeyMapFwdElectrons->find(*i); + if (fwdel != m_systSgKeyMapFwdElectrons->end()) { + m_systAllSgKeyMapFwdElectrons->insert(std::make_pair((*i), (*fwdel).second)); + } + if (fwdel == m_systSgKeyMapFwdElectrons->end()) { + m_systAllSgKeyMapFwdElectrons->insert(std::make_pair((*i), nominalFwdElectrons)); } - std::unordered_map<std::size_t,std::string>::const_iterator mu = m_systSgKeyMapMuons->find( *i ); + std::unordered_map<std::size_t, std::string>::const_iterator mu = m_systSgKeyMapMuons->find(*i); if (mu != m_systSgKeyMapMuons->end()) { - m_systAllSgKeyMapMuons->insert( std::make_pair( (*i) , (*mu).second ) ); + m_systAllSgKeyMapMuons->insert(std::make_pair((*i), (*mu).second)); } if (mu == m_systSgKeyMapMuons->end()) { - m_systAllSgKeyMapMuons->insert( std::make_pair( (*i) , nominalMuons ) ); + m_systAllSgKeyMapMuons->insert(std::make_pair((*i), nominalMuons)); } - std::unordered_map<std::size_t,std::string>::const_iterator tau = m_systSgKeyMapTaus->find( *i ); + std::unordered_map<std::size_t, std::string>::const_iterator softmu = m_systSgKeyMapSoftMuons->find(*i); + if (softmu != m_systSgKeyMapSoftMuons->end()) { + m_systAllSgKeyMapSoftMuons->insert(std::make_pair((*i), (*softmu).second)); + } + if (softmu == m_systSgKeyMapSoftMuons->end()) { + m_systAllSgKeyMapSoftMuons->insert(std::make_pair((*i), nominalSoftMuons)); + } + + std::unordered_map<std::size_t, std::string>::const_iterator tau = m_systSgKeyMapTaus->find(*i); if (tau != m_systSgKeyMapTaus->end()) { - m_systAllSgKeyMapTaus->insert( std::make_pair( (*i) , (*tau).second ) ); + m_systAllSgKeyMapTaus->insert(std::make_pair((*i), (*tau).second)); } if (tau == m_systSgKeyMapTaus->end()) { - m_systAllSgKeyMapTaus->insert( std::make_pair( (*i) , nominalTaus ) ); + m_systAllSgKeyMapTaus->insert(std::make_pair((*i), nominalTaus)); } - std::unordered_map<std::size_t,std::string>::const_iterator jet = m_systSgKeyMapJets->find( *i ); + std::unordered_map<std::size_t, std::string>::const_iterator jet = m_systSgKeyMapJets->find(*i); if (jet != m_systSgKeyMapJets->end()) { - m_systAllSgKeyMapJets->insert( std::make_pair( (*i) , (*jet).second ) ); + m_systAllSgKeyMapJets->insert(std::make_pair((*i), (*jet).second)); } if (jet == m_systSgKeyMapJets->end()) { - m_systAllSgKeyMapJets->insert( std::make_pair( (*i) , nominalJets ) ); + m_systAllSgKeyMapJets->insert(std::make_pair((*i), nominalJets)); } - std::unordered_map<std::size_t,std::string>::const_iterator largeRJet = m_systSgKeyMapLargeRJets->find( *i ); + std::unordered_map<std::size_t, std::string>::const_iterator largeRJet = m_systSgKeyMapLargeRJets->find(*i); if (largeRJet != m_systSgKeyMapLargeRJets->end()) { - m_systAllSgKeyMapLargeRJets->insert( std::make_pair( (*i) , (*largeRJet).second ) ); + m_systAllSgKeyMapLargeRJets->insert(std::make_pair((*i), (*largeRJet).second)); } if (largeRJet == m_systSgKeyMapLargeRJets->end()) { - m_systAllSgKeyMapLargeRJets->insert( std::make_pair( (*i) , nominalLargeRJets ) ); + m_systAllSgKeyMapLargeRJets->insert(std::make_pair((*i), nominalLargeRJets)); } - std::unordered_map<std::size_t,std::string>::const_iterator trackJet = m_systSgKeyMapTrackJets->find( *i ); + std::unordered_map<std::size_t, std::string>::const_iterator trackJet = m_systSgKeyMapTrackJets->find(*i); if (trackJet != m_systSgKeyMapTrackJets->end()) { - m_systAllSgKeyMapTrackJets->insert( std::make_pair( (*i) , (*trackJet).second ) ); + m_systAllSgKeyMapTrackJets->insert(std::make_pair((*i), (*trackJet).second)); } if (trackJet == m_systSgKeyMapTrackJets->end()) { - m_systAllSgKeyMapTrackJets->insert( std::make_pair( (*i) , nominalTrackJets ) ); + m_systAllSgKeyMapTrackJets->insert(std::make_pair((*i), nominalTrackJets)); + } + + std::unordered_map<std::size_t, std::string>::const_iterator tracks = m_systSgKeyMapTracks->find(*i); + if (tracks != m_systSgKeyMapTracks->end()) { + m_systAllSgKeyMapTracks->insert(std::make_pair((*i), (*tracks).second)); + } + if (tracks == m_systSgKeyMapTracks->end()) { + m_systAllSgKeyMapTracks->insert(std::make_pair((*i), nominalTracks)); } + + } // Loop over all systematic hash values @@ -1466,133 +2633,207 @@ namespace top{ std::string electronInJetSubtraction_Electrons("electronInJetSubtraction_Electrons_USING_"); std::string electronInJetSubtraction_Jets("electronInJetSubtraction_Jets_USING_"); std::string electronInJetSubtraction_JetsLoose("electronInJetSubtraction_JetsLoose_USING_"); - std::string electronInJetSubtraction_nominalElectrons = electronInJetSubtraction_Electrons+nominalElectrons+"_AND_"+nominalJets; - std::string electronInJetSubtraction_nominalJets = electronInJetSubtraction_Jets+nominalElectrons+"_AND_"+nominalJets; - std::string electronInJetSubtraction_nominalJetsLoose = electronInJetSubtraction_JetsLoose+nominalElectrons+"_AND_"+nominalJets; + std::string electronInJetSubtraction_nominalElectrons = electronInJetSubtraction_Electrons + nominalElectrons + + "_AND_" + nominalJets; + std::string electronInJetSubtraction_nominalJets = electronInJetSubtraction_Jets + nominalElectrons + "_AND_" + + nominalJets; + std::string electronInJetSubtraction_nominalJetsLoose = electronInJetSubtraction_JetsLoose + nominalElectrons + + "_AND_" + nominalJets; - for (std::unordered_set<std::size_t>::const_iterator i=m_systHashAll->begin();i!=m_systHashAll->end();++i) { - std::unordered_map<std::size_t,std::string>::const_iterator el = m_systSgKeyMapElectrons->find( *i ); - std::unordered_map<std::size_t,std::string>::const_iterator jet = m_systSgKeyMapJets->find( *i ); + for (std::unordered_set<std::size_t>::const_iterator i = m_systHashAll->begin(); i != m_systHashAll->end(); ++i) { + std::unordered_map<std::size_t, std::string>::const_iterator el = m_systSgKeyMapElectrons->find(*i); + std::unordered_map<std::size_t, std::string>::const_iterator jet = m_systSgKeyMapJets->find(*i); if (el != m_systSgKeyMapElectrons->end()) { - m_systAllSgKeyMapElectrons_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_Electrons+(*el).second+"_AND_"+nominalJets ) ); - m_systAllSgKeyMapJets_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_Jets+(*el).second+"_AND_"+nominalJets ) ); - m_systSgKeyMapJets_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_Jets+(*el).second+"_AND_"+nominalJets ) ); - - m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_JetsLoose+(*el).second+"_AND_"+nominalJets ) ); - m_systSgKeyMapJetsLoose_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_JetsLoose+(*el).second+"_AND_"+nominalJets ) ); + m_systAllSgKeyMapElectrons_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_Electrons + + (*el).second + "_AND_" + + nominalJets)); + m_systAllSgKeyMapJets_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_Jets + + (*el).second + "_AND_" + nominalJets)); + m_systSgKeyMapJets_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_Jets + + (*el).second + "_AND_" + nominalJets)); + + m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_JetsLoose + + (*el).second + "_AND_" + + nominalJets)); + m_systSgKeyMapJetsLoose_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_JetsLoose + + (*el).second + "_AND_" + + nominalJets)); } if (jet != m_systSgKeyMapJets->end()) { - m_systAllSgKeyMapElectrons_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_Electrons+nominalElectrons+"_AND_"+(*jet).second ) ); - m_systAllSgKeyMapJets_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_Jets+nominalElectrons+"_AND_"+(*jet).second ) ); - m_systSgKeyMapJets_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_Jets+nominalElectrons+"_AND_"+(*jet).second ) ); - - m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_JetsLoose+nominalElectrons+"_AND_"+(*jet).second ) ); - m_systSgKeyMapJetsLoose_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_JetsLoose+nominalElectrons+"_AND_"+(*jet).second ) ); + m_systAllSgKeyMapElectrons_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_Electrons + + nominalElectrons + "_AND_" + + (*jet).second)); + m_systAllSgKeyMapJets_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_Jets + + nominalElectrons + "_AND_" + + (*jet).second)); + m_systSgKeyMapJets_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_Jets + + nominalElectrons + "_AND_" + + (*jet).second)); + + m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_JetsLoose + + nominalElectrons + "_AND_" + + (*jet).second)); + m_systSgKeyMapJetsLoose_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_JetsLoose + + nominalElectrons + "_AND_" + + (*jet).second)); } if (el == m_systSgKeyMapElectrons->end() && jet == m_systSgKeyMapJets->end()) { - m_systAllSgKeyMapElectrons_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_nominalElectrons ) ); - m_systAllSgKeyMapJets_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_nominalJets ) ); - m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->insert( std::make_pair( (*i) , electronInJetSubtraction_nominalJetsLoose ) ); + m_systAllSgKeyMapElectrons_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_nominalElectrons)); + m_systAllSgKeyMapJets_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_nominalJets)); + m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->insert(std::make_pair((*i), + electronInJetSubtraction_nominalJetsLoose)); } } // Loop over all systematic hash values } // electron in jet Subtraction // Tempory data store names - typedef std::unordered_map<std::size_t,std::string>::const_iterator Itr2; - for (Itr2 i=m_systAllSgKeyMapPhotons->begin();i!=m_systAllSgKeyMapPhotons->end();++i) { - m_systAllSgKeyMapPhotonsTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapPhotonsTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + typedef std::unordered_map<std::size_t, std::string>::const_iterator Itr2; + for (Itr2 i = m_systAllSgKeyMapPhotons->begin(); i != m_systAllSgKeyMapPhotons->end(); ++i) { + m_systAllSgKeyMapPhotonsTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapPhotonsTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); + } + + for (Itr2 i = m_systAllSgKeyMapElectrons->begin(); i != m_systAllSgKeyMapElectrons->end(); ++i) { + m_systAllSgKeyMapElectronsTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapElectronsTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapElectrons->begin();i!=m_systAllSgKeyMapElectrons->end();++i) { - m_systAllSgKeyMapElectronsTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapElectronsTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (const auto& i : *(m_systAllSgKeyMapFwdElectrons)) { + m_systAllSgKeyMapFwdElectronsTDS->insert(std::make_pair(i.first, i.second + tds)); + m_systAllSgKeyMapFwdElectronsTDSAux->insert(std::make_pair(i.first, i.second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapMuons->begin();i!=m_systAllSgKeyMapMuons->end();++i) { - m_systAllSgKeyMapMuonsTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapMuonsTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (Itr2 i = m_systAllSgKeyMapMuons->begin(); i != m_systAllSgKeyMapMuons->end(); ++i) { + m_systAllSgKeyMapMuonsTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapMuonsTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapTaus->begin();i!=m_systAllSgKeyMapTaus->end();++i) { - m_systAllSgKeyMapTausTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapTausTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (Itr2 i = m_systAllSgKeyMapSoftMuons->begin(); i != m_systAllSgKeyMapSoftMuons->end(); ++i) { + m_systAllSgKeyMapSoftMuonsTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapSoftMuonsTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapJets->begin();i!=m_systAllSgKeyMapJets->end();++i) { - m_systAllSgKeyMapJetsTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapJetsTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (Itr2 i = m_systAllSgKeyMapTaus->begin(); i != m_systAllSgKeyMapTaus->end(); ++i) { + m_systAllSgKeyMapTausTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapTausTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapLargeRJets->begin();i!=m_systAllSgKeyMapLargeRJets->end();++i) { - m_systAllSgKeyMapLargeRJetsTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapLargeRJetsTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (Itr2 i = m_systAllSgKeyMapJets->begin(); i != m_systAllSgKeyMapJets->end(); ++i) { + m_systAllSgKeyMapJetsTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapJetsTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapElectrons_electronInJetSubtraction->begin();i!=m_systAllSgKeyMapElectrons_electronInJetSubtraction->end();++i) { - m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (Itr2 i = m_systAllSgKeyMapLargeRJets->begin(); i != m_systAllSgKeyMapLargeRJets->end(); ++i) { + m_systAllSgKeyMapLargeRJetsTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapLargeRJetsTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapTrackJets->begin();i!=m_systAllSgKeyMapTrackJets->end();++i) { - m_systAllSgKeyMapTrackJetsTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapTrackJetsTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (Itr2 i = m_systAllSgKeyMapElectrons_electronInJetSubtraction->begin(); + i != m_systAllSgKeyMapElectrons_electronInJetSubtraction->end(); ++i) { + m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux->insert(std::make_pair((*i).first, + (*i).second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapJets_electronInJetSubtraction->begin();i!=m_systAllSgKeyMapJets_electronInJetSubtraction->end();++i) { - m_systAllSgKeyMapJets_electronInJetSubtractionTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (Itr2 i = m_systAllSgKeyMapTrackJets->begin(); i != m_systAllSgKeyMapTrackJets->end(); ++i) { + m_systAllSgKeyMapTrackJetsTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapTrackJetsTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); } - for (Itr2 i=m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->begin();i!=m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->end();++i) { - m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS->insert( std::make_pair( (*i).first , (*i).second + tds ) ); - m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux->insert( std::make_pair( (*i).first , (*i).second + tdsAux ) ); + for (Itr2 i = m_systAllSgKeyMapTracks->begin(); i != m_systAllSgKeyMapTracks->end(); ++i) { + m_systAllSgKeyMapTracksTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapTracksTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); + } + + for (Itr2 i = m_systAllSgKeyMapJets_electronInJetSubtraction->begin(); + i != m_systAllSgKeyMapJets_electronInJetSubtraction->end(); ++i) { + m_systAllSgKeyMapJets_electronInJetSubtractionTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux->insert(std::make_pair((*i).first, (*i).second + tdsAux)); + } + + for (Itr2 i = m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->begin(); + i != m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->end(); ++i) { + m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS->insert(std::make_pair((*i).first, (*i).second + tds)); + m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux->insert(std::make_pair((*i).first, + (*i).second + tdsAux)); } // TTree names - m_systAllTTreeNames->insert( std::make_pair( m_nominalHashValue , nominal ) ); - typedef std::unordered_map<std::size_t,CP::SystematicSet>::const_iterator Itr; + m_systAllTTreeNames->insert(std::make_pair(m_nominalHashValue, nominal)); + typedef std::unordered_map<std::size_t, CP::SystematicSet>::const_iterator Itr; if (m_usePhotons) { - for (Itr i=m_systMapPhotons->begin();i!=m_systMapPhotons->end();++i) { - m_systAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second.name() ) ); + for (Itr i = m_systMapPhotons->begin(); i != m_systMapPhotons->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); } } if (m_useElectrons) { - for (Itr i=m_systMapElectrons->begin();i!=m_systMapElectrons->end();++i) { - m_systAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second.name() ) ); + for (Itr i = m_systMapElectrons->begin(); i != m_systMapElectrons->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); + } + } + if (m_useFwdElectrons) { + for (Itr i = m_systMapFwdElectrons->begin(); i != m_systMapFwdElectrons->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); } } if (m_useMuons) { - for (Itr i=m_systMapMuons->begin();i!=m_systMapMuons->end();++i) { - m_systAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second.name() ) ); + for (Itr i = m_systMapMuons->begin(); i != m_systMapMuons->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); + } + } + if (m_useSoftMuons) { + for (Itr i = m_systMapSoftMuons->begin(); i != m_systMapSoftMuons->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); } } if (m_useTaus) { - for (Itr i=m_systMapTaus->begin();i!=m_systMapTaus->end();++i) { - m_systAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second.name() ) ); + for (Itr i = m_systMapTaus->begin(); i != m_systMapTaus->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); } } if (m_useJets) { - for (Itr i=m_systMapJets->begin();i!=m_systMapJets->end();++i) { - m_systAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second.name() ) ); + for (Itr i = m_systMapJets->begin(); i != m_systMapJets->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); } } if (m_useLargeRJets) { - for (Itr i=m_systMapLargeRJets->begin();i!=m_systMapLargeRJets->end();++i) { - m_systAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second.name() ) ); + for (Itr i = m_systMapLargeRJets->begin(); i != m_systMapLargeRJets->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); } } if (m_useTrackJets) { - for (Itr i=m_systMapTrackJets->begin();i!=m_systMapTrackJets->end();++i) { - m_systAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second.name() ) ); + for (Itr i = m_systMapTrackJets->begin(); i != m_systMapTrackJets->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); } } - for (Itr i=m_systMapMET->begin();i!=m_systMapMET->end();++i) { - m_systAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second.name() ) ); + if (m_useTracks) { + for (Itr i = m_systMapTracks->begin(); i != m_systMapTracks->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); + } + } + if (m_useJetGhostTrack) { + for (Itr i = m_systMapJetGhostTrack->begin(); i != m_systMapJetGhostTrack->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); + } + } + for (Itr i = m_systMapMET->begin(); i != m_systMapMET->end(); ++i) { + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second.name())); } @@ -1600,86 +2841,89 @@ namespace top{ // Missing ET from TTree names // KLFitter from TTree names - for (Itr2 i=m_systAllTTreeNames->begin();i!=m_systAllTTreeNames->end();++i) { - if (!m_doLooseTreeOnly) - m_systSgKeyMapMissingET->insert( std::make_pair( (*i).first , m_sgKeyMissingEt + "_" + (*i).second ) ); - if (m_doLooseEvents) - m_systSgKeyMapMissingETLoose->insert( std::make_pair( (*i).first , m_sgKeyMissingEt + "_Loose_" + (*i).second ) ); + for (Itr2 i = m_systAllTTreeNames->begin(); i != m_systAllTTreeNames->end(); ++i) { + if (m_doTightEvents) m_systSgKeyMapMissingET->insert(std::make_pair((*i).first, + m_sgKeyMissingEt + "_" + (*i).second)); + if (m_doLooseEvents) m_systSgKeyMapMissingETLoose->insert(std::make_pair((*i).first, + m_sgKeyMissingEt + "_Loose_" + + (*i).second)); - if (!m_doLooseTreeOnly) - m_systSgKeyMapKLFitter->insert( std::make_pair( (*i).first , m_sgKeyKLFitter + "_" + (*i).second ) ); - if (m_doLooseEvents) - m_systSgKeyMapKLFitterLoose->insert( std::make_pair( (*i).first , m_sgKeyKLFitter + "_Loose_" + (*i).second ) ); + if (m_doTightEvents) m_systSgKeyMapKLFitter->insert(std::make_pair((*i).first, + m_sgKeyKLFitter + "_" + (*i).second)); + if (m_doLooseEvents) m_systSgKeyMapKLFitterLoose->insert(std::make_pair((*i).first, + m_sgKeyKLFitter + "_Loose_" + + (*i).second)); - m_systSgKeyMapPseudoTop->insert( std::make_pair( (*i).first , m_sgKeyPseudoTop + "_" + (*i).second ) ); - + if (m_doTightEvents) m_systSgKeyMapPseudoTop->insert(std::make_pair((*i).first, + m_sgKeyPseudoTop + "_" + (*i).second)); + if (m_doLooseEvents) m_systSgKeyMapPseudoTopLoose->insert(std::make_pair((*i).first, + m_sgKeyPseudoTop + "_Loose_" + + (*i).second)); } // TTree index unsigned int TTreeIndex(0); - if (!m_doLooseTreeOnly) { - for (Itr2 i=m_systAllTTreeNames->begin();i!=m_systAllTTreeNames->end();++i) { - m_systAllTTreeIndex->insert( std::make_pair( (*i).first , TTreeIndex ) ); - ++TTreeIndex; + if (m_doTightEvents) { + for (Itr2 i = m_systAllTTreeNames->begin(); i != m_systAllTTreeNames->end(); ++i) { + if ((*i).second == "nominal" || m_doTightSysts) { + m_systAllTTreeIndex->insert(std::make_pair((*i).first, TTreeIndex)); + ++TTreeIndex; + } } } if (m_doLooseEvents) { - for (Itr2 i=m_systAllTTreeNames->begin();i!=m_systAllTTreeNames->end();++i) { - m_systAllTTreeLooseIndex->insert( std::make_pair( (*i).first , TTreeIndex ) ); - ++TTreeIndex; + for (Itr2 i = m_systAllTTreeNames->begin(); i != m_systAllTTreeNames->end(); ++i) { + if ((*i).second == "nominal" || m_doLooseSysts) { + m_systAllTTreeLooseIndex->insert(std::make_pair((*i).first, TTreeIndex)); + ++TTreeIndex; + } } } if (m_makeAllCPTools) { - for (Itr2 i=m_systAllTTreeNames->begin();i!=m_systAllTTreeNames->end();++i) { - m_systPersistantAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second) ); + for (Itr2 i = m_systAllTTreeNames->begin(); i != m_systAllTTreeNames->end(); ++i) { + m_systPersistantAllTTreeNames->insert(std::make_pair((*i).first, (*i).second)); } } - } - - - - const std::string& TopConfig::sgKeyPhotons( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapPhotons->find( hash ); + const std::string& TopConfig::sgKeyPhotons(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapPhotons->find(hash); if (key != m_systAllSgKeyMapPhotons->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyPhotonsTDS( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapPhotonsTDS->find( hash ); + const std::string& TopConfig::sgKeyPhotonsTDS(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapPhotonsTDS->find(hash); if (key != m_systAllSgKeyMapPhotonsTDS->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyPhotonsTDSAux( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapPhotonsTDSAux->find( hash ); + const std::string& TopConfig::sgKeyPhotonsTDSAux(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapPhotonsTDSAux->find(hash); if (key != m_systAllSgKeyMapPhotonsTDSAux->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyElectrons( const std::size_t hash ) const - { + const std::string& TopConfig::sgKeyElectrons(const std::size_t hash) const { if (!m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapElectrons->find( hash ); + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapElectrons->find(hash); if (key != m_systAllSgKeyMapElectrons->end()) { return (*key).second; } } if (m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapElectrons_electronInJetSubtraction->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = m_systAllSgKeyMapElectrons_electronInJetSubtraction->find( + hash); if (key != m_systAllSgKeyMapElectrons_electronInJetSubtraction->end()) { return (*key).second; } @@ -1688,17 +2932,18 @@ namespace top{ return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyElectronsTDS( const std::size_t hash ) const - { + const std::string& TopConfig::sgKeyElectronsTDS(const std::size_t hash) const { if (!m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapElectronsTDS->find( hash ); + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapElectronsTDS->find(hash); if (key != m_systAllSgKeyMapElectronsTDS->end()) { return (*key).second; } } if (m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = + m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS->find(hash); if (key != m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS->end()) { return (*key).second; } @@ -1707,17 +2952,18 @@ namespace top{ return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyElectronsTDSAux( const std::size_t hash ) const - { + const std::string& TopConfig::sgKeyElectronsTDSAux(const std::size_t hash) const { if (!m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapElectronsTDSAux->find( hash ); + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapElectronsTDSAux->find(hash); if (key != m_systAllSgKeyMapElectronsTDSAux->end()) { return (*key).second; } } if (m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = + m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux->find(hash); if (key != m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux->end()) { return (*key).second; } @@ -1726,74 +2972,124 @@ namespace top{ return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyElectronsStandAlone( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapElectrons->find( hash ); + const std::string& TopConfig::sgKeyElectronsStandAlone(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapElectrons->find(hash); if (key != m_systAllSgKeyMapElectrons->end()) { return (*key).second; } return m_sgKeyDummy; } + const std::string& TopConfig::sgKeyFwdElectrons(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapFwdElectrons->find(hash); + if (key != m_systAllSgKeyMapFwdElectrons->end()) { + return (*key).second; + } + + return m_sgKeyDummy; + } + + const std::string& TopConfig::sgKeyFwdElectronsTDS(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapFwdElectronsTDS->find(hash); + if (key != m_systAllSgKeyMapFwdElectronsTDS->end()) { + return (*key).second; + } + + return m_sgKeyDummy; + } + + const std::string& TopConfig::sgKeyFwdElectronsTDSAux(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapFwdElectronsTDSAux->find(hash); + if (key != m_systAllSgKeyMapFwdElectronsTDSAux->end()) { + return (*key).second; + } + + return m_sgKeyDummy; + } + + const std::string& TopConfig::sgKeyFwdElectronsStandAlone(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapFwdElectrons->find(hash); + if (key != m_systAllSgKeyMapFwdElectrons->end()) { + return (*key).second; + } + return m_sgKeyDummy; + } - const std::string& TopConfig::sgKeyMuons( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapMuons->find( hash ); + const std::string& TopConfig::sgKeyMuons(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapMuons->find(hash); if (key != m_systAllSgKeyMapMuons->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyMuonsTDS( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapMuonsTDS->find( hash ); + const std::string& TopConfig::sgKeyMuonsTDS(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapMuonsTDS->find(hash); if (key != m_systAllSgKeyMapMuonsTDS->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyMuonsTDSAux( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapMuonsTDSAux->find( hash ); + const std::string& TopConfig::sgKeyMuonsTDSAux(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapMuonsTDSAux->find(hash); if (key != m_systAllSgKeyMapMuonsTDSAux->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyTaus( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapTaus->find( hash ); + const std::string& TopConfig::sgKeySoftMuons(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapSoftMuons->find(hash); + if (key != m_systAllSgKeyMapSoftMuons->end()) { + return (*key).second; + } + return m_sgKeyDummy; + } + + const std::string& TopConfig::sgKeySoftMuonsTDS(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapSoftMuonsTDS->find(hash); + if (key != m_systAllSgKeyMapSoftMuonsTDS->end()) { + return (*key).second; + } + return m_sgKeyDummy; + } + + const std::string& TopConfig::sgKeySoftMuonsTDSAux(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapSoftMuonsTDSAux->find(hash); + if (key != m_systAllSgKeyMapSoftMuonsTDSAux->end()) { + return (*key).second; + } + return m_sgKeyDummy; + } + + const std::string& TopConfig::sgKeyTaus(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTaus->find(hash); if (key != m_systAllSgKeyMapTaus->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyTausTDS( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapTausTDS->find( hash ); + const std::string& TopConfig::sgKeyTausTDS(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTausTDS->find(hash); if (key != m_systAllSgKeyMapTausTDS->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyTausTDSAux( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapTausTDSAux->find( hash ); + const std::string& TopConfig::sgKeyTausTDSAux(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTausTDSAux->find(hash); if (key != m_systAllSgKeyMapTausTDSAux->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyJets( const std::size_t hash , const bool useLooseLeptonJets) const - { + const std::string& TopConfig::sgKeyJets(const std::size_t hash, const bool useLooseLeptonJets) const { if (!m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJets->find( hash ); + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapJets->find(hash); if (key != m_systAllSgKeyMapJets->end()) { return (*key).second; } @@ -1801,13 +3097,17 @@ namespace top{ if (m_applyElectronInJetSubtraction) { if (!useLooseLeptonJets) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJets_electronInJetSubtraction->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = + m_systAllSgKeyMapJets_electronInJetSubtraction->find(hash); if (key != m_systAllSgKeyMapJets_electronInJetSubtraction->end()) { return (*key).second; } } if (useLooseLeptonJets) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->find( + hash); if (key != m_systAllSgKeyMapJetsLoose_electronInJetSubtraction->end()) { return (*key).second; } @@ -1817,10 +3117,9 @@ namespace top{ return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyJetsTDS( const std::size_t hash , const bool useLooseLeptonJets) const - { + const std::string& TopConfig::sgKeyJetsTDS(const std::size_t hash, const bool useLooseLeptonJets) const { if (!m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJetsTDS->find( hash ); + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapJetsTDS->find(hash); if (key != m_systAllSgKeyMapJetsTDS->end()) { return (*key).second; } @@ -1828,13 +3127,17 @@ namespace top{ if (m_applyElectronInJetSubtraction) { if (!useLooseLeptonJets) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJets_electronInJetSubtractionTDS->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = m_systAllSgKeyMapJets_electronInJetSubtractionTDS->find( + hash); if (key != m_systAllSgKeyMapJets_electronInJetSubtractionTDS->end()) { return (*key).second; } } if (useLooseLeptonJets) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = + m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS->find(hash); if (key != m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS->end()) { return (*key).second; } @@ -1844,11 +3147,9 @@ namespace top{ return m_sgKeyDummy; } - - const std::string& TopConfig::sgKeyJetsTDSAux( const std::size_t hash , const bool useLooseLeptonJets) const - { + const std::string& TopConfig::sgKeyJetsTDSAux(const std::size_t hash, const bool useLooseLeptonJets) const { if (!m_applyElectronInJetSubtraction) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJetsTDSAux->find( hash ); + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapJetsTDSAux->find(hash); if (key != m_systAllSgKeyMapJetsTDSAux->end()) { return (*key).second; } @@ -1856,13 +3157,17 @@ namespace top{ if (m_applyElectronInJetSubtraction) { if (!useLooseLeptonJets) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = + m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux->find(hash); if (key != m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux->end()) { return (*key).second; } } if (useLooseLeptonJets) { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux->find( hash ); + std::unordered_map<std::size_t, + std::string>::const_iterator key = + m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux->find(hash); if (key != m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux->end()) { return (*key).second; } @@ -1872,138 +3177,159 @@ namespace top{ return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyJetsStandAlone( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapJets->find( hash ); + const std::string& TopConfig::sgKeyJetsStandAlone(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapJets->find(hash); if (key != m_systAllSgKeyMapJets->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyLargeRJets( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapLargeRJets->find( hash ); + const std::string& TopConfig::sgKeyLargeRJets(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapLargeRJets->find(hash); if (key != m_systAllSgKeyMapLargeRJets->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyLargeRJetsTDS( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapLargeRJetsTDS->find( hash ); + const std::string& TopConfig::sgKeyLargeRJetsTDS(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapLargeRJetsTDS->find(hash); if (key != m_systAllSgKeyMapLargeRJetsTDS->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyLargeRJetsTDSAux( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapLargeRJetsTDSAux->find( hash ); + const std::string& TopConfig::sgKeyLargeRJetsTDSAux(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapLargeRJetsTDSAux->find(hash); if (key != m_systAllSgKeyMapLargeRJetsTDSAux->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyTrackJets( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapTrackJets->find( hash ); + const std::string& TopConfig::sgKeyTrackJets(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTrackJets->find(hash); if (key != m_systAllSgKeyMapTrackJets->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyTrackJetsTDS( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapTrackJetsTDS->find( hash ); + const std::string& TopConfig::sgKeyTrackJetsTDS(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTrackJetsTDS->find(hash); if (key != m_systAllSgKeyMapTrackJetsTDS->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyTrackJetsTDSAux( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systAllSgKeyMapTrackJetsTDSAux->find( hash ); + const std::string& TopConfig::sgKeyTrackJetsTDSAux(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTrackJetsTDSAux->find(hash); if (key != m_systAllSgKeyMapTrackJetsTDSAux->end()) { return (*key).second; } return m_sgKeyDummy; } + const std::string& TopConfig::sgKeyTracks(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTracks->find(hash); + if (key != m_systAllSgKeyMapTracks->end()) { + return (*key).second; + } + return m_sgKeyDummy; + } + + const std::string& TopConfig::sgKeyTracksTDS(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTracksTDS->find(hash); + if (key != m_systAllSgKeyMapTracksTDS->end()) { + return (*key).second; + } + return m_sgKeyDummy; + } + + const std::string& TopConfig::sgKeyTracksTDSAux(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systAllSgKeyMapTracksTDSAux->find(hash); + if (key != m_systAllSgKeyMapTracksTDSAux->end()) { + return (*key).second; + } + return m_sgKeyDummy; + } - const std::string& TopConfig::sgKeyMissingEt( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systSgKeyMapMissingET->find( hash ); + const std::string& TopConfig::sgKeyMissingEt(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systSgKeyMapMissingET->find(hash); if (key != m_systSgKeyMapMissingET->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyMissingEtLoose( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systSgKeyMapMissingETLoose->find( hash ); + const std::string& TopConfig::sgKeyMissingEtLoose(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systSgKeyMapMissingETLoose->find(hash); if (key != m_systSgKeyMapMissingETLoose->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyKLFitter( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systSgKeyMapKLFitter->find( hash ); + const std::string& TopConfig::sgKeyKLFitter(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systSgKeyMapKLFitter->find(hash); if (key != m_systSgKeyMapKLFitter->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyKLFitterLoose( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systSgKeyMapKLFitterLoose->find( hash ); + const std::string& TopConfig::sgKeyKLFitterLoose(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systSgKeyMapKLFitterLoose->find(hash); if (key != m_systSgKeyMapKLFitterLoose->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string& TopConfig::sgKeyPseudoTop( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systSgKeyMapPseudoTop->find( hash ); + const std::string& TopConfig::sgKeyPseudoTop(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systSgKeyMapPseudoTop->find(hash); if (key != m_systSgKeyMapPseudoTop->end()) { return (*key).second; } return m_sgKeyDummy; } - const std::string & TopConfig::decoKeyJetGhostTrack(const std::size_t hash) const { - // If it's in the map, use the mapped value, otherwise use the nominal. - auto it = m_systDecoKeyMapJetGhostTrack->find(hash); - if (it != m_systDecoKeyMapJetGhostTrack->end()){ - return it->second; - } else { - return m_decoKeyJetGhostTrack; - } + const std::string& TopConfig::sgKeyPseudoTopLoose(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systSgKeyMapPseudoTopLoose->find(hash); + if (key != m_systSgKeyMapPseudoTopLoose->end()) { + return (*key).second; + } + return m_sgKeyDummy; } + const std::string& TopConfig::decoKeyJetGhostTrack(const std::size_t hash) const { + // If it's in the map, use the mapped value, otherwise use the nominal. + auto it = m_systDecoKeyMapJetGhostTrack->find(hash); - const std::string& TopConfig::systematicName( const std::size_t hash ) const - { - std::unordered_map<std::size_t,std::string>::const_iterator key = m_systPersistantAllTTreeNames - ->find( hash ); + if (it != m_systDecoKeyMapJetGhostTrack->end()) { + return it->second; + } else { + it = m_systDecoKeyMapJetGhostTrack->find(m_nominalHashValue); + if (it == m_systDecoKeyMapJetGhostTrack->end()) throw std::runtime_error( + "TopConfig: Failed to retrieve decoKeyJetGhostTrack."); + return it->second; + } + } + + const std::string& TopConfig::systematicName(const std::size_t hash) const { + std::unordered_map<std::size_t, std::string>::const_iterator key = m_systPersistantAllTTreeNames + ->find(hash); if (key != m_systPersistantAllTTreeNames->end()) { return (*key).second; } return m_sgKeyDummy; } - std::shared_ptr<std::unordered_map<std::size_t,std::string>> TopConfig::systSgKeyMapJets(const bool useLooseLeptonJets) const - { + std::shared_ptr<std::unordered_map<std::size_t, std::string> > TopConfig::systSgKeyMapJets( + const bool useLooseLeptonJets) const { if (m_applyElectronInJetSubtraction) { if (useLooseLeptonJets) { return m_systSgKeyMapJetsLoose_electronInJetSubtraction; @@ -2014,73 +3340,107 @@ namespace top{ } // TTree index - unsigned int TopConfig::ttreeIndex( const std::size_t hash ) const - { + unsigned int TopConfig::ttreeIndex(const std::size_t hash) const { unsigned int index(99999); // This will crash the job if not set properly - std::unordered_map<std::size_t,unsigned int>::const_iterator Itr = m_systAllTTreeIndex->find( hash ); + + std::unordered_map<std::size_t, unsigned int>::const_iterator Itr = m_systAllTTreeIndex->find(hash); if (Itr != m_systAllTTreeIndex->end()) { index = (*Itr).second; } if (index == 99999) { - std::cout<<"ttreeIndex is crazy, something has gone wrong with the hash value = "<<hash<<std::endl; + ATH_MSG_WARNING("ttreeIndex is crazy, something has gone wrong with the hash value = " << hash); } return index; } - unsigned int TopConfig::ttreeIndexLoose( const std::size_t hash ) const - { + unsigned int TopConfig::ttreeIndexLoose(const std::size_t hash) const { unsigned int index(99999); // This will crash the job if not set properly - std::unordered_map<std::size_t,unsigned int>::const_iterator Itr = m_systAllTTreeLooseIndex->find( hash ); + + std::unordered_map<std::size_t, unsigned int>::const_iterator Itr = m_systAllTTreeLooseIndex->find(hash); if (Itr != m_systAllTTreeLooseIndex->end()) { index = (*Itr).second; } if (index == 99999) { - std::cout<<"ttreeIndex is crazy, something has gone wrong with the hash value = "<<hash<<std::endl; + ATH_MSG_WARNING("ttreeIndex is crazy, something has gone wrong with the hash value = " << hash); } return index; } - const std::vector<std::string>& TopConfig::allTriggers(const std::string& selection) const - { - std::unordered_map<std::string,std::vector<std::string>>::const_iterator key = m_allTriggers->find( selection ); - if (key != m_allTriggers->end()) { + const std::vector<std::string>& TopConfig::allTriggers_Tight(const std::string& selection) const { + std::unordered_map<std::string, + std::vector<std::string> >::const_iterator key = m_allTriggers_Tight->find(selection); + if (key != m_allTriggers_Tight->end()) { + return (*key).second; + } + return m_dummyTrigger; + } + + const std::vector<std::string>& TopConfig::electronTriggers_Tight(const std::string& selection) const { + std::unordered_map<std::string, std::vector<std::string> >::const_iterator key = m_electronTriggers_Tight->find( + selection); + if (key != m_electronTriggers_Tight->end()) { + return (*key).second; + } + return m_dummyTrigger; + } + + const std::vector<std::string>& TopConfig::muonTriggers_Tight(const std::string& selection) const { + std::unordered_map<std::string, std::vector<std::string> >::const_iterator key = m_muonTriggers_Tight->find( + selection); + if (key != m_muonTriggers_Tight->end()) { + return (*key).second; + } + return m_dummyTrigger; + } + + const std::vector<std::string>& TopConfig::tauTriggers_Tight(const std::string& selection) const { + std::unordered_map<std::string, + std::vector<std::string> >::const_iterator key = m_tauTriggers_Tight->find(selection); + if (key != m_tauTriggers_Tight->end()) { return (*key).second; } return m_dummyTrigger; } - const std::vector<std::string>& TopConfig::electronTriggers(const std::string& selection) const - { - std::unordered_map<std::string,std::vector<std::string>>::const_iterator key = m_electronTriggers->find( selection ); - if (key != m_electronTriggers->end()) { + const std::vector<std::string>& TopConfig::allTriggers_Loose(const std::string& selection) const { + std::unordered_map<std::string, + std::vector<std::string> >::const_iterator key = m_allTriggers_Loose->find(selection); + if (key != m_allTriggers_Loose->end()) { return (*key).second; } return m_dummyTrigger; } - const std::vector<std::string>& TopConfig::muonTriggers(const std::string& selection) const - { - std::unordered_map<std::string,std::vector<std::string>>::const_iterator key = m_muonTriggers->find( selection ); - if (key != m_muonTriggers->end()) { + const std::vector<std::string>& TopConfig::electronTriggers_Loose(const std::string& selection) const { + std::unordered_map<std::string, std::vector<std::string> >::const_iterator key = m_electronTriggers_Loose->find( + selection); + if (key != m_electronTriggers_Loose->end()) { return (*key).second; } return m_dummyTrigger; } - const std::vector<std::string>& TopConfig::tauTriggers(const std::string& selection) const - { - std::unordered_map<std::string,std::vector<std::string>>::const_iterator key = m_tauTriggers->find( selection ); - if (key != m_tauTriggers->end()) { + const std::vector<std::string>& TopConfig::muonTriggers_Loose(const std::string& selection) const { + std::unordered_map<std::string, std::vector<std::string> >::const_iterator key = m_muonTriggers_Loose->find( + selection); + if (key != m_muonTriggers_Loose->end()) { return (*key).second; } return m_dummyTrigger; } + const std::vector<std::string>& TopConfig::tauTriggers_Loose(const std::string& selection) const { + std::unordered_map<std::string, + std::vector<std::string> >::const_iterator key = m_tauTriggers_Loose->find(selection); + if (key != m_tauTriggers_Loose->end()) { + return (*key).second; + } + return m_dummyTrigger; + } - ///-- top::TopPersistentSettings allows us to take a snapshot of top::TopConfig --/// + ///-- top::TopPersistentSettings allows us to take a snapshot of top::TopConfig --/// ///-- and save it to a mini-xAOD. We can then re-create the top::TopConfig from file --/// - top::TopPersistentSettings* TopConfig::createPersistentSettings() - { + top::TopPersistentSettings* TopConfig::createPersistentSettings() { top::TopPersistentSettings* out = new top::TopPersistentSettings(); out->m_isMC = m_isMC; @@ -2097,11 +3457,14 @@ namespace top{ out->m_sgKeyPrimaryVertices = m_sgKeyPrimaryVertices; out->m_sgKeyPhotons = m_sgKeyPhotons; out->m_sgKeyElectrons = m_sgKeyElectrons; + out->m_sgKeyFwdElectrons = m_sgKeyFwdElectrons; out->m_sgKeyMuons = m_sgKeyMuons; + out->m_sgKeySoftMuons = m_sgKeySoftMuons; out->m_sgKeyTaus = m_sgKeyTaus; out->m_sgKeyJets = m_sgKeyJets; out->m_sgKeyLargeRJets = m_sgKeyLargeRJets; out->m_sgKeyTrackJets = m_sgKeyTrackJets; + out->m_sgKeyTracks = m_sgKeyTracks; out->m_sgKeyMissingEt = m_sgKeyMissingEt; out->m_sgKeyMissingEtLoose = m_sgKeyMissingEtLoose; @@ -2109,6 +3472,11 @@ namespace top{ out->m_electronIDLoose = m_electronIDLoose; out->m_electronIsolation = m_electronIsolation; out->m_electronIsolationLoose = m_electronIsolationLoose; + out->m_useElectronChargeIDSelection = m_useElectronChargeIDSelection; + out->m_useEgammaLeakageCorrection = m_useEgammaLeakageCorrection; + out->m_enablePromptLeptonImprovedVetoStudies = m_enablePromptLeptonImprovedVetoStudies; + + out->m_fwdElectronID = m_fwdElectronID; out->m_muon_trigger_SF = m_muon_trigger_SF; out->m_muonQuality = m_muonQuality; @@ -2116,85 +3484,118 @@ namespace top{ out->m_muonIsolation = m_muonIsolation; out->m_muonIsolationLoose = m_muonIsolationLoose; - typedef std::unordered_map<std::size_t,std::string>::const_iterator Itr; + out->m_softmuonQuality = m_softmuonQuality; + + out->m_trackQuality = m_trackQuality; + + typedef std::unordered_map<std::size_t, std::string>::const_iterator Itr; + + for (std::vector<std::pair<std::string, std::string> >::const_iterator i = m_chosen_btaggingWP.begin(); + i != m_chosen_btaggingWP.end(); ++i) + out->m_chosen_btaggingWP.push_back(*i); - for (std::vector<std::string>::const_iterator i=m_chosen_btaggingWP.begin();i!=m_chosen_btaggingWP.end();++i) - out->m_chosen_btaggingWP.push_back( *i ); + for (Itr i = m_systSgKeyMapPhotons->begin(); i != m_systSgKeyMapPhotons->end(); ++i) + out->m_systSgKeyMapPhotons.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapPhotons->begin();i!=m_systSgKeyMapPhotons->end();++i) - out->m_systSgKeyMapPhotons.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapElectrons->begin(); i != m_systSgKeyMapElectrons->end(); ++i) + out->m_systSgKeyMapElectrons.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapElectrons->begin();i!=m_systSgKeyMapElectrons->end();++i) - out->m_systSgKeyMapElectrons.insert( std::make_pair( (*i).first , (*i).second ) ); + for (const auto& i : *(m_systSgKeyMapFwdElectrons)) + out->m_systSgKeyMapFwdElectrons.insert(std::make_pair(i.first, i.second)); - for (Itr i=m_systSgKeyMapMuons->begin();i!=m_systSgKeyMapMuons->end();++i) - out->m_systSgKeyMapMuons.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapMuons->begin(); i != m_systSgKeyMapMuons->end(); ++i) + out->m_systSgKeyMapMuons.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapTaus->begin();i!=m_systSgKeyMapTaus->end();++i) - out->m_systSgKeyMapTaus.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapSoftMuons->begin(); i != m_systSgKeyMapSoftMuons->end(); ++i) + out->m_systSgKeyMapSoftMuons.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapJets->begin();i!=m_systSgKeyMapJets->end();++i) - out->m_systSgKeyMapJets.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapTaus->begin(); i != m_systSgKeyMapTaus->end(); ++i) + out->m_systSgKeyMapTaus.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapJets_electronInJetSubtraction->begin();i!=m_systSgKeyMapJets_electronInJetSubtraction->end();++i) - out->m_systSgKeyMapJets_electronInJetSubtraction.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapJets->begin(); i != m_systSgKeyMapJets->end(); ++i) + out->m_systSgKeyMapJets.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapJetsLoose_electronInJetSubtraction->begin();i!=m_systSgKeyMapJetsLoose_electronInJetSubtraction->end();++i) - out->m_systSgKeyMapJetsLoose_electronInJetSubtraction.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapJets_electronInJetSubtraction->begin(); + i != m_systSgKeyMapJets_electronInJetSubtraction->end(); ++i) + out->m_systSgKeyMapJets_electronInJetSubtraction.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapLargeRJets->begin();i!=m_systSgKeyMapLargeRJets->end();++i) - out->m_systSgKeyMapLargeRJets.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapJetsLoose_electronInJetSubtraction->begin(); + i != m_systSgKeyMapJetsLoose_electronInJetSubtraction->end(); ++i) + out->m_systSgKeyMapJetsLoose_electronInJetSubtraction.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapTrackJets->begin();i!=m_systSgKeyMapTrackJets->end();++i) - out->m_systSgKeyMapTrackJets.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapLargeRJets->begin(); i != m_systSgKeyMapLargeRJets->end(); ++i) + out->m_systSgKeyMapLargeRJets.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapMissingET->begin();i!=m_systSgKeyMapMissingET->end();++i) - out->m_systSgKeyMapMissingET.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapTrackJets->begin(); i != m_systSgKeyMapTrackJets->end(); ++i) + out->m_systSgKeyMapTrackJets.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapMissingETLoose->begin();i!=m_systSgKeyMapMissingETLoose->end();++i) - out->m_systSgKeyMapMissingETLoose.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapTracks->begin(); i != m_systSgKeyMapTracks->end(); ++i) + out->m_systSgKeyMapTracks.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapKLFitter->begin();i!=m_systSgKeyMapKLFitter->end();++i) - out->m_systSgKeyMapKLFitter.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapMissingET->begin(); i != m_systSgKeyMapMissingET->end(); ++i) + out->m_systSgKeyMapMissingET.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapKLFitterLoose->begin();i!=m_systSgKeyMapKLFitterLoose->end();++i) - out->m_systSgKeyMapKLFitterLoose.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapMissingETLoose->begin(); i != m_systSgKeyMapMissingETLoose->end(); ++i) + out->m_systSgKeyMapMissingETLoose.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systSgKeyMapPseudoTop->begin();i!=m_systSgKeyMapPseudoTop->end();++i) - out->m_systSgKeyMapPseudoTop.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapKLFitter->begin(); i != m_systSgKeyMapKLFitter->end(); ++i) + out->m_systSgKeyMapKLFitter.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systDecoKeyMapJetGhostTrack->begin();i!=m_systDecoKeyMapJetGhostTrack->end();++i) - out->m_systDecoKeyMapJetGhostTrack.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapKLFitterLoose->begin(); i != m_systSgKeyMapKLFitterLoose->end(); ++i) + out->m_systSgKeyMapKLFitterLoose.insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=m_systPersistantAllTTreeNames->begin();i!=m_systPersistantAllTTreeNames->end();++i) - out->m_systPersistantAllTTreeNames.insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = m_systSgKeyMapPseudoTop->begin(); i != m_systSgKeyMapPseudoTop->end(); ++i) + out->m_systSgKeyMapPseudoTop.insert(std::make_pair((*i).first, (*i).second)); - for (std::list<std::size_t>::const_iterator i=m_list_systHashAll->begin();i!=m_list_systHashAll->end();++i) - out->m_list_systHashAll.push_back( *i ); + for (Itr i = m_systSgKeyMapPseudoTopLoose->begin(); i != m_systSgKeyMapPseudoTopLoose->end(); ++i) + out->m_systSgKeyMapPseudoTopLoose.insert(std::make_pair((*i).first, (*i).second)); - for (std::list<std::size_t>::const_iterator i=m_list_systHash_electronInJetSubtraction->begin();i!=m_list_systHash_electronInJetSubtraction->end();++i) - out->m_list_systHash_electronInJetSubtraction.push_back( *i ); + for (Itr i = m_systDecoKeyMapJetGhostTrack->begin(); i != m_systDecoKeyMapJetGhostTrack->end(); ++i) + out->m_systDecoKeyMapJetGhostTrack.insert(std::make_pair((*i).first, (*i).second)); - for (std::vector<std::string>::const_iterator i=m_allSelectionNames->begin();i!=m_allSelectionNames->end();++i) - out->m_allSelectionNames.push_back( *i ); + for (Itr i = m_systPersistantAllTTreeNames->begin(); i != m_systPersistantAllTTreeNames->end(); ++i) + out->m_systPersistantAllTTreeNames.insert(std::make_pair((*i).first, (*i).second)); - for (auto i : *m_allTriggers) { - out->m_allTriggers.insert(i); + for (std::list<std::size_t>::const_iterator i = m_list_systHashAll->begin(); i != m_list_systHashAll->end(); ++i) + out->m_list_systHashAll.push_back(*i); + + for (std::list<std::size_t>::const_iterator i = m_list_systHash_electronInJetSubtraction->begin(); + i != m_list_systHash_electronInJetSubtraction->end(); ++i) + out->m_list_systHash_electronInJetSubtraction.push_back(*i); + + for (std::vector<std::string>::const_iterator i = m_allSelectionNames->begin(); i != m_allSelectionNames->end(); + ++i) + out->m_allSelectionNames.push_back(*i); + + for (auto i : *m_allTriggers_Tight) { + out->m_allTriggers_Tight.insert(i); + } + for (auto i : *m_electronTriggers_Tight) { + out->m_electronTriggers_Tight.insert(i); + } + for (auto i : *m_muonTriggers_Tight) { + out->m_tauTriggers_Tight.insert(i); + } + + for (auto i : *m_allTriggers_Loose) { + out->m_allTriggers_Loose.insert(i); + } + for (auto i : *m_electronTriggers_Loose) { + out->m_electronTriggers_Loose.insert(i); } - for (auto i : *m_electronTriggers) { - out->m_electronTriggers.insert(i); + for (auto i : *m_muonTriggers_Loose) { + out->m_muonTriggers_Loose.insert(i); } - for (auto i : *m_muonTriggers) { - out->m_muonTriggers.insert(i); + for (auto i : *m_tauTriggers_Loose) { + out->m_tauTriggers_Loose.insert(i); } return out; } -TopConfig::TopConfig( const top::TopPersistentSettings* settings ) : + TopConfig::TopConfig(const top::TopPersistentSettings* settings) : // delegate to the default ctor - this is a nice C++11 feature, John likes this a lot - TopConfig() - { + TopConfig() { m_makeAllCPTools = false; m_isMC = settings->m_isMC; m_isAFII = settings->m_isAFII; @@ -2208,13 +3609,16 @@ TopConfig::TopConfig( const top::TopPersistentSettings* settings ) : m_sgKeyEventInfo = settings->m_sgKeyEventInfo; m_sgKeyPrimaryVertices = settings->m_sgKeyPrimaryVertices; - sgKeyPhotons( settings->m_sgKeyPhotons ); - sgKeyElectrons( settings->m_sgKeyElectrons ); - sgKeyMuons( settings->m_sgKeyMuons ); - sgKeyTaus( settings->m_sgKeyTaus ); - sgKeyJets( settings->m_sgKeyJets ); - sgKeyLargeRJets( settings->m_sgKeyLargeRJets ); - sgKeyTrackJets( settings->m_sgKeyTrackJets ); + sgKeyPhotons(settings->m_sgKeyPhotons); + sgKeyElectrons(settings->m_sgKeyElectrons); + sgKeyFwdElectrons(settings->m_sgKeyFwdElectrons); + sgKeyMuons(settings->m_sgKeyMuons); + sgKeySoftMuons(settings->m_sgKeySoftMuons); + sgKeyTaus(settings->m_sgKeyTaus); + sgKeyJets(settings->m_sgKeyJets); + sgKeyLargeRJets(settings->m_sgKeyLargeRJets); + sgKeyTrackJets(settings->m_sgKeyTrackJets); + sgKeyTracks(settings->m_sgKeyTracks); m_sgKeyMissingEt = settings->m_sgKeyMissingEt; m_sgKeyMissingEtLoose = settings->m_sgKeyMissingEtLoose; @@ -2222,170 +3626,336 @@ TopConfig::TopConfig( const top::TopPersistentSettings* settings ) : m_electronIDLoose = settings->m_electronIDLoose; m_electronIsolation = settings->m_electronIsolation; m_electronIsolationLoose = settings->m_electronIsolationLoose; + m_useElectronChargeIDSelection = settings->m_useElectronChargeIDSelection; + m_useEgammaLeakageCorrection = settings->m_useEgammaLeakageCorrection; + m_enablePromptLeptonImprovedVetoStudies = settings->m_enablePromptLeptonImprovedVetoStudies; + + m_fwdElectronID = settings->m_fwdElectronID; m_muon_trigger_SF = settings->m_muon_trigger_SF; m_muonQuality = settings->m_muonQuality; m_muonQualityLoose = settings->m_muonQualityLoose; m_muonIsolation = settings->m_muonIsolation; m_muonIsolationLoose = settings->m_muonIsolationLoose; - - for (std::vector<std::string>::const_iterator i=settings->m_chosen_btaggingWP.begin();i!=settings->m_chosen_btaggingWP.end();++i) - m_chosen_btaggingWP.push_back( *i ); - typedef std::map<std::size_t,std::string>::const_iterator Itr; + m_softmuonQuality = settings->m_softmuonQuality; + + for (std::vector<std::pair<std::string, std::string> >::const_iterator i = settings->m_chosen_btaggingWP.begin(); + i != settings->m_chosen_btaggingWP.end(); ++i) + m_chosen_btaggingWP.push_back(*i); + + typedef std::map<std::size_t, std::string>::const_iterator Itr; + + for (Itr i = settings->m_systSgKeyMapPhotons.begin(); i != settings->m_systSgKeyMapPhotons.end(); ++i) + m_systSgKeyMapPhotons->insert(std::make_pair((*i).first, (*i).second)); + + for (Itr i = settings->m_systSgKeyMapElectrons.begin(); i != settings->m_systSgKeyMapElectrons.end(); ++i) + m_systSgKeyMapElectrons->insert(std::make_pair((*i).first, (*i).second)); + + for (Itr i = settings->m_systSgKeyMapFwdElectrons.begin(); i != settings->m_systSgKeyMapFwdElectrons.end(); ++i) + m_systSgKeyMapFwdElectrons->insert(std::make_pair((*i).first, (*i).second)); + + for (Itr i = settings->m_systSgKeyMapMuons.begin(); i != settings->m_systSgKeyMapMuons.end(); ++i) + m_systSgKeyMapMuons->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapPhotons.begin();i!=settings->m_systSgKeyMapPhotons.end();++i) - m_systSgKeyMapPhotons->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapSoftMuons.begin(); i != settings->m_systSgKeyMapSoftMuons.end(); ++i) + m_systSgKeyMapSoftMuons->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapElectrons.begin();i!=settings->m_systSgKeyMapElectrons.end();++i) - m_systSgKeyMapElectrons->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapTaus.begin(); i != settings->m_systSgKeyMapTaus.end(); ++i) + m_systSgKeyMapTaus->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapMuons.begin();i!=settings->m_systSgKeyMapMuons.end();++i) - m_systSgKeyMapMuons->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapJets.begin(); i != settings->m_systSgKeyMapJets.end(); ++i) + m_systSgKeyMapJets->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapTaus.begin();i!=settings->m_systSgKeyMapTaus.end();++i) - m_systSgKeyMapTaus->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapJets_electronInJetSubtraction.begin(); + i != settings->m_systSgKeyMapJets_electronInJetSubtraction.end(); ++i) + m_systSgKeyMapJets_electronInJetSubtraction->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapJets.begin();i!=settings->m_systSgKeyMapJets.end();++i) - m_systSgKeyMapJets->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapJetsLoose_electronInJetSubtraction.begin(); + i != settings->m_systSgKeyMapJetsLoose_electronInJetSubtraction.end(); ++i) + m_systSgKeyMapJetsLoose_electronInJetSubtraction->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapJets_electronInJetSubtraction.begin();i!=settings->m_systSgKeyMapJets_electronInJetSubtraction.end();++i) - m_systSgKeyMapJets_electronInJetSubtraction->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapLargeRJets.begin(); i != settings->m_systSgKeyMapLargeRJets.end(); ++i) + m_systSgKeyMapLargeRJets->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapJetsLoose_electronInJetSubtraction.begin();i!=settings->m_systSgKeyMapJetsLoose_electronInJetSubtraction.end();++i) - m_systSgKeyMapJetsLoose_electronInJetSubtraction->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapTrackJets.begin(); i != settings->m_systSgKeyMapTrackJets.end(); ++i) + m_systSgKeyMapTrackJets->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapLargeRJets.begin();i!=settings->m_systSgKeyMapLargeRJets.end();++i) - m_systSgKeyMapLargeRJets->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapTracks.begin(); i != settings->m_systSgKeyMapTracks.end(); ++i) + m_systSgKeyMapTracks->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapTrackJets.begin();i!=settings->m_systSgKeyMapTrackJets.end();++i) - m_systSgKeyMapTrackJets->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapMissingET.begin(); i != settings->m_systSgKeyMapMissingET.end(); ++i) + m_systSgKeyMapMissingET->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapMissingET.begin();i!=settings->m_systSgKeyMapMissingET.end();++i) - m_systSgKeyMapMissingET->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapMissingETLoose.begin(); i != settings->m_systSgKeyMapMissingETLoose.end(); ++i) + m_systSgKeyMapMissingETLoose->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapMissingETLoose.begin();i!=settings->m_systSgKeyMapMissingETLoose.end();++i) - m_systSgKeyMapMissingETLoose->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapKLFitter.begin(); i != settings->m_systSgKeyMapKLFitter.end(); ++i) + m_systSgKeyMapKLFitter->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapKLFitter.begin();i!=settings->m_systSgKeyMapKLFitter.end();++i) - m_systSgKeyMapKLFitter->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapKLFitterLoose.begin(); i != settings->m_systSgKeyMapKLFitterLoose.end(); ++i) + m_systSgKeyMapKLFitterLoose->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapKLFitterLoose.begin();i!=settings->m_systSgKeyMapKLFitterLoose.end();++i) - m_systSgKeyMapKLFitterLoose->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapPseudoTop.begin(); i != settings->m_systSgKeyMapPseudoTop.end(); ++i) + m_systSgKeyMapPseudoTop->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systSgKeyMapPseudoTop.begin();i!=settings->m_systSgKeyMapPseudoTop.end();++i) - m_systSgKeyMapPseudoTop->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systSgKeyMapPseudoTopLoose.begin(); i != settings->m_systSgKeyMapPseudoTopLoose.end(); ++i) + m_systSgKeyMapPseudoTopLoose->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systDecoKeyMapJetGhostTrack.begin();i!=settings->m_systDecoKeyMapJetGhostTrack.end();++i) - m_systDecoKeyMapJetGhostTrack->insert( std::make_pair( (*i).first , (*i).second ) ); + for (Itr i = settings->m_systDecoKeyMapJetGhostTrack.begin(); i != settings->m_systDecoKeyMapJetGhostTrack.end(); + ++i) + m_systDecoKeyMapJetGhostTrack->insert(std::make_pair((*i).first, (*i).second)); - for (Itr i=settings->m_systPersistantAllTTreeNames.begin();i!=settings->m_systPersistantAllTTreeNames.end();++i) { - m_systPersistantAllTTreeNames->insert( std::make_pair( (*i).first , (*i).second ) ); - m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second)); + for (Itr i = settings->m_systPersistantAllTTreeNames.begin(); i != settings->m_systPersistantAllTTreeNames.end(); + ++i) { + m_systPersistantAllTTreeNames->insert(std::make_pair((*i).first, (*i).second)); + m_systAllTTreeNames->insert(std::make_pair((*i).first, (*i).second)); } - - for (std::vector<std::size_t>::const_iterator i=settings->m_list_systHashAll.begin();i!=settings->m_list_systHashAll.end();++i) - m_list_systHashAll->push_back( *i ); - for (std::vector<std::size_t>::const_iterator i=settings->m_list_systHash_electronInJetSubtraction.begin();i!=settings->m_list_systHash_electronInJetSubtraction.end();++i) - m_list_systHash_electronInJetSubtraction->push_back( *i ); + for (std::vector<std::size_t>::const_iterator i = settings->m_list_systHashAll.begin(); + i != settings->m_list_systHashAll.end(); ++i) + m_list_systHashAll->push_back(*i); - for (std::vector<std::string>::const_iterator i=settings->m_allSelectionNames.begin();i!=settings->m_allSelectionNames.end();++i) - m_allSelectionNames->push_back( *i ); + for (std::vector<std::size_t>::const_iterator i = settings->m_list_systHash_electronInJetSubtraction.begin(); + i != settings->m_list_systHash_electronInJetSubtraction.end(); ++i) + m_list_systHash_electronInJetSubtraction->push_back(*i); - m_allTriggers = std::make_shared<std::unordered_map<std::string, std::vector<std::string> >>(); - m_electronTriggers = std::make_shared<std::unordered_map<std::string, std::vector<std::string> >>(); - m_muonTriggers = std::make_shared<std::unordered_map<std::string, std::vector<std::string> >>(); - - for (auto i : settings->m_allTriggers) { - m_allTriggers->insert(i); + for (std::vector<std::string>::const_iterator i = settings->m_allSelectionNames.begin(); + i != settings->m_allSelectionNames.end(); ++i) + m_allSelectionNames->push_back(*i); + + m_allTriggers_Tight = std::make_shared<std::unordered_map<std::string, std::vector<std::string> > >(); + m_electronTriggers_Tight = std::make_shared<std::unordered_map<std::string, std::vector<std::string> > >(); + m_muonTriggers_Tight = std::make_shared<std::unordered_map<std::string, std::vector<std::string> > >(); + m_tauTriggers_Tight = std::make_shared<std::unordered_map<std::string, std::vector<std::string> > >(); + + m_allTriggers_Loose = std::make_shared<std::unordered_map<std::string, std::vector<std::string> > >(); + m_electronTriggers_Loose = std::make_shared<std::unordered_map<std::string, std::vector<std::string> > >(); + m_muonTriggers_Loose = std::make_shared<std::unordered_map<std::string, std::vector<std::string> > >(); + m_tauTriggers_Loose = std::make_shared<std::unordered_map<std::string, std::vector<std::string> > >(); + + for (auto i : settings->m_allTriggers_Tight) { + m_allTriggers_Tight->insert(i); + } + for (auto i : settings->m_electronTriggers_Tight) { + m_electronTriggers_Tight->insert(i); + } + for (auto i : settings->m_muonTriggers_Tight) { + m_muonTriggers_Tight->insert(i); + } + for (auto i : settings->m_tauTriggers_Tight) { + m_tauTriggers_Tight->insert(i); } - for (auto i : settings->m_electronTriggers) { - m_electronTriggers->insert(i); + + for (auto i : settings->m_allTriggers_Loose) { + m_allTriggers_Loose->insert(i); + } + for (auto i : settings->m_electronTriggers_Loose) { + m_electronTriggers_Loose->insert(i); } - for (auto i : settings->m_muonTriggers) { - m_muonTriggers->insert(i); + for (auto i : settings->m_muonTriggers_Loose) { + m_muonTriggers_Loose->insert(i); + } + for (auto i : settings->m_tauTriggers_Loose) { + m_tauTriggers_Loose->insert(i); } fixConfiguration(); } - - AodMetaDataAccess & TopConfig::aodMetaData() { + AodMetaDataAccess& TopConfig::aodMetaData() { return *m_aodMetaData; } // Place into a private function to allow use without replication of code - void TopConfig::ReadIsAFII(top::ConfigurationSettings* const& settings){ - if (settings->value("IsAFII") == "True") - this->setIsAFII(true); - else if (settings->value("IsAFII") == "False") - this->setIsAFII(false); - else if (settings->value("IsAFII") != " ") - throw std::runtime_error("TopConfig: option IsAFII must be either True or False"); - else if (this->isMC()) - throw std::runtime_error("TopConfig: option IsAFII not set"); + void TopConfig::ReadIsAFII(top::ConfigurationSettings* const& settings) { + if (settings->value("IsAFII") == "True") this->setIsAFII(true); + else if (settings->value("IsAFII") == "False") this->setIsAFII(false); + else if (settings->value("IsAFII") != " ") throw std::runtime_error( + "TopConfig: option IsAFII must be either True or False"); + else if (this->isMC()) throw std::runtime_error("TopConfig: option IsAFII not set"); } -} - -std::ostream& operator<<(std::ostream& os, const top::TopConfig& config) -{ - typedef std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> map_t; - typedef std::unordered_map<std::size_t,CP::SystematicSet>::const_iterator Itr; + // Function to set the release series (this method may change so refactor) + void TopConfig::setReleaseSeries() { + // Method taken from TopCPTools + std::string release_series = ""; + const char* rel_temp = std::getenv("ROOTCORE_RELEASE_SERIES"); + if (rel_temp) { + release_series = std::string(rel_temp); + } else { + release_series = ""; + } - if( config.useJetGhostTrack() ){ - for (const auto & item : config.systematicsJetGhostTrack()){ - os << " Jet Ghost Track Systematic\t\t :: " << item << " \n"; - } + if (release_series == "23") { + m_release_series = 23; // 2.3 + } else if (release_series == "24") { + m_release_series = 24; // 2.4 R20.7 + } else if (release_series == "25") { + m_release_series = 25; // 2.6 R21 + } else { + // Default to R21 because this build has moved away from ROOTCORE + m_release_series = 25; + } + return; } - os << "\n"; - os << "top::TopConfig will evaluate the following systematics (saved as TTrees in your ntuple) \n"; - os << "A blank systematic means \"Nominal\" in xAOD. All Nominal calibrations go into the Nominal TTree. \n"; - os << "\n"; - if( config.usePhotons() ){ - map_t syst = config.systMapPhotons(); - for(Itr i=syst->begin();i!=syst->end();++i){ - os << " Photon systematic\t :: " << (*i).second.name() <<" \n"; + void TopConfig::setAmiTag(std::string const& amiTag) { + assert(!m_configFixed); + if (m_amiTagSet == 0) { + m_amiTag = amiTag; + m_amiTagSet = 1; + } else if (m_amiTagSet > 0 && m_amiTag != amiTag) { + m_amiTag.clear(); + m_amiTagSet = -1; } } - if( config.useElectrons() ){ - map_t syst = config.systMapElectrons(); - for(Itr i=syst->begin();i!=syst->end();++i){ - os << " Electron systematic\t :: " << (*i).second.name() <<" \n"; - } + std::string const& TopConfig::getAmiTag() const { + assert(m_configFixed); + return m_amiTag; } - if( config.useMuons() ){ - map_t syst = config.systMapMuons(); - for(Itr i=syst->begin();i!=syst->end();++i){ - os << " Muon systematic\t :: " << (*i).second.name() <<" \n"; + // Function to return the year of data taking based on either run number (data) or random run number (MC) + std::string TopConfig::getYear(unsigned int runnumber, const bool isMC) { + + if (isMC) { + // mc16a - returning only 2015 but is really a mix of 15 + 16 + if (runnumber == 284500) return "2015"; + + // mc16d + if (runnumber == 300000) return "2017"; + + // mc16e + if (runnumber == 310000) return "2018"; + + return "UNKNOWN"; } + + // Set of runNumbers for data + // 2015 : 266904 - 284484 + if (runnumber >= 266904 && runnumber <= 284484) return "2015"; + + // 2016 : 296939 - 311481 + if (runnumber >= 296939 && runnumber <= 311481) return "2016"; + + // 2017 : 324320 - 348835 + if (runnumber >= 324320 && runnumber <= 348835) return "2017"; + + // 2018 : > 348835 + if (runnumber > 348835 && runnumber < 999999) return "2018"; + + return "UNKNOWN"; } - if( config.useTaus() ){ - map_t syst = config.systMapTaus(); - for(Itr i=syst->begin();i!=syst->end();++i){ - os << " Tau systematic\t :: " << (*i).second.name() <<" \n"; - } + void TopConfig::SetTriggersToYear(const bool isMC) { + if (m_year == "UNKNOWN") return; + + std::string year2(""); + if (isMC && m_year == "2015") year2 = "2016"; + if (isMC && m_year == "2016") year2 = "2015"; + + auto removeYears = [](std::unordered_map<std::string,std::vector<std::string> >& trig, const std::string& year1, const std::string& year2) { + auto itr = trig.begin(); + while (itr != trig.end()) { + if ((*itr).first != year1 && (*itr).first != year2) { + itr = trig.erase(itr); + } else { + itr++; + } + } + }; + + removeYears(m_trigGlobalConfiguration.trigger, m_year, year2); + removeYears(m_trigGlobalConfiguration.trigger_loose, m_year, year2); } - if( config.useJets() ){ - map_t syst = config.systMapJets(); - for(Itr i=syst->begin();i!=syst->end();++i){ - os << " Jet systematic\t\t :: " << (*i).second.name() <<" \n"; - } + void TopConfig::setGlobalTriggerConfiguration(std::vector<std::string> electron_trigger_systematics, + std::vector<std::string> muon_trigger_systematics, + std::vector<std::string> electron_tool_names, + std::vector<std::string> muon_tool_names) { + m_trigGlobalConfiguration.electron_trigger_systematics = electron_trigger_systematics; + m_trigGlobalConfiguration.muon_trigger_systematics = muon_trigger_systematics; + m_trigGlobalConfiguration.electron_trigger_tool_names = electron_tool_names; + m_trigGlobalConfiguration.muon_trigger_tool_names = muon_tool_names; + m_trigGlobalConfiguration.isConfigured = true; + return; } - if( config.useLargeRJets() ){ - map_t syst = config.systMapLargeRJets(); - for(Itr i=syst->begin();i!=syst->end();++i){ - os << " Large-R Jet systematic\t\t :: " << (*i).second.name() <<" \n"; + + + std::ostream& operator << (std::ostream& os, const TopConfig& config) { + typedef std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > map_t; + typedef std::unordered_map<std::size_t, CP::SystematicSet>::const_iterator Itr; + + if (config.useJetGhostTrack()) { + for (const auto& item : config.systematicsJetGhostTrack()) { + os << " Jet Ghost Track Systematic\t\t :: " << item << " \n"; + } + } + + os << "\n"; + os << "top::TopConfig has identified the following analysis release series : " << config.getReleaseSeries() << "\n"; + os << "top::TopConfig will evaluate the following systematics (saved as TTrees in your ntuple) \n"; + os << "A blank systematic means \"Nominal\" in xAOD. All Nominal calibrations go into the Nominal TTree. \n"; + os << "\n"; + if (config.usePhotons()) { + map_t syst = config.systMapPhotons(); + for (Itr i = syst->begin(); i != syst->end(); ++i) { + os << " Photon systematic\t :: " << (*i).second.name() << " \n"; + } + } + + if (config.useElectrons()) { + map_t syst = config.systMapElectrons(); + for (Itr i = syst->begin(); i != syst->end(); ++i) { + os << " Electron systematic\t :: " << (*i).second.name() << " \n"; + } + } + + if (config.useFwdElectrons()) { + map_t syst = config.systMapFwdElectrons(); + for (Itr i = syst->begin(); i != syst->end(); ++i) { + os << " Fwd Electron systematic\t :: " << (*i).second.name() << " \n"; + } } - } - os << "\n"; - return os; + if (config.useMuons()) { + map_t syst = config.systMapMuons(); + for (Itr i = syst->begin(); i != syst->end(); ++i) { + os << " Muon systematic\t :: " << (*i).second.name() << " \n"; + } + } + + if (config.useSoftMuons()) { + map_t syst = config.systMapSoftMuons(); + for (Itr i = syst->begin(); i != syst->end(); ++i) { + os << " Soft Muon systematic\t :: " << (*i).second.name() << " \n"; + } + } + + if (config.useTaus()) { + map_t syst = config.systMapTaus(); + for (Itr i = syst->begin(); i != syst->end(); ++i) { + os << " Tau systematic\t :: " << (*i).second.name() << " \n"; + } + } + + if (config.useJets()) { + map_t syst = config.systMapJets(); + for (Itr i = syst->begin(); i != syst->end(); ++i) { + os << " Jet systematic\t\t :: " << (*i).second.name() << " \n"; + } + } + + if (config.useLargeRJets()) { + map_t syst = config.systMapLargeRJets(); + for (Itr i = syst->begin(); i != syst->end(); ++i) { + os << " Large-R Jet systematic\t\t :: " << (*i).second.name() << " \n"; + } + } + + os << "\n"; + return os; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TopPersistentSettings.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TopPersistentSettings.cxx index 4b75df761232..47a4bdf30d04 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TopPersistentSettings.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TopPersistentSettings.cxx @@ -1,10 +1,10 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopConfiguration/TopPersistentSettings.h" -namespace top{ +namespace top { TopPersistentSettings::TopPersistentSettings() : m_isMC(false), m_isAFII(false), @@ -19,11 +19,14 @@ namespace top{ m_sgKeyPrimaryVertices("SetMe"), m_sgKeyPhotons("SetMe"), m_sgKeyElectrons("SetMe"), + m_sgKeyFwdElectrons("SetMe"), m_sgKeyMuons("SetMe"), + m_sgKeySoftMuons("SetMe"), m_sgKeyTaus("SetMe"), m_sgKeyJets("SetMe"), m_sgKeyLargeRJets("SetMe"), m_sgKeyTrackJets("SetMe"), + m_sgKeyTracks("SetMe"), m_sgKeyMissingEt("SetMe"), m_sgKeyMissingEtLoose("SetMe"), @@ -31,6 +34,11 @@ namespace top{ m_electronIDLoose("SetMe"), m_electronIsolation("SetMe"), m_electronIsolationLoose("SetMe"), + m_useElectronChargeIDSelection(false), + m_useEgammaLeakageCorrection(true), + m_enablePromptLeptonImprovedVetoStudies(false), + + m_fwdElectronID("SetMe"), m_muon_trigger_SF("SetMe"), m_muonQuality("SetMe"), @@ -38,11 +46,17 @@ namespace top{ m_muonIsolation("SetMe"), m_muonIsolationLoose("SetMe"), + m_softmuonQuality("SetMe"), + + m_trackQuality("SetMe"), + m_chosen_btaggingWP(), m_systSgKeyMapPhotons(), m_systSgKeyMapElectrons(), + m_systSgKeyMapFwdElectrons(), m_systSgKeyMapMuons(), + m_systSgKeyMapSoftMuons(), m_systSgKeyMapTaus(), m_systSgKeyMapJets(), m_systSgKeyMapJets_electronInJetSubtraction(), @@ -54,16 +68,22 @@ namespace top{ m_systSgKeyMapKLFitter(), m_systSgKeyMapKLFitterLoose(), m_systSgKeyMapPseudoTop(), + m_systSgKeyMapPseudoTopLoose(), m_systPersistantAllTTreeNames(), m_systDecoKeyMapJetGhostTrack(), + m_systSgKeyMapTracks(), m_list_systHashAll(), m_list_systHash_electronInJetSubtraction(), - m_allSelectionNames(), - m_allTriggers(), - m_electronTriggers(), - m_muonTriggers(), - m_tauTriggers() + m_allTriggers_Tight(), + m_electronTriggers_Tight(), + m_muonTriggers_Tight(), + m_tauTriggers_Tight(), + + m_allTriggers_Loose(), + m_electronTriggers_Loose(), + m_muonTriggers_Loose(), + m_tauTriggers_Loose() {} } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TreeFilter.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TreeFilter.cxx new file mode 100644 index 000000000000..3e08b7bd0739 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/TreeFilter.cxx @@ -0,0 +1,53 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopConfiguration/TreeFilter.h" +#include "TopConfiguration/Tokenize.h" + +#include <iostream> +#include <regex> +#include <sstream> + +namespace top { + + TreeFilter::TreeFilter(){} + + TreeFilter::TreeFilter(const std::string& longstring){ + init(longstring); + } + + void TreeFilter::init(const std::string& longstring){ + std::vector<std::string> helpvec_str; + tokenize(longstring, helpvec_str, ","); + + m_vecFilters.clear(); + for (const std::string& x : helpvec_str) { + std::istringstream isstr(x); + std::copy(std::istream_iterator<std::string>(isstr), + std::istream_iterator<std::string>(), std::back_inserter(m_vecFilters)); + } + + for (std::string& filter : m_vecFilters) { + // replace "*" with ".*" + filter = regex_replace(filter, std::regex("\\*"), ".*"); + } + + + } + + bool TreeFilter::filterTree(const std::string& treename) const{ + + for (const std::string& filter : m_vecFilters) { + // check for a match + std::smatch match; + std::regex_search(treename, match, std::regex("^"+filter)); + if (!match.empty()) return false; + } + + + return true; + } + + +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/AodMetaDataAccess.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/AodMetaDataAccess.h index d1607a65b30d..ac3e4a52ba93 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/AodMetaDataAccess.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/AodMetaDataAccess.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPCONFIGURATION_AODMETADATAACCESS_H #define TOPCONFIGURATION_AODMETADATAACCESS_H @@ -9,63 +9,62 @@ #include <string> namespace top { - -class AodMetaDataAccess { - -public: - - AodMetaDataAccess(); - virtual ~AodMetaDataAccess(); - virtual void loadWithFilesFrom(std::string const & fileListPath); - - /** - * @brief retrieve an AOD meta-data value - * - * @param folderName the folder name, e.g. "/TagInfo" - * @param keyName the key name, e.g. "project_name" - * - * @return the meta-data value as a string - */ - std::string get(std::string const & folderName, std::string const & keyName) const; - - /** - * @brief retrieve an AOD meta-data value - * - * @param folderName the folder name, e.g. "/TagInfo" - * @param keyName the key name, e.g. "project_name" - * - * @return the meta-data value as a string, or @p defaultValue if the meta-data entry does not exist - */ - std::string get(std::string const & folderName, std::string const & keyName, std::string const & defaultValue) const; - - /** - * @brief check whether AOD meta-data has been loaded - * - * @return whether the AOD meta-data has been loaded - */ - bool valid() const; - - /** - * @brief check whether the data are simulated or real - * - * @return true for MC, false for real data - */ - bool isSimulation() const; - - /** - * @brief check whether this sample is simulation, and then check if it was simulated with ATLFASTII - * - * @return true for AFII, false otherwise (FS or Data) - */ - bool isAFII() const; - - -private: - - std::map<std::string, std::map< std::string, std::string > > * m_data; - -}; - + class AodMetaDataAccess { + public: + AodMetaDataAccess(); + virtual ~AodMetaDataAccess(); + virtual void loadWithFilesFrom(std::string const& fileListPath); + + /** + * @brief retrieve an AOD meta-data value + * + * @param folderName the folder name, e.g. "/TagInfo" + * @param keyName the key name, e.g. "project_name" + * + * @return the meta-data value as a string + */ + std::string get(std::string const& folderName, std::string const& keyName) const; + + /** + * @brief retrieve an AOD meta-data value + * + * @param folderName the folder name, e.g. "/TagInfo" + * @param keyName the key name, e.g. "project_name" + * + * @return the meta-data value as a string, or @p defaultValue if the meta-data entry does not exist + */ + std::string get(std::string const& folderName, std::string const& keyName, std::string const& defaultValue) const; + + /** + * @brief check whether AOD meta-data has been loaded + * + * @return whether the AOD meta-data has been loaded + */ + bool valid() const; + + /** + * @brief check whether the data are simulated or real + * + * @return true for MC, false for real data + */ + bool isSimulation() const; + + /** + * @brief check whether the sample is MCoverlay or not + * + * @return true if it is overlay + */ + bool IsEventOverlayInputSim() const; + + /** + * @brief check whether this sample is simulation, and then check if it was simulated with ATLFASTII + * + * @return true for AFII, false otherwise (FS or Data) + */ + bool isAFII() const; + private: + std::map<std::string, std::map< std::string, std::string > >* m_data; + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/ConfigurationSettings.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/ConfigurationSettings.h index 26422ee55983..354cb5874935 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/ConfigurationSettings.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/ConfigurationSettings.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef CONFIGURATIONSETTINGS_H_ #define CONFIGURATIONSETTINGS_H_ @@ -13,14 +13,13 @@ #include "StringData.h" namespace top { - /** * @brief Hold the configuration information for the whole run. A singleton, * so only one of these exists. It needs populating with a call to loadFromFile * early on. Otherwise it'll be full of rubbish and will refuse to run properly */ -class ConfigurationSettings { -public: + class ConfigurationSettings { + public: /** * @brief Design patterns 101. A singleton getter function. */ @@ -41,11 +40,14 @@ public: * @param key The string key used to identify this variable. * @param value On success, the setting for the given key (output). * - * @return Indicates success (i.e. the value was not empty). - * * Note: an attempt to retrieve a key with a non-boolean values raises an exception. */ - bool retrieve(std::string const & key, bool & value) const; + void retrieve(std::string const& key, bool& value) const; + + /** + * same as above, but directly returning the boolean + */ + bool retrieve(std::string const& key) const; /** * @brief Have the configuration settings been read from a file? @@ -81,9 +83,15 @@ public: * @param name The key used to refer to this variable. * @param message A human readable explanation */ - void registerParameter(const std::string& name, const std::string& message, const std::string& default_val=""); + void registerParameter(const std::string& name, const std::string& message, const std::string& default_val = ""); -private: + /** + * @brief test whether an (experimental) feature should be enabled + * + * Note: It's not a particularly cheap operation, so avoid it in loops. + */ + bool feature(std::string const& name) const; + private: ///True if the class has read the settings from a file or something bool m_configured; @@ -91,11 +99,14 @@ private: static ConfigurationSettings* m_instance; ///Hold the configuration data - std::map<std::string, StringData> m_strings; + std::map<std::string, StringData> strings_; ///Data used when configuring the selections std::vector<SelectionConfigurationData> m_selections; + ///Kill-switch for experimental features + std::vector<std::string> m_killedFeatures; + ///private constructor ConfigurationSettings(); @@ -103,14 +114,12 @@ private: ConfigurationSettings(const ConfigurationSettings&); ///Here but not implemented, resulting in a happy compile error if you try and use them - ConfigurationSettings operator=(const ConfigurationSettings&); - -}; + ConfigurationSettings operator = (const ConfigurationSettings&); + }; + std::ostream& operator << (std::ostream& os, const ConfigurationSettings& settings); + std::ostream& operator << (std::ostream& os, const SelectionConfigurationData& data); } -std::ostream& operator<<(std::ostream& os, const top::ConfigurationSettings& settings); -std::ostream& operator<<(std::ostream& os, const top::SelectionConfigurationData& data); - #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/JsonUtils.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/JsonUtils.h new file mode 100644 index 000000000000..35b83cae193c --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/JsonUtils.h @@ -0,0 +1,85 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef _TOPCONFIGURATION_JSONUTILS_H_ +#define _TOPCONFIGURATION_JSONUTILS_H_ + +#include "AsgTools/Property.h" + +#include <boost/optional.hpp> + +#include <cmath> +#include <ios> +#include <memory> +#include <sstream> +#include <string> +#include <type_traits> +#include <utility> +#include <vector> + +class Property; + +namespace top { +/** @brief Convert boolean to JSON format. */ + template<typename T, typename std::enable_if< + std::is_same<typename std::remove_cv<T>::type, bool>::value + >::type* = nullptr> + std::string json_dump(T value) { + return(value ? "true" : "false"); + } + +/** @brief Convert number to JSON format. */ + template<typename T, typename std::enable_if< + std::is_integral<T>::value&& !std::is_same<typename std::remove_cv<T>::type, bool>::value + >::type* = nullptr> + std::string json_dump(T value) { + std::stringstream out; + out << value; + return out.str(); + } + +/** @brief Convert number to JSON format. */ + template<typename T, typename std::enable_if< + std::is_floating_point<T>::value + >::type* = nullptr> + std::string json_dump(T value) { + if (std::isfinite(value)) { + std::stringstream out; + out << value; + return out.str(); + } + return(std::isinf(value) ? (std::signbit(value) ? "-Infinity" : "Infinity") : "NaN"); + } + +/** @brief Escape string for use in JSON format. */ + std::string json_dump(std::string const& value); + + +/** + * @brief Convert values of Property instances to JSON. + */ + class PropertyValueJsonDumper { + public: + PropertyValueJsonDumper(); + ~PropertyValueJsonDumper(); + + /** + * @brief Convert the value of a property to JSON. + * + * @return The JSON representation of the value, or boost::none if no conversion is available. + */ + boost::optional<std::string> operator () (Property* prop) const; + + class ISpecializedDumper { + public: + virtual ~ISpecializedDumper(); + virtual std::string operator () (Property* prop) = 0; + }; + protected: + std::vector<std::pair<Property::Type, std::unique_ptr<ISpecializedDumper> > > m_dispatch; + }; +} + + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/MsgCategory.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/MsgCategory.h new file mode 100644 index 000000000000..f69ad0e98633 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/MsgCategory.h @@ -0,0 +1,11 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#ifndef _TOPCONFIGURATION_MSG_CATEGORY_H_ +#define _TOPCONFIGURATION_MSG_CATEGORY_H_ + +#include <AsgMessaging/MessageCheck.h> + +ANA_MSG_HEADER(TopConfiguration) + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/SelectionConfigurationData.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/SelectionConfigurationData.h index 93ab53bf74e0..62dfb1a26132 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/SelectionConfigurationData.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/SelectionConfigurationData.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SELECTIONCONFIGURATIONDATA_H_ #define SELECTIONCONFIGURATIONDATA_H_ @@ -9,21 +9,19 @@ #include <vector> namespace top { - /** * @brief Some configuration data to setup the selections. * * My understanding is that we'll only have a single stream of data next year, * so you might want to run ee, mumu and emu in the same job (i.e. selections). */ -struct SelectionConfigurationData { + struct SelectionConfigurationData { ///The name of the selection, e.g. ee std::string m_name; ///The cuts for this particular selection stored as strings, as read from the text file std::vector<std::string> m_cutnames; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/StringData.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/StringData.h index 117bbd9d525d..16752f14cc1e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/StringData.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/StringData.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef STRINGDATA_H_ #define STRINGDATA_H_ @@ -8,12 +8,11 @@ #include <string> namespace top { - /** * @brief A little helper to hold the data, a little information that's useful * to humans and a flag (true) if the settings has been set. */ -struct StringData { + struct StringData { ///The data set by the user std::string m_data; @@ -22,8 +21,7 @@ struct StringData { ///A flag that lets us know if the user has set something or not. bool m_set; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/Tokenize.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/Tokenize.h index 5561b0d1d620..9a98b74df09d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/Tokenize.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/Tokenize.h @@ -1,58 +1,49 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Filename: Tokenize.h -// Description: -// Author: Fabian Wilk -// Created: Tue Aug 11 10:12:30 2015 -// -// (c) by The ATLAS Collaboration -// (c) by Fabian Wilk <mail@fabianwilk.de> -// -// This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 -// International License. -// -// You should have received a copy of the license along with this work. -// If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef _UTILS_TOKENIZE_H_ #define _UTILS_TOKENIZE_H_ #include <string> -namespace top{ - /*! - * @brief Tokenize an input string using a set of delimiters. - * @tparam Container The type of the output container. - * @param input The input string which is to be tokenized. - * @param output The container onto which the tokens are to be appended. Must - * support an emplace_back function which takes as pointer to const char (the - * string data) and a std::size_t (the string length). - * - * For maximum performance use a non-allocating string in the out container, - * e.g. use `Container = std::vector<std::string_view>` in c++14. - */ - template <typename Container> - void tokenize(const std::string & input, Container & output, - const std::string & delimiters = " ", bool trim_empty = false) { - const auto size = input.size(); - std::string::size_type pos{0}; - std::string::size_type last_pos{0}; - - while (last_pos < size + 1) { - pos = input.find_first_of(delimiters, last_pos); - if (pos == std::string::npos) { - pos = size; - } - - if (pos != last_pos || not trim_empty){ - output.emplace_back(input.data() + last_pos, pos - last_pos); - } - - last_pos = pos + 1; - } +namespace top { + /*! + * @brief Tokenize an input string using a set of delimiters. + * @tparam Container The type of the output container. + * @param input The input string which is to be tokenized. + * @param output The container onto which the tokens are to be appended. Must + * support an emplace_back function which takes as pointer to const char (the + * string data) and a std::size_t (the string length). + * + * For maximum performance use a non-allocating string in the out container, + * e.g. use `Container = std::vector<std::string_view>` in c++14. + */ + template <typename Container> + void tokenize(const std::string& input, Container& output, + const std::string& delimiters = " ", bool trim_empty = false) { + const auto size = input.size(); + + std::string::size_type pos { + 0 + }; + std::string::size_type last_pos { + 0 + }; + + while (last_pos < size + 1) { + pos = input.find_first_of(delimiters, last_pos); + if (pos == std::string::npos) { + pos = size; + } + + if (pos != last_pos || not trim_empty) { + output.emplace_back(input.data() + last_pos, pos - last_pos); + } + + last_pos = pos + 1; } + } } #endif /* _UTILS_TOKENIZE_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TopConfig.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TopConfig.h index 10cdeaa9efac..e9eedb97962a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TopConfig.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TopConfig.h @@ -1,8 +1,7 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ -// $Id: TopConfig.h 803103 2017-04-18 17:30:51Z tpelzer $ #ifndef ANALYSISTOP_TOPCONFIGURATION_TOPCONFIG_H #define ANALYSISTOP_TOPCONFIGURATION_TOPCONFIG_H @@ -12,10 +11,6 @@ * @brief TopConfig * A simple configuration that is NOT a singleton * - * $Revision: 803103 $ - * $Date: 2017-04-18 19:30:51 +0200 (Tue, 18 Apr 2017) $ - * - * **/ // System include(s): @@ -27,1343 +22,2744 @@ #include <unordered_map> #include <unordered_set> #include <iostream> +#include <utility> // Systematic include(s): #include "PATInterfaces/SystematicSet.h" // Persistent settings #include "TopConfiguration/TopPersistentSettings.h" +// Tree Filter +#include "TopConfiguration/TreeFilter.h" + +#include "TopDataPreparation/SampleXsection.h" + +namespace top { + class AodMetaDataAccess; + class ConfigurationSettings; + + class TopConfig final { + public: + TopConfig(); + explicit TopConfig(const top::TopPersistentSettings* settings); + virtual ~TopConfig() {} + + // Delete Standard constructors + TopConfig(const TopConfig& rhs) = delete; + TopConfig(TopConfig&& rhs) = delete; + TopConfig& operator = (const TopConfig& rhs) = delete; + + // create settings to persist to mini-xAOD + top::TopPersistentSettings* createPersistentSettings(); + + void setConfigSettings(top::ConfigurationSettings* const& settings); + + // Prevent any more configuration + void fixConfiguration(); + + // Make all CP Tools? + inline bool makeAllCPTools() const {return m_makeAllCPTools;} + + // GRL file + void setGrlDir(const std::string& s); + inline const std::string& grlDir() const {return m_grlDir;} + void setGrlFile(const std::string& s); + inline const std::vector<std::string> grlFile() const {return m_grlFile;} + + // TDP path + void setTDPPath(const std::string& s); + inline const std::string& getTDPPath() const {return m_topDataPreparationPath;} + + //showering algorithm + void setShoweringAlgorithm(SampleXsection::showering in) { m_showeringAlgo=in; } + SampleXsection::showering getShoweringAlgorithm() const {return m_showeringAlgo;} + + inline bool recomputeCPvars() const {return m_recomputeCPvars;} + + // What objects are we using + inline bool usePhotons() const {return m_usePhotons;} + inline bool useElectrons() const {return m_useElectrons;} + inline bool useFwdElectrons() const {return m_useFwdElectrons;} + inline bool useMuons() const {return m_useMuons;} + inline bool useSoftMuons() const {return m_useSoftMuons;} + inline bool useTaus() const {return m_useTaus;} + inline bool useJets() const {return m_useJets;} + inline bool useLargeRJets() const {return m_useLargeRJets;} + inline bool useTrackJets() const {return m_useTrackJets;} + inline bool useTracks() const {return m_useTracks;} + inline bool useJetGhostTrack() const {return m_useJetGhostTrack;} + inline bool useRCJets() const {return m_useRCJets;} + inline bool useVarRCJets() const {return m_useVarRCJets;} + + inline bool useParticleFlowJets() const {return m_useParticleFlowJets;} + + inline bool useTruthParticles() const {return m_useTruthParticles;} + inline bool useTruthElectrons() const {return m_useTruthElectrons;} + inline bool useTruthMuons() const {return m_useTruthMuons;} + inline bool useTruthPhotons() const {return m_useTruthPhotons;} + inline bool useTruthJets() const {return m_useTruthJets;} + inline bool useTruthLargeRJets() const {return m_useTruthLargeRJets;} + inline bool useTruthTaus() const {return m_useTruthTaus;} + inline bool useTruthMET() const {return m_useTruthMET;} + + inline bool applyTTVACut() const {return m_applyTTVACut;} + + inline bool useAntiMuons() const {return m_useAntiMuons;}; + + // MC or not MC - this should be set by metadata + inline bool isMC() const {return m_isMC;} + inline void setIsMC(const bool value) { + if (!m_configFixed) { + m_isMC = value; + } + } -namespace top{ - -class AodMetaDataAccess; -class ConfigurationSettings; - -class TopConfig final { - public: - TopConfig(); - explicit TopConfig( const top::TopPersistentSettings* settings ); - virtual ~TopConfig(){} - - // Delete Standard constructors - TopConfig( const TopConfig& rhs ) = delete; - TopConfig( TopConfig&& rhs ) = delete; - TopConfig& operator=( const TopConfig& rhs ) = delete; - - // create settings to persist to mini-xAOD - top::TopPersistentSettings* createPersistentSettings(); - - void setConfigSettings( top::ConfigurationSettings* const& settings ); - - // Prevent any more configuration - void fixConfiguration(); - - // Make all CP Tools? - inline bool makeAllCPTools() const {return m_makeAllCPTools;} - - // GRL file - void setGrlDir( const std::string& s ); - inline const std::string& grlDir() const {return m_grlDir;} - void setGrlFile( const std::string& s ); - inline const std::vector<std::string> grlFile() const {return m_grlFile;} - - // What objects are we using - inline bool usePhotons() const {return m_usePhotons; } - inline bool useElectrons() const {return m_useElectrons; } - inline bool useMuons() const {return m_useMuons; } - inline bool useTaus() const {return m_useTaus; } - inline bool useJets() const {return m_useJets; } - inline bool useLargeRJets() const {return m_useLargeRJets;} - inline bool useTrackJets() const {return m_useTrackJets; } - inline bool useJetGhostTrack() const {return m_useJetGhostTrack; } - inline bool useRCJets() const {return m_useRCJets;} - inline bool useVarRCJets() const {return m_useVarRCJets;} - - inline bool useParticleFlowJets() const {return m_useParticleFlowJets;} - - inline bool useTruthParticles() const {return m_useTruthParticles;} - inline bool useTruthElectrons() const {return m_useTruthElectrons; } - inline bool useTruthMuons() const {return m_useTruthMuons; } - inline bool useTruthPhotons() const {return m_useTruthPhotons; } - inline bool useTruthJets() const {return m_useTruthJets; } - inline bool useTruthLargeRJets() const {return m_useTruthLargeRJets; } - inline bool useTruthMET() const {return m_useTruthMET; } - - inline bool applyTTVACut() const {return m_applyTTVACut; } - - inline bool useAntiMuons() const {return m_useAntiMuons; }; - - // MC or not MC - this should be set by metadata - inline bool isMC() const {return m_isMC;} - inline void setIsMC(const bool value) {if(!m_configFixed){m_isMC = value;}} - - // AFII? - inline bool isAFII() const {return m_isAFII;} - inline void setIsAFII(const bool value) {if(!m_configFixed){m_isAFII = value;}} - - // Is this a Primary xAOD? - inline bool isPrimaryxAOD() const {return m_isPrimaryxAOD;} - inline void setIsPrimaryxAOD(const bool value) {if(!m_configFixed){m_isPrimaryxAOD = value;}} - - // Is this a Truth DxAOD? - inline bool isTruthDxAOD() const {return m_isTruthDxAOD;} - inline void setIsTruthDxAOD(const bool value) {if(!m_configFixed){m_isTruthDxAOD = value;}} - - // What derivation type is it? - inline std::string getDerivationStream() const { return m_derivationStream;} - inline void setDerivationStream(const std::string value) {if(!m_configFixed){m_derivationStream = value;}} - - inline unsigned int getDSID() const {return m_DSID;} - inline void setDSID(unsigned int value) { - // Check here if this is a sherpa 2.2 V+jets sample - // (see below to set DSIDs) - setIsSherpa22Vjets(value); - m_DSID = value; - } - - // Is this Sherpa 2.2 V+jets? - // (if so then we need to reweight based on num truth jets) - inline bool isSherpa22Vjets() const {return m_is_sherpa_22_vjets;} - inline void setIsSherpa22Vjets(unsigned int dsid) { - // m_is_sherpa_22_vjets = false by default - // Sherpa 2.2 W+jets (from TopDataPrep) - if (dsid >= 363331 && dsid <= 363354) - m_is_sherpa_22_vjets = true; - if (dsid >= 363436 && dsid <= 363483) - m_is_sherpa_22_vjets = true; - // Sherpa 2.2 Z+jets (from TopDataPrep) - if (dsid >= 363102 && dsid <= 363122) - m_is_sherpa_22_vjets = true; - if (dsid >= 363361 && dsid <= 363435) - m_is_sherpa_22_vjets = true; - } - - // map index for MC/MC b-tagging scale factors - inline unsigned int getMapIndex() const {return m_MapIndex;} - inline void setMapIndex(unsigned int value) {m_MapIndex = value;} - - // Do Loose analysis for fakes - // For analysis this should only be run on data, not for MC - // By default you will get a Loose TTree for data and not for MC - inline bool doLooseEvents() const {return m_doLooseEvents;} - - // Do fakes MM weight calculation - inline bool doFakesMMWeights() const {return m_doFakesMMWeights;} - - // Directory of efficiency files for MM fake estimate - inline std::string FakesMMDir() const {return m_FakesMMDir;} - - // DDebug mode for MM fake estimate - inline bool FakesMMDebug() const {return m_doFakesMMDebug;} - - // Special mode to run Loose events on MC for the purposes - // of determining the Fakes control regions - // This is not for regular users, it is for the Fakes sub-group - // or for determining your own control regions - // - // If you are determining your own control regions, you have just joined - // the fakes sub-group, please report your finding in the Fakes meetings - // - // The function name is long and convoluted on purpose, I hope you don't call it by mistake - inline void FakesControlRegionDetermination_setDoLooseEventsOnMC_notForRegularUsers() - {if(!m_configFixed){m_doLooseEvents = true;}} - - // enables calculation of MM weights - // only possible for data loose - // doing it on MC loose is explicitly forbidden - inline void setFakesMMWeightsCalculation() - {m_doFakesMMWeights = true;} - inline void setFakesMMDir(const std::string dir) - {m_FakesMMDir = dir;} - inline void setFakesMMDebug() - {m_doFakesMMDebug = true;} - - // By default the top group does overlap removal on the tight lepton definitions - // If you use this you are going off piste and need to report - // your findings to the top reconstruction meeting - inline void setOverlapRemovalOnLooseLeptonDef() - {if(!m_configFixed){m_doOverlapRemovalOnLooseLeptonDef = true;}} - inline bool doOverlapRemovalOnLooseLeptonDef() const {return m_doOverlapRemovalOnLooseLeptonDef;} - - inline std::string overlapRemovalProcedure() const - {return m_overlap_removal_procedure;} - - // do overlap removal also with large-R jets - // (using whatever procedure is used in the official tools) - inline void setLargeJetOverlapRemoval() - {if(!m_configFixed){m_doLargeJetOverlapRemoval = true;}} - inline bool doLargeJetOverlapRemoval() const {return m_doLargeJetOverlapRemoval;} - - // Only dumps the *_Loose trees - also on MC - // Usefull if you want your tight selection to be a subset of loose - inline void setLooseTreeOnly() - {if(!m_configFixed){m_doLooseTreeOnly = true;}} - inline bool doLooseTreeOnly() const {return m_doLooseTreeOnly;} - - // In the *_Loose trees, lepton SFs are calculated considering - // tight ID and isolation instead of loose - // Only tight leptons are considered in the event SF calculation - inline void setApplyTightSFsInLooseTree() - {if(!m_configFixed){m_applyTightSFsInLooseTree = true;}} - inline bool applyTightSFsInLooseTree() const {return m_applyTightSFsInLooseTree;} - - // Apply Electron In Jet subtraction - // For boosted analysis - inline bool applyElectronInJetSubtraction() const {return m_applyElectronInJetSubtraction;} - inline void setApplyElectronInJetSubtraction() - {if(!m_configFixed){m_applyElectronInJetSubtraction = true;}} - - // Dump truth block info - inline bool doTruthBlockInfo() const {return m_doTruthBlockInfo;} - inline void setTruthBlockInfo() - {if(!m_configFixed){m_doTruthBlockInfo = true;}} - - // Write truth PDF info - inline bool doTruthPDFInfo() const {return m_doTruthPDFInfo;} - inline void setTruthPDFInfo() - {if(!m_configFixed){m_doTruthPDFInfo = true;}} - // Write truth PDF info in reco tree - inline bool doTruthPDFInfoInNominalTrees() const {return m_doTruthPDFInfoInNominalTrees;} - inline void setTruthPDFInfoInNominalTrees() - {if(!m_configFixed){m_doTruthPDFInfoInNominalTrees = true;}} - - // Write MC generator weights - inline bool doMCGeneratorWeights() const {return m_doMCGeneratorWeights;} - inline void setMCGeneratorWeights() - {if(!m_configFixed){m_doMCGeneratorWeights = true;}} - // Write truth PDF info in reco tree - inline bool doMCGeneratorWeightsInNominalTrees() const {return m_doMCGeneratorWeightsInNominalTrees;} - inline void setMCGeneratorWeightsInNominalTrees() - {if(!m_configFixed){m_doMCGeneratorWeightsInNominalTrees = true;}} - - // Top Parton History - inline bool doTopPartonHistory() const {return m_doTopPartonHistory;} - inline void setTopPartonHistory() - {if(!m_configFixed){m_doTopPartonHistory = true;}} - - // Register Top Parton History in flat ntuple - // This doesn't use m_configFixed - this is bad :( - // This is a simple implementation of saving xAOD objects to ntuples - // John has more advanced ideas on how to do this - // This is just a quick fix for now to get the concept working - inline bool isTopPartonHistoryRegisteredInNtuple() const {return m_isTopPartonHistoryRegisteredInNtuple;} - inline void setTopPartonHistoryRegisteredInNtuple() - {m_isTopPartonHistoryRegisteredInNtuple = true;} - - // TopParticleLevel - inline bool doTopParticleLevel() const { return m_doTopParticleLevel; } - inline void setTopParticleLevel() { if ( ! m_configFixed ){ m_doTopParticleLevel = true; } } - - inline bool doParticleLevelOverlapRemovalMuJet() const { return m_doParticleLevelOverlapRemovalMuJet; } - inline bool doParticleLevelOverlapRemovalElJet() const { return m_doParticleLevelOverlapRemovalElJet; } - inline bool doParticleLevelOverlapRemovalJetPhoton() const { return m_doParticleLevelOverlapRemovalJetPhoton; } - inline void setParticleLevelOverlapRemovalMuJet( bool value ) { if ( ! m_configFixed ){ m_doParticleLevelOverlapRemovalMuJet = value; } } - inline void setParticleLevelOverlapRemovalElJet( bool value ) { if ( ! m_configFixed ){ m_doParticleLevelOverlapRemovalElJet = value; } } - inline void setParticleLevelOverlapRemovalJetPhoton( bool value ) { if ( ! m_configFixed ){ m_doParticleLevelOverlapRemovalJetPhoton = value; } } - - // KLFitter - inline bool doKLFitter() const {return m_doKLFitter;} - inline void setKLFitter(){if(!m_configFixed){m_doKLFitter = true;}} - inline const std::string& KLFitterTransferFunctionsPath() const {return m_KLFitterTransferFunctionsPath;} - inline const std::string& KLFitterJetSelectionMode() const {return m_KLFitterJetSelectionMode;} - inline const std::string& KLFitterBTaggingMethod() const {return m_KLFitterBTaggingMethod;} - inline const std::string& KLFitterLH() const {return m_KLFitterLH;} - - inline bool KLFitterTopMassFixed() const {return m_KLFitterTopMassFixed;} - inline bool KLFitterSaveAllPermutations() const {return m_KLFitterSaveAllPermutations;} - - // PseudoTop - inline bool doPseudoTop() const {return m_doPseudoTop;} - inline void setPseudoTop(){if(!m_configFixed){m_doPseudoTop = true;}} - - // Triggers - inline virtual void allTriggers(std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> triggers) - {if(!m_configFixed){m_allTriggers = triggers;}} - - inline virtual void electronTriggers(std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> triggers) - {if(!m_configFixed){m_electronTriggers = triggers;}} - - inline virtual void muonTriggers(std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> triggers) - {if(!m_configFixed){m_muonTriggers = triggers;}} - - inline virtual void tauTriggers(std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> triggers) - {if(!m_configFixed){m_tauTriggers = triggers;}} - - inline std::shared_ptr<std::vector<std::string>> allSelectionNames() const {return m_allSelectionNames;} - virtual const std::vector<std::string>& allTriggers(const std::string& selection) const; - virtual const std::vector<std::string>& electronTriggers(const std::string& selection) const; - virtual const std::vector<std::string>& muonTriggers(const std::string& selection) const; - virtual const std::vector<std::string>& tauTriggers(const std::string& selection) const; - - // StoreGate Keys - virtual void sgKeyMCParticle ( const std::string& s ); - virtual void sgKeyPhotons ( const std::string& s ); - virtual void sgKeyElectrons ( const std::string& s ); - virtual void sgKeyMuons ( const std::string& s ); - virtual void sgKeyTaus ( const std::string& s ); - virtual void sgKeyJets ( const std::string& s ); - virtual void sgKeyLargeRJets ( const std::string& s ); - virtual void sgKeyTrackJets ( const std::string& s ); - - virtual void sgKeyTruthElectrons ( const std::string& s ); - virtual void sgKeyTruthMuons ( const std::string& s ); - virtual void sgKeyTruthPhotons ( const std::string& s ); - virtual void sgKeyTruthMET ( const std::string& s ); - virtual void sgKeyTruthJets ( const std::string& s ); - virtual void sgKeyTruthLargeRJets ( const std::string& s ); - - inline virtual void sgKeyMissingEt ( const std::string& s ){if(!m_configFixed){m_sgKeyMissingEt = s; }} - inline virtual void sgKeyMissingEtLoose ( const std::string& s ){if(!m_configFixed){m_sgKeyMissingEtLoose = s; }} - - inline const std::string& sgKeyEventInfo() const {return m_sgKeyEventInfo; } - inline const std::string& sgKeyPrimaryVertices() const {return m_sgKeyPrimaryVertices;} - inline virtual const std::string& sgKeyPhotons() const {return m_sgKeyPhotons; } - inline virtual const std::string& sgKeyElectrons() const {return m_sgKeyElectrons; } - inline virtual const std::string& sgKeyMuons() const {return m_sgKeyMuons; } - inline virtual const std::string& sgKeyTaus() const {return m_sgKeyTaus; } - inline virtual const std::string& sgKeyJets() const {return m_sgKeyJets; } - inline virtual const std::string& sgKeyLargeRJets() const {return m_sgKeyLargeRJets;} - inline virtual const std::string& sgKeyTrackJets() const {return m_sgKeyTrackJets; } - inline virtual const std::string& sgKeyMissingEt() const {return m_sgKeyMissingEt; } - inline virtual const std::string& sgKeyMissingEtLoose() const {return m_sgKeyMissingEtLoose; } - inline const std::string& sgKeyInDetTrackParticles() const {return m_sgKeyInDetTrackParticles;} - - inline const std::string& sgKeyTruthEvent() const {return m_sgKeyTruthEvent;} - inline virtual const std::string& sgKeyMCParticle() const {return m_sgKeyMCParticle;} - inline const std::string& sgKeyTruthPhotons() const {return m_sgKeyTruthPhotons;} - inline const std::string& sgKeyTruthElectrons() const {return m_sgKeyTruthElectrons;} - inline const std::string& sgKeyTruthMuons() const {return m_sgKeyTruthMuons;} - inline const std::string& sgKeyTruthTaus() const {return m_sgKeyTruthTaus;} - inline virtual const std::string& sgKeyTruthJets() const {return m_sgKeyTruthJets;} - inline virtual const std::string& sgKeyTruthLargeRJets() const {return m_sgKeyTruthLargeRJets;} - inline const std::string& sgKeyTruthMET() const {return m_sgKeyTruthMET;} - inline const std::string& sgKeyTopPartonHistory() const {return m_sgKeyTopPartonHistory;} - - inline const std::string& sgKeyTopSystematicEvents() const {return m_sgKeyTopSystematicEvents;} - inline const std::string& sgKeyTopSystematicEventsLoose() const {return m_sgKeyTopSystematicEventsLoose;} - inline const std::string& passEventSelectionDecoration() const {return m_passEventSelectionDecoration;} - virtual void decoKeyJetGhostTrack(const std::string & key); - inline virtual const std::string & decoKeyJetGhostTrack() const {return m_decoKeyJetGhostTrack;} - virtual void runPeriodJetGhostTrack(const std::vector<std::uint32_t> & vect); - - virtual const std::string& sgKeyPhotons ( const std::size_t hash ) const; - virtual const std::string& sgKeyElectrons ( const std::size_t hash ) const; - virtual const std::string& sgKeyElectronsStandAlone ( const std::size_t hash ) const; - virtual const std::string& sgKeyMuons ( const std::size_t hash ) const; - virtual const std::string& sgKeyTaus - ( const std::size_t hash ) const; - virtual const std::string& sgKeyJets ( const std::size_t hash , const bool useLooseLeptonJets ) const; - virtual const std::string& sgKeyJetsStandAlone ( const std::size_t hash ) const; - virtual const std::string& sgKeyLargeRJets( const std::size_t hash ) const; - virtual const std::string& sgKeyTrackJets ( const std::size_t hash ) const; - virtual const std::string& sgKeyMissingEt ( const std::size_t hash ) const; - virtual const std::string& sgKeyMissingEtLoose ( const std::size_t hash ) const; - - // For top::TopEventMaker - const std::string& sgKeyPhotonsTDS( const std::size_t hash ) const; - const std::string& sgKeyPhotonsTDSAux( const std::size_t hash ) const; - const std::string& sgKeyElectronsTDS( const std::size_t hash ) const; - const std::string& sgKeyElectronsTDSAux( const std::size_t hash ) const; - const std::string& sgKeyMuonsTDS( const std::size_t hash ) const; - const std::string& sgKeyMuonsTDSAux( const std::size_t hash ) const; - const std::string& sgKeyTausTDS( const std::size_t hash ) const; - const std::string& sgKeyTausTDSAux( const std::size_t hash ) const; - const std::string& sgKeyJetsTDS( const std::size_t hash , const bool useLooseLeptonJets ) const; - const std::string& sgKeyJetsTDSAux( const std::size_t hash , const bool useLooseLeptonJets ) const; - const std::string& sgKeyLargeRJetsTDS( const std::size_t hash ) const; - const std::string& sgKeyLargeRJetsTDSAux( const std::size_t hash ) const; - const std::string& sgKeyTrackJetsTDS( const std::size_t hash ) const; - const std::string& sgKeyTrackJetsTDSAux( const std::size_t hash ) const; - - // KLFitter - const std::string& sgKeyKLFitter( const std::size_t hash ) const; - const std::string& sgKeyKLFitterLoose( const std::size_t hash ) const; - - // PseudoTop - const std::string& sgKeyPseudoTop( const std::size_t hash ) const; - const std::string& sgKeyPseudoTop( const std::string ) const; - - // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - // Jet Ghost-Track Systematics - - // The jet decoration name for a given systematic (nominal also possible). - const std::string & decoKeyJetGhostTrack(const std::size_t hash) const; - - // Retrieve names of all (registered) systematics that affect ghost tracks. - const std::vector<std::string> & systematicsJetGhostTrack() const {return m_jetGhostTrackSystematics;} - - // Retrieve run periods for ghost tracks. - const std::vector<std::uint32_t> & runPeriodsJetGhostTrack() const {return m_jetGhostTrackRunPeriods;} - - // Retrieve mapping from systematic hash to CP::SystematicSet. - inline std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> systMapJetGhostTrack() const {return m_systMapJetGhostTrack; } - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - - // special: allow to dump the systematics-shifted b-tagging SFs in the systematics trees - inline virtual void dumpBtagSystsInSystTrees( const bool& b ){if(!m_configFixed){m_dumpBtagSystsInSystTrees = b;}} - inline virtual const bool& dumpBtagSystsInSystTrees(){return m_dumpBtagSystsInSystTrees;} - - // Electron configuration - inline virtual void egammaSystematicModel( const std::string& s ){if(!m_configFixed){m_egammaSystematicModel = s;}} - inline virtual void electronID( const std::string& s ){if(!m_configFixed){m_electronID = s;}} - inline virtual void electronIDLoose( const std::string& s ){if(!m_configFixed){m_electronIDLoose = s;}} - inline void removeElectronVetoLArCrack() {if(!m_configFixed){m_electronVetoLArCrack = false;}} - inline virtual void electronVetoLArCrack( const bool b ){if(!m_configFixed){m_electronVetoLArCrack = b;}} - inline virtual void electronPtcut(const float pt) {if(!m_configFixed){m_electronPtcut = pt;}} - inline virtual void electronIsolation(const std::string& iso) {if(!m_configFixed){m_electronIsolation = iso;}} - inline virtual void electronIsolationLoose(const std::string& iso) {if(!m_configFixed){m_electronIsolationLoose = iso;}} - inline virtual void electronIsoSFs(const bool b){if(!m_configFixed){m_electronIsoSFs = b;}} - - inline virtual const std::string& egammaSystematicModel(){return m_egammaSystematicModel;} - inline virtual const std::string& electronID() const {return m_electronID; } - inline virtual const std::string& electronIDLoose() const {return m_electronIDLoose;} - inline virtual bool electronVetoLArCrack() const {return m_electronVetoLArCrack;} - inline virtual float electronPtcut() const {return m_electronPtcut;} - inline virtual const std::string& electronIsolation() const {return m_electronIsolation;} - inline virtual const std::string& electronIsolationLoose() const {return m_electronIsolationLoose;} - inline virtual bool electronIsoSFs() const {return m_electronIsoSFs;} - inline const std::string& electronIDDecoration() const {return m_electronIDDecoration;} - inline const std::string& electronIDLooseDecoration() const {return m_electronIDLooseDecoration;} - - // Photon configuration - inline virtual void photonPtcut(const float pt) {if(!m_configFixed){m_photon_configuration.pt = pt;}} - inline virtual void photonEtacut(const float eta) {if(!m_configFixed){m_photon_configuration.eta = eta;}} - inline virtual void photonIdentification(const std::string& quality) {if(!m_configFixed){m_photon_configuration.identification = quality;}} - inline virtual void photonIdentificationLoose(const std::string& quality) {if(!m_configFixed){m_photon_configuration_loose.identification = quality;}} - inline virtual void photonIsolation(const std::string& quality) {if(!m_configFixed){m_photon_configuration.isolation = quality;}} - inline virtual void photonIsolationLoose(const std::string& quality) {if(!m_configFixed){m_photon_configuration_loose.isolation = quality;}} - inline virtual void photonUseRadiativeZ(const bool b) {if(!m_configFixed){m_photon_configuration.useRadiativeZ = b;}} - - // Muon configuration - inline virtual void muonPtcut(const float pt) {if(!m_configFixed){m_muonPtcut = pt;}} - inline virtual void muonEtacut(const float eta) {if(!m_configFixed){m_muonEtacut = eta;}} - inline virtual void muonQuality(const std::string& quality) {if(!m_configFixed){m_muonQuality = quality;}} - inline virtual void muonQualityLoose(const std::string& quality) {if(!m_configFixed){m_muonQualityLoose = quality;}} - inline virtual void muonIsolation(const std::string& iso) {if(!m_configFixed){m_muonIsolation = iso;}} - inline virtual void muonIsolationLoose(const std::string& iso) {if(!m_configFixed){m_muonIsolationLoose = iso;}} - - inline virtual float muonPtcut() const {return m_muonPtcut;} - inline virtual float muonEtacut() const {return m_muonEtacut;} - inline virtual const std::string& muonQuality() const {return m_muonQuality;} - inline virtual const std::string& muonQualityLoose() const {return m_muonQualityLoose;} - inline virtual const std::string& muonIsolation() const {return m_muonIsolation;} - inline virtual const std::string& muonIsolationLoose() const {return m_muonIsolationLoose;} - - // Jet configuration - inline virtual void jetPtcut(const float pt) {if(!m_configFixed){m_jetPtcut = pt;}} - inline virtual void jetEtacut(const float eta) {if(!m_configFixed){m_jetEtacut = eta;}} - inline virtual void fwdJetAndMET(const std::string& fwd) {if(!m_configFixed){m_fwdJetAndMET = fwd;}} - - inline virtual float jetPtcut() const {return m_jetPtcut;} - inline virtual float jetEtacut() const {return m_jetEtacut;} - inline virtual const std::string& fwdJetAndMET() const {return m_fwdJetAndMET;} - - inline virtual void largeRJetPtcut(const float pt) {if(!m_configFixed){m_largeRJetPtcut = pt;}} - inline virtual void largeRJetEtacut(const float eta) {if(!m_configFixed){m_largeRJetEtacut = eta;}} - inline virtual void largeRJESUncertaintyConfig(const std::string& largeR_config) {if(!m_configFixed){m_largeRJESUncertaintyConfig = largeR_config;}} - inline virtual void largeRJESJMSConfig(const std::string& largeR_config) {if(!m_configFixed){m_largeRJESJMSConfig = largeR_config;}} - inline virtual float largeRJetPtcut() const {return m_largeRJetPtcut;} - inline virtual float largeRJetEtacut() const {return m_largeRJetEtacut;} - inline virtual const std::string& largeRJESUncertaintyConfig() const {return m_largeRJESUncertaintyConfig;} - inline virtual const std::string& largeRJESJMSConfig() const {return m_largeRJESJMSConfig;} - - inline virtual void trackJetPtcut(const float pt) {if(!m_configFixed){m_trackJetPtcut = pt;}} - inline virtual void trackJetEtacut(const float eta) {if(!m_configFixed){m_trackJetEtacut = eta;}} - inline virtual float trackJetPtcut() const {return m_trackJetPtcut;} - inline virtual float trackJetEtacut() const {return m_trackJetEtacut;} - - inline virtual float RCJetPtcut() const {return m_RCJetPtcut;} - inline virtual float RCJetEtacut() const {return m_RCJetEtacut;} - inline virtual float RCJetTrimcut() const {return m_RCJetTrimcut;} - inline virtual float RCJetRadius() const {return m_RCJetRadius;} - - inline virtual void RCJetPtcut(const float pt) {if(!m_configFixed){m_RCJetPtcut = pt;}} - inline virtual void RCJetEtacut(const float eta) {if(!m_configFixed){m_RCJetEtacut = eta;}} - inline virtual void RCJetTrimcut(const float trim) {if(!m_configFixed){m_RCJetTrimcut = trim;}} - inline virtual void RCJetRadius(const float radius) {if(!m_configFixed){m_RCJetRadius = radius;}} - - inline virtual float VarRCJetPtcut() const{return m_VarRCJetPtcut;} - inline virtual float VarRCJetEtacut() const {return m_VarRCJetEtacut;} - inline virtual float VarRCJetTrimcut() const {return m_VarRCJetTrimcut;} - inline virtual float VarRCJetMaxRadius() const {return m_VarRCJetMaxRadius;} - inline virtual const std::string& VarRCJetRho() const {return m_VarRCJetRho;} - inline virtual const std::string& VarRCJetMassScale() const {return m_VarRCJetMassScale;} - - inline virtual void VarRCJetPtcut(const float pt) {if(!m_configFixed){m_VarRCJetPtcut = pt;}} - inline virtual void VarRCJetEtacut(const float eta) {if(!m_configFixed){m_VarRCJetEtacut = eta;}} - inline virtual void VarRCJetTrimcut(const float trim) {if(!m_configFixed){m_VarRCJetTrimcut = trim;}} - inline virtual void VarRCJetMaxRadius(const float radius) {if(!m_configFixed){m_VarRCJetMaxRadius = radius;}} - inline virtual void VarRCJetRho(const std::string& rho) {if(!m_configFixed){m_VarRCJetRho = rho;}} - inline virtual void VarRCJetMassScale(const std::string& mass_scale) {if(!m_configFixed){m_VarRCJetMassScale = mass_scale;}} - - inline virtual void jetUncertainties_BunchSpacing( const std::string& s ){if(!m_configFixed){m_jetUncertainties_BunchSpacing = s;}} - inline virtual const std::string& jetUncertainties_BunchSpacing() const {return m_jetUncertainties_BunchSpacing;} - - virtual void jetUncertainties_NPModel( const std::string& s ); - inline bool doMultipleJES() const {return m_doMultipleJES;} - inline bool doLargeRSmallRCorrelations() const {return m_largeRSmallRCorrelations;} - inline virtual const std::string& jetUncertainties_NPModel() const {return m_jetUncertainties_NPModel;} - - inline virtual void jetJERSmearingModel( const std::string& s ){if(!m_configFixed){m_jetJERSmearingModel = s;}} - inline virtual const std::string& jetJERSmearingModel() const {return m_jetJERSmearingModel;} - - inline virtual void jetCalibSequence( const std::string& s ){if(!m_configFixed){m_jetCalibSequence = s;}} - inline virtual const std::string& jetCalibSequence() const {return m_jetCalibSequence;} - - inline virtual void doJVTinMET( const bool& doJVT ){if(!m_configFixed){m_doJVTInMETCalculation = doJVT;}} - inline virtual bool doJVTinMET() const {return m_doJVTInMETCalculation;} - - inline virtual float JSF() const{return m_JSF;} - inline virtual float bJSF() const{return m_bJSF;} - - // Tau configuration setters - inline virtual void tauPtcut(const float pt) { - if(!m_configFixed) { - m_tau_configuration.pt = pt; - m_tau_configuration_loose.pt = pt; - } - } - inline virtual void tauJetIDWP(const std::string& s) { - if(!m_configFixed) - m_tau_configuration.jetIDWP = s; - } - inline virtual void tauJetIDWPLoose(const std::string& s) { - if(!m_configFixed) - m_tau_configuration_loose.jetIDWP = s; - } - inline virtual void tauEleBDTWP(const std::string& s) { - if(!m_configFixed) - m_tau_configuration.eleBDTWP = s; - } - inline virtual void tauEleBDTWPLoose(const std::string& s) { - if(!m_configFixed) - m_tau_configuration_loose.eleBDTWP = s; - } - inline virtual void tauEleOLR(bool do_tau_ele_olr) { - if(!m_configFixed) - m_tau_configuration.eleOLR = do_tau_ele_olr; - } - inline virtual void tauEleOLRLoose(bool do_tau_ele_olr) { - if(!m_configFixed) - m_tau_configuration_loose.eleOLR = do_tau_ele_olr; - } - inline virtual void tauJetConfigFile(const std::string& s) { - if(!m_configFixed) - m_tau_configuration.fileName = s; - } - inline virtual void tauJetConfigFileLoose(const std::string& s) { - if(!m_configFixed) - m_tau_configuration_loose.fileName = s; - } - // Applying new tau energy calibration - inline virtual void applyTauMVATES(bool apply) { - m_applyTauMVATES = apply; - } - - // Tau configuration getters - inline virtual float tauPtcut() const { - return m_tau_configuration.pt; - } - inline const std::string& tauJetIDWP() const { - return m_tau_configuration.jetIDWP; - } - inline const std::string& tauJetIDWPLoose() const { - return m_tau_configuration_loose.jetIDWP; - } - inline const std::string& tauEleBDTWP() const { - return m_tau_configuration.eleBDTWP; - } - inline const std::string& tauEleBDTWPLoose() const { - return m_tau_configuration_loose.eleBDTWP; - } - inline virtual bool tauEleOLR() { - return m_tau_configuration.eleOLR; - } - inline virtual bool tauEleOLRLoose() { - return m_tau_configuration_loose.eleOLR; - } - inline const std::string& tauJetConfigFile() { - return m_tau_configuration.fileName; - } - inline const std::string& tauJetConfigFileLoose() { - return m_tau_configuration_loose.fileName; - } - // Applying new tau energy calibration - inline bool applyTauMVATES() { - return m_applyTauMVATES; - } - - // photon getters - inline virtual float photonPtcut() const { - return m_photon_configuration.pt; - } - inline virtual float photonEtacut() const { - return m_photon_configuration.eta; - } - inline const std::string& photonIdentification() { - return m_photon_configuration.identification; - } - inline const std::string& photonIdentificationLoose() { - return m_photon_configuration_loose.identification; - } - inline const std::string& photonIsolation() { - return m_photon_configuration.isolation; - } - inline const std::string& photonIsolationLoose() { - return m_photon_configuration_loose.isolation; - } - inline const bool& photonUseRadiativeZ() { - return m_photon_configuration.useRadiativeZ; - } - - // inline const std::string& tauJetID() const {return m_tauJetID;} - // inline const std::string& tauJetIDBkg() const {return m_tauJetIDBkg;} - // inline const std::string& tauEVetoID() const {return m_tauEVetoID;} - // inline virtual bool tauVetoLArCrack() const {return m_tauVetoLArCrack;} - // inline virtual float tauPtcut() const {return m_tauPtcut;} - - // [[[----------------------------------------------- - // Particle Level (Truth) configuration - - // electrons - inline virtual void truth_electron_PtCut( const float pt ) { if ( ! m_configFixed ){ m_truth_electron.PtCut = pt; } } - inline virtual void truth_electron_EtaCut( const float eta ) { if ( ! m_configFixed ){ m_truth_electron.EtaCut = eta; } } - - inline virtual float truth_electron_PtCut() const { return m_truth_electron.PtCut; } - inline virtual float truth_electron_EtaCut() const { return m_truth_electron.EtaCut; } - inline virtual bool truth_electron_NotFromHadron() const { return m_truth_electron.NotFromHadron; } - inline virtual bool truth_electron_TauIsHadron() const { return m_truth_electron.TauIsHadron; } - - // muons - inline virtual void truth_muon_PtCut( const float pt ) { if ( ! m_configFixed ){ m_truth_muon.PtCut = pt; } } - inline virtual void truth_muon_EtaCut( const float eta ) { if ( ! m_configFixed ){ m_truth_muon.EtaCut = eta; } } - - inline virtual float truth_muon_PtCut() const { return m_truth_muon.PtCut; } - inline virtual float truth_muon_EtaCut() const { return m_truth_muon.EtaCut; } - inline virtual bool truth_muon_NotFromHadron() const { return m_truth_muon.NotFromHadron; } - inline virtual bool truth_muon_TauIsHadron() const { return m_truth_muon.TauIsHadron; } - - // photons - inline virtual void truth_photon_PtCut( const float pt ) { if ( ! m_configFixed ){ m_truth_photon.PtCut = pt; } } - inline virtual void truth_photon_EtaCut( const float eta ) { if ( ! m_configFixed ){ m_truth_photon.EtaCut = eta; } } - inline virtual void truth_photon_Origin(const std::string & value) { if ( ! m_configFixed ){ m_truth_photon.Origin = value; } } - inline virtual void truth_photon_Isolation(const std::string & value) { if ( ! m_configFixed ){ m_truth_photon.Isolation = value; } } - - inline virtual float truth_photon_PtCut() const { return m_truth_photon.PtCut; } - inline virtual float truth_photon_EtaCut() const { return m_truth_photon.EtaCut; } - inline virtual const std::string & truth_photon_Origin() const { return m_truth_photon.Origin; } - inline virtual const std::string & truth_photon_Isolation() const { return m_truth_photon.Isolation; } - - // jets - inline virtual void truth_jet_PtCut( const float pt ) { if ( ! m_configFixed ){ m_truth_jet.PtCut = pt; } } - inline virtual void truth_jet_EtaCut( const float eta ) { if ( ! m_configFixed ){ m_truth_jet.EtaCut = eta; } } - - inline virtual float truth_jet_PtCut() const { return m_truth_jet.PtCut; } - inline virtual float truth_jet_EtaCut() const { return m_truth_jet.EtaCut; } - - // large R jets - inline virtual void truth_jet_largeR_PtCut( const float pt ) { if ( ! m_configFixed ){ m_truth_largeRJet.PtCut = pt; } } - inline virtual void truth_jet_largeR_EtaCut( const float eta ) { if ( ! m_configFixed ){ m_truth_largeRJet.EtaCut = eta; } } - - inline virtual float truth_jet_largeR_PtCut() const { return m_truth_largeRJet.PtCut; } - inline virtual float truth_jet_largeR_EtaCut() const { return m_truth_largeRJet.EtaCut; } - - // -----------------------------------------------]]] - - /// HL LHC studies - inline virtual void HLLHC(const bool s) { if(!m_configFixed){m_HLLHC=s;} } - inline virtual bool HLLHC() const {return m_HLLHC;} - - void setBTaggingSFSysts( std::string WP, const std::set<std::string>& btagging_SFs, bool isTrackJet=false ); - - inline virtual std::set<std::string> btagging_namedSysts(std::string WP) const { return m_bTag_named_systs.at(WP); } - inline virtual unsigned int btagging_num_B_eigenvars(std::string WP) const { return m_bTag_eigen_B.at(WP); } - inline virtual unsigned int btagging_num_C_eigenvars(std::string WP) const { return m_bTag_eigen_C.at(WP); } - inline virtual unsigned int btagging_num_Light_eigenvars(std::string WP) const { return m_bTag_eigen_light.at(WP); } - - inline virtual std::set<std::string> trkjet_btagging_namedSysts(std::string WP) const { return m_bTag_named_systs_trkJet.at(WP); } - inline virtual unsigned int trkjet_btagging_num_B_eigenvars(std::string WP) const { return m_bTag_eigen_B_trkJet.at(WP); } - inline virtual unsigned int trkjet_btagging_num_C_eigenvars(std::string WP) const { return m_bTag_eigen_C_trkJet.at(WP); } - inline virtual unsigned int trkjet_btagging_num_Light_eigenvars(std::string WP) const { return m_bTag_eigen_light_trkJet.at(WP); } - - // B-tagging WPs requested by user - const std::vector<std::string> bTagWP() const { return m_chosen_btaggingWP;} - // B-tagging systematics requested by user to be excluded from EV treatment, separated by semi-colons - const std::string bTagSystsExcludedFromEV() const { return m_bTagSystsExcludedFromEV;} - - // B-tagging WPs actually available, according to CDI file - // will be set in TopCPTools - void setBTagWP_available( std::string btagging_WP ); - void setBTagWP_available_trkJet( std::string btagging_WP ); - const std::vector<std::string>& bTagWP_available() const { return m_available_btaggingWP;} - const std::vector<std::string>& bTagWP_available_trkJet() const { return m_available_btaggingWP_trkJet;} - // B-tagging WPs actually calibrated, according to CDI file - // will be set in TopCPTools - void setBTagWP_calibrated( std::string btagging_WP ); - void setBTagWP_calibrated_trkJet( std::string btagging_WP ); - const std::vector<std::string>& bTagWP_calibrated() const { return m_calibrated_btaggingWP;} - const std::vector<std::string>& bTagWP_calibrated_trkJet() const { return m_calibrated_btaggingWP_trkJet;} - - std::string FormatedWP(std::string raw_WP); - - const std::string& bTaggingCalibration_B() const - {return m_btagging_calibration_B;}; - const std::string& bTaggingCalibration_C() const - {return m_btagging_calibration_C;}; - const std::string& bTaggingCalibration_Light() const - {return m_btagging_calibration_Light;}; - - // LHAPDF settings - - inline virtual std::vector<std::string> LHAPDFSets(){ return m_lhapdf_options.pdf_set_names; } - inline virtual bool doLHAPDF(){ return m_lhapdf_options.doLHAPDF; } - inline virtual std::string baseLHAPDF() { return m_lhapdf_options.baseLHAPDF; } - inline virtual bool doLHAPDFInNominalTrees(){ return m_lhapdf_options.doLHAPDFInNominalTrees; } - inline virtual bool saveLHAPDFEvent(){ return m_lhapdf_options.save_per_event; } - void addLHAPDFResult( const std::string& pdf_name, - std::vector<float> sum_of_weights ); - - std::unordered_map<std::string, std::vector<float> >& getLHAPDFResults() { return m_lhapdf_options.pdf_results; }; - - - // Pileup Reweighting Settings - bool doPileupReweighting(){ return m_pileup_reweighting.apply;}; - bool PileupUseGRLTool(){ return m_pileup_reweighting.use_grl_tool;}; - - const std::vector<std::string>& PileupConfig(){ return m_pileup_reweighting.config_files; }; - const std::vector<std::string>& PileupLumiCalc(){ return m_pileup_reweighting.lumi_calc_files; }; - - bool PileupMuDependent(){return m_pileup_reweighting.mu_dependent;}; - - inline const std::string& muonTriggerSF() const {return m_muon_trigger_SF;} - - // Where the sum of event weights - // before derivation framework is kept - inline const std::string& sumOfEventWeightsMetaData() const {return m_sumOfEventWeightsMetaData; } - - // Object Selector Name - inline virtual void objectSelectionName(const std::string& s){if(!m_configFixed){m_objectSelectionName = s;}} - inline virtual const std::string& objectSelectionName() const {return m_objectSelectionName;} - // Output Format - inline virtual void outputFormat(const std::string& s){if(!m_configFixed){m_outputFormat = s;}} - inline virtual const std::string& outputFormat() const {return m_outputFormat;} - // Output Events - virtual void outputEvents(const std::string& s); - inline virtual const std::string& outputEvents() const {return m_outputEvents;} - inline bool saveOnlySelectedEvents() const {return m_saveOnlySelectedEvents;} - - // SetAutoFlush(0) on EventSaverFlatNtuple for ANALYSISTO-44 workaround - inline bool outputFileSetAutoFlushZero() const {return m_outputFileSetAutoFlushZero;} - - // Number of events to run on (only for testing) - inline virtual unsigned int numberOfEventsToRun() const { return m_numberOfEventsToRun;} - inline virtual void numberOfEventsToRun(const unsigned int& n_events) {if(!m_configFixed){m_numberOfEventsToRun = n_events;}} - - // Number of events to skip (only for testing) - inline virtual unsigned int numberOfEventsToSkip() const { return m_numberOfEventsToSkip;} - inline virtual void numberOfEventsToSkip(const unsigned int& n_events) {if(!m_configFixed){m_numberOfEventsToSkip = n_events;}} - - // systematics - inline virtual void systematics(const std::string& s) {if(!m_configFixed){m_systematics = s;}} - inline virtual const std::string& systematics() const {return m_systematics;} - - /// syst helper functions - bool isSystNominal(const std::string& syst) const; - bool isSystAll(const std::string& syst) const; - bool getSystematicsList(const std::string& syst, std::set<std::string>& systList) const; - bool contains(const std::set<std::string>& systList, const std::string& name) const; - - virtual void systematicsPhotons ( const std::list<CP::SystematicSet>& syst ); - virtual void systematicsElectrons ( const std::list<CP::SystematicSet>& syst ); - virtual void systematicsMuons ( const std::list<CP::SystematicSet>& syst ); - virtual void systematicsTaus ( const std::list<CP::SystematicSet>& syst ); - virtual void systematicsJets ( const std::list<CP::SystematicSet>& syst ); - virtual void systematicsLargeRJets ( const std::list<CP::SystematicSet>& syst ); - virtual void systematicsTrackJets ( const std::list<CP::SystematicSet>& syst ); - virtual void systematicsMET ( const std::list<CP::SystematicSet>& syst ); - - virtual void systematicsJetGhostTrack ( const std::list<CP::SystematicSet>& syst ); - - inline virtual void jetSubstructureName(const std::string &s) {if(!m_configFixed){ m_jetSubstructureName = s;} } - inline virtual const std::string& jetSubstructureName() const {return m_jetSubstructureName;} - - // Systematic hash values - inline std::size_t nominalHashValue() const {return m_nominalHashValue;} - inline std::shared_ptr<std::unordered_set<std::size_t>> systHashPhotons() const {return m_systHashPhotons; } - inline std::shared_ptr<std::unordered_set<std::size_t>> systHashElectrons() const {return m_systHashElectrons;} - inline std::shared_ptr<std::unordered_set<std::size_t>> systHashMuons() const {return m_systHashMuons; } - inline std::shared_ptr<std::unordered_set<std::size_t>> systHashTaus() const {return m_systHashTaus; } - inline std::shared_ptr<std::unordered_set<std::size_t>> systHashJets() const {return m_systHashJets; } - inline std::shared_ptr<std::unordered_set<std::size_t>> systHashAll() const {return m_systHashAll; } - inline std::shared_ptr<std::unordered_set<std::size_t>> systHashElectronInJetSubtraction() const {return m_systHash_electronInJetSubtraction;} - - // Systematic Maps - inline std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> systMapPhotons() const {return m_systMapPhotons; } - inline std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> systMapElectrons() const {return m_systMapElectrons;} - inline std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> systMapMuons() const {return m_systMapMuons; } - inline std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> systMapTaus() const {return m_systMapTaus; } - inline std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> systMapJets() const {return m_systMapJets; } - inline std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> systMapLargeRJets() const {return m_systMapLargeRJets; } - - // Systematic StoreGate key Maps - inline std::shared_ptr<std::unordered_map<std::size_t,std::string>> systSgKeyMapPhotons() const {return m_systSgKeyMapPhotons; } - inline std::shared_ptr<std::unordered_map<std::size_t,std::string>> systSgKeyMapElectrons() const {return m_systSgKeyMapElectrons; } - inline std::shared_ptr<std::unordered_map<std::size_t,std::string>> systSgKeyMapMuons() const {return m_systSgKeyMapMuons; } - inline std::shared_ptr<std::unordered_map<std::size_t,std::string>> systSgKeyMapTaus() const {return m_systSgKeyMapTaus; } - std::shared_ptr<std::unordered_map<std::size_t,std::string>> systSgKeyMapJets(const bool useLooseLeptonJets) const; - inline std::shared_ptr<std::unordered_map<std::size_t,std::string>> systSgKeyMapLargeRJets() const {return m_systSgKeyMapLargeRJets;} - inline std::shared_ptr<std::unordered_map<std::size_t,std::string>> systSgKeyMapTrackJets() const {return m_systSgKeyMapTrackJets;} - - // TTree names - inline std::shared_ptr<std::unordered_map<std::size_t,std::string>> systAllTTreeNames() const {return m_systAllTTreeNames;} - const std::string& systematicName( const std::size_t hash ) const; - // TTree index - unsigned int ttreeIndex( const std::size_t hash ) const; - unsigned int ttreeIndexLoose( const std::size_t hash ) const; - - AodMetaDataAccess & aodMetaData(); - AodMetaDataAccess const & aodMetaData() const { return *m_aodMetaData; } - - private: - // Prevent any more configuration - bool m_configFixed; - - // Make all CP Tools, or just the SF - bool m_makeAllCPTools; - - // GRL file - std::string m_grlDir; - std::vector<std::string> m_grlFile = {}; - - // Use which objects - bool m_usePhotons; - bool m_useElectrons; - bool m_useMuons; - bool m_useAntiMuons; - bool m_useTaus; - bool m_useJets; - bool m_useLargeRJets; - bool m_useTrackJets; - bool m_useRCJets; - bool m_useVarRCJets; - - // Ghost Tracks on jets can not really be disabled because they are always - // available. However, we want the systematics to be executed automatically - // whenever the user has "configured" ghost tracks. - bool m_useJetGhostTrack; - - // Are we using particle flow jets - // Need this as some things aren't supported at the moment - // C++11 so nice inline initialization (we should make this consistent) - bool m_useParticleFlowJets = false; - - bool m_useTruthParticles; - bool m_useTruthElectrons; - bool m_useTruthMuons; - bool m_useTruthPhotons; - bool m_useTruthJets; - bool m_useTruthLargeRJets; - bool m_useTruthMET; - - // define if d0/z0 cut should be used at all - bool m_applyTTVACut; - - std::string m_jetSubstructureName; - - // Do systematics? - this needs many more configuration options - std::string m_systematics; - std::string m_nominalSystName; - std::string m_allSystName; - - unsigned int m_DSID; - unsigned int m_MapIndex; - bool m_is_sherpa_22_vjets = false; - - bool m_isMC; - bool m_isAFII; - bool m_isPrimaryxAOD; - bool m_isTruthDxAOD = false; - std::string m_derivationStream; - - // Do loose events? - default for data, MC is special case - bool m_doLooseEvents; - - // Do fakes MM weights calculation? - only for data loose - bool m_doFakesMMWeights; - // Directory of efficiency files for MM fake estimate - std::string m_FakesMMDir; - // Debug mode? - bool m_doFakesMMDebug; - - // By default the top group does overlap removal on - // the tight lepton definitions. - // If you turn this to true you are going off piste and need to report - // your findings to the top reconstruction meeting. - bool m_doOverlapRemovalOnLooseLeptonDef; - - // String to describe which overlap removal procedure is used - // Current options are whether to use the ASG recommended - // overlap removal (recommended) - // procedure, or the one developed by the harmonization - // task force and use throughout 2015 (harmonized) - std::string m_overlap_removal_procedure = "recommended"; - - // do overlap removal also with large-R jets - // (using whatever procedure is used in the official tools) - bool m_doLargeJetOverlapRemoval; - - // Only dumps the *_Loose trees - also on MC - // Usefull if you want your tight selection to be a subset of loose - bool m_doLooseTreeOnly; - - // In the *_Loose trees, lepton SFs are calculated considering - // tight ID and isolation instead of loose - // Only tight leptons are considered in the event SF calculation - bool m_applyTightSFsInLooseTree; - - // Apply Electron In Jet subtraction - // For boosted analysis - bool m_applyElectronInJetSubtraction; - - // Write Truth block info - bool m_doTruthBlockInfo; - - // Write Truth PDF info - bool m_doTruthPDFInfo; - bool m_doTruthPDFInfoInNominalTrees; - - // Write MC generator weights - bool m_doMCGeneratorWeights; - bool m_doMCGeneratorWeightsInNominalTrees; - - // Top Parton History - bool m_doTopPartonHistory; - bool m_isTopPartonHistoryRegisteredInNtuple; - - // Top Particle Level - bool m_doTopParticleLevel; - bool m_doParticleLevelOverlapRemovalMuJet; - bool m_doParticleLevelOverlapRemovalElJet; - bool m_doParticleLevelOverlapRemovalJetPhoton; - - // KLFitter - bool m_doKLFitter; - std::string m_KLFitterTransferFunctionsPath; - std::string m_KLFitterJetSelectionMode; - std::string m_KLFitterBTaggingMethod; - std::string m_KLFitterLH; - bool m_KLFitterTopMassFixed; - bool m_KLFitterSaveAllPermutations; - - // PseudoTop - bool m_doPseudoTop; - - // StoreGate / TStore keys - std::string m_sgKeyDummy; - std::string m_sgKeyEventInfo; - std::string m_sgKeyPrimaryVertices; - std::string m_sgKeyPhotons; - std::string m_sgKeyElectrons; - std::string m_sgKeyMuons; - std::string m_sgKeyTaus; - std::string m_sgKeyJets; - std::string m_sgKeyLargeRJets; - std::string m_sgKeyTrackJets; - std::string m_sgKeyMissingEt; - std::string m_sgKeyMissingEtLoose; - std::string m_sgKeyInDetTrackParticles; - - std::string m_sgKeyTruthEvent; - std::string m_sgKeyMCParticle; - std::string m_sgKeyTruthPhotons; - std::string m_sgKeyTruthElectrons; - std::string m_sgKeyTruthMuons; - std::string m_sgKeyTruthTaus; - std::string m_sgKeyTruthJets; - std::string m_sgKeyTruthLargeRJets; - std::string m_sgKeyTruthMET; - std::string m_sgKeyTopPartonHistory; - - std::string m_sgKeyTopSystematicEvents; - std::string m_sgKeyTopSystematicEventsLoose; - std::string m_passEventSelectionDecoration; - - std::string m_decoKeyJetGhostTrack; - std::vector<std::string> m_jetGhostTrackSystematics; - std::vector<std::uint32_t> m_jetGhostTrackRunPeriods; - - // special: allow to dump the systematics-shifted b-tagging SFs in the systematics trees - bool m_dumpBtagSystsInSystTrees; - - // Electron configuration - std::string m_egammaSystematicModel; - std::string m_electronID; - std::string m_electronIDLoose; - bool m_electronVetoLArCrack; - float m_electronPtcut; - std::string m_electronIsolation; - std::string m_electronIsolationLoose; - bool m_electronIsoSFs; - int m_electron_d0SigCut; - float m_electron_delta_z0; - - std::string m_electronIDDecoration; - std::string m_electronIDLooseDecoration; - - // Muon configuration - float m_muonPtcut; // muon object selection pT cut - float m_muonEtacut; // muon object selection (abs) eta cut - std::string m_muonQuality; // muon quality used in object selection - std::string m_muonQualityLoose; // loose muon quality used in object selection - std::string m_muonIsolation; - std::string m_muonIsolationLoose; - int m_muon_d0SigCut; - float m_muon_delta_z0; - - - // Jet configuration - float m_jetPtcut; // jet object selection pT cut - float m_jetEtacut; // jet object selection (abs) eta cut - std::string m_fwdJetAndMET; // type of treatment of forward jets, including for MET calculation - std::string m_jetUncertainties_BunchSpacing; // 25ns or 50ns - std::string m_jetUncertainties_NPModel; // AllNuisanceParameters, 19NP or 3NP - bool m_doMultipleJES; - bool m_largeRSmallRCorrelations = false; // Add correlations of large/small R jets - std::string m_jetJERSmearingModel; // Full or Simple - std::string m_jetCalibSequence; // GCC or JMS - bool m_doJVTInMETCalculation; - - // Large R jet configuration - float m_largeRJetPtcut; // large R jet object selection pT cut - float m_largeRJetEtacut; // large R jet object selection (abs) eta cut - std::string m_largeRJESUncertaintyConfig; // large R jet JES uncertainty configuration file - // see: https://twiki.cern.ch/twiki/bin/view/AtlasProtected/JetUncertainties2015PrerecLargeR - std::string m_largeRJESJMSConfig; // large R jet JES/JMS calibration choice - see ANALYSISTO-210 - - // Track jet configuration - float m_trackJetPtcut; // track jet object selection pT cut - float m_trackJetEtacut; // track jet object selection (abs) eta cut - - // Jet configuration for reclustered jets - float m_RCJetPtcut; - float m_RCJetEtacut; - float m_RCJetTrimcut; - float m_RCJetRadius; - - // Jet configuration for variable large-R jets - float m_VarRCJetPtcut; - float m_VarRCJetEtacut; - float m_VarRCJetTrimcut; - float m_VarRCJetMaxRadius; - std::string m_VarRCJetRho; - std::string m_VarRCJetMassScale; - - // these are needed for the top mass analysis, per default should be 1.0 - float m_JSF; - float m_bJSF; - - // Tau configuration - struct { - // filename to load tau configuration from. - // If this is an empty string then take the 'default' - std::string fileName = "Default"; - // The jetIDWP in CamelCase - // see https://svnweb.cern.ch/trac/atlasoff/browser/PhysicsAnalysis/TauID/TauAnalysisTools/trunk/doc/README-TauSelectionTool.rst - // for supported WPs - std::string jetIDWP = "Medium"; - // the electron BDTWP - std::string eleBDTWP = "Medium"; - // Whether to perform electron overlap removal - bool eleOLR = false; - // pT cut on taus - float pt = 20000; - } m_tau_configuration, m_tau_configuration_loose; - - // Applying new tau energy calibration - bool m_applyTauMVATES = false; - - // photon configuration - struct { - // pT cut on photons - float pt = 25000; - float eta = 2.5; - std::string isolation = "None"; - std::string identification = "None"; - bool useRadiativeZ = false; - } m_photon_configuration, m_photon_configuration_loose; - - // [[[----------------------------------------------- - // Particle Level (truth) configuration - - // electrons - struct { - float PtCut; // [ParticleLevel / Truth] Electron Object - // Selection minimum pT Cut (Standard ATLAS - // units, [MeV]). - float EtaCut; // [ParticleLevel / Truth] Electron Object - // Selection maximum absolute eta Cut. - bool NotFromHadron; // [ParticleLevel / Truth] Whether to apply the - // 'NotFromHadron' requirement onto the objects. - bool TauIsHadron; // [ParticleLevel / Truth] Whether a tauon is a - // hadron during the 'NotFromHadron' check - } m_truth_electron; - - // muons - struct { - float PtCut; // [ParticleLevel / Truth] Muon Object - // Selection minimum pT Cut (Standard ATLAS - // units, [MeV]). - float EtaCut; // [ParticleLevel / Truth] Muon Object - // Selection maximum absolute eta Cut. - bool NotFromHadron; // [ParticleLevel / Truth] Whether to apply the - // 'NotFromHadron' requirement onto the objects. - bool TauIsHadron; // [ParticleLevel / Truth] Whether a tauon is a - // hadron during the 'NotFromHadron' check - } m_truth_muon; - - // photons - struct { - float PtCut; // [ParticleLevel / Truth] Photon Object - // Selection minimum pT Cut (Standard ATLAS - // units, [MeV]). - float EtaCut; // [ParticleLevel / Truth] Photon Object - // Selection maximum absolute eta Cut. - std::string Origin; // [ParticleLevel / Truth] Photon Object - // Selection truth origin configuration. - std::string Isolation; // [ParticleLevel / Truth] Photon Object - // Selection truth isolation configuration. - } m_truth_photon; - - // normal / large R jets - struct { - float PtCut; // [ParticleLevel / Truth] Jet Object - // Selection minimum pT Cut (Standard ATLAS - // units, [MeV]). - float EtaCut; // [ParticleLevel / Truth] Jet Object - // Selection maximum absolute eta Cut. - } m_truth_jet, m_truth_largeRJet; - - - // -----------------------------------------------]]] - - // Options for upgrade studies - bool m_HLLHC; - - // B-tagging WPs requested by the user - std::vector< std::string > m_chosen_btaggingWP = { }; - // B-tagging systematics requested by user to be excluded from EV treatment, separated by semi-colons - std::string m_bTagSystsExcludedFromEV = ""; - - // list of B-tagging WP actualy available - std::vector<std::string> m_available_btaggingWP; - std::vector<std::string> m_available_btaggingWP_trkJet; - // list of B-tagging WP actualy calibrated - std::vector<std::string> m_calibrated_btaggingWP; - std::vector<std::string> m_calibrated_btaggingWP_trkJet; - - // B-tagging calibration to be used - std::string m_btagging_calibration_B = "default"; - std::string m_btagging_calibration_C = "default"; - std::string m_btagging_calibration_Light = "default"; - - // b-tag SF helpers - one of each per WP - // will be set in the BTagScaleFactorCalculator - // These are the base names of the SF systematics (without __up/__down) - std::unordered_map<std::string,std::set<std::string>> m_bTag_base_names; - std::unordered_map<std::string,std::set<std::string>> m_bTag_base_names_trkJet; - // and those of them which are not eigenvectors - std::unordered_map<std::string,std::set<std::string>> m_bTag_named_systs; - std::unordered_map<std::string,std::set<std::string>> m_bTag_named_systs_trkJet; - // how many B eigen-variations do we have? - std::unordered_map<std::string,unsigned int> m_bTag_eigen_B; - std::unordered_map<std::string,unsigned int> m_bTag_eigen_B_trkJet; - // how many C eigen-variations do we have? - std::unordered_map<std::string,unsigned int> m_bTag_eigen_C; - std::unordered_map<std::string,unsigned int> m_bTag_eigen_C_trkJet; - // how many Light eigen-variations do we have? - std::unordered_map<std::string,unsigned int> m_bTag_eigen_light; - std::unordered_map<std::string,unsigned int> m_bTag_eigen_light_trkJet; - - // LHAPDF options - struct { - - std::vector<std::string> pdf_set_names = {}; - std::string baseLHAPDF = ""; // used only if XF1*XF2==0 - - // options - bool doLHAPDF = false; - bool doLHAPDFInNominalTrees = false; - - bool save_per_event = false; - - // we pass the results back to config in PDFScaleFactor::finalize - std::unordered_map< std::string, std::vector<float> > pdf_results; - - - } m_lhapdf_options; - - // Pile-up reweighting - struct { - - std::vector<std::string> lumi_calc_files = {}; - - std::vector<std::string> config_files = {}; - - bool apply = false; - - bool use_grl_tool = false; - - // Whether or not to perform mu dependent - // pile-up reweighting. Optional because can - // result in a possible loss of statistics - // that are crucial for things like MVA training. - bool mu_dependent = true; - - } m_pileup_reweighting; - - // Muon Trigger SF configuration - std::string m_muon_trigger_SF; - - - // Selections - std::shared_ptr<std::vector<std::string>> m_allSelectionNames; - // Trigger configuration - // First string is the selection name, second string is the trigger - std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> m_allTriggers; - std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> m_electronTriggers; - std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> m_muonTriggers; - std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> m_tauTriggers; - std::vector<std::string> m_dummyTrigger; - - // Where the sum of event weights - // before derivation framework is kept - std::string m_sumOfEventWeightsMetaData; - - // Object Selector name - std::string m_objectSelectionName; - // Output Format - std::string m_outputFormat; - // Output Events - std::string m_outputEvents; - bool m_saveOnlySelectedEvents; - // SetAutoFlush(0) on EventSaverFlatNtuple for ANALYSISTO-44 workaround - bool m_outputFileSetAutoFlushZero; - - // Number of events to run on (for testing) - unsigned int m_numberOfEventsToRun; - - // Number of events to skip (for testing) - unsigned int m_numberOfEventsToSkip; - - // AOD meta-data access service - AodMetaDataAccess * m_aodMetaData; - - // Systematics - std::size_t m_nominalHashValue; - - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashPhotons; - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashElectrons; - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashMuons; - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashTaus; - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashJets; - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashLargeRJets; - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashTrackJets; - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashMET; - - std::shared_ptr<std::unordered_set<std::size_t>> m_systHashAll; - std::shared_ptr<std::list<std::size_t>> m_list_systHashAll; - - std::shared_ptr<std::unordered_set<std::size_t>> m_systHash_electronInJetSubtraction; - std::shared_ptr<std::list<std::size_t>> m_list_systHash_electronInJetSubtraction; - - std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> m_systMapPhotons; - std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> m_systMapElectrons; - std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> m_systMapMuons; - std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> m_systMapTaus; - std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> m_systMapJets; - std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> m_systMapLargeRJets; - std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> m_systMapTrackJets; - std::shared_ptr<std::unordered_map<std::size_t,CP::SystematicSet>> m_systMapMET; - - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapPhotons; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapElectrons; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapMuons; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapTaus; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapJets; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapJets_electronInJetSubtraction; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapJetsLoose_electronInJetSubtraction; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapLargeRJets; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapTrackJets; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapMET; - - // For TopEvent/SingleSystEvent - will return the nominal key if not under variation - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapPhotons; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapElectrons; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapMuons; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapTaus; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJets; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapLargeRJets; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapTrackJets; - // The boosted case is a bit more complex, we need additional collections - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapElectrons_electronInJetSubtraction; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJets_electronInJetSubtraction; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJetsLoose_electronInJetSubtraction; - - // For top::TopEventMaker - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapPhotonsTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapPhotonsTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapElectronsTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapElectronsTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapMuonsTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapMuonsTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapTausTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapTausTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJetsTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJetsTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapLargeRJetsTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapLargeRJetsTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapTrackJetsTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapTrackJetsTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJets_electronInJetSubtractionTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux; - - // Missing ET - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapMissingET; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapMissingETLoose; - - // KLFitter - std::string m_sgKeyKLFitter; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapKLFitter; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapKLFitterLoose; - - // PseudoTop - std::string m_sgKeyPseudoTop; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systSgKeyMapPseudoTop; - - // Map from systematic hash to CP::SystematicSet - std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapJetGhostTrack; - // Map from systematic hash to decoration key. - std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systDecoKeyMapJetGhostTrack; - - // Output TTree names - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systAllTTreeNames; - std::shared_ptr<std::unordered_map<std::size_t,std::string>> m_systPersistantAllTTreeNames; - // Output TTree index - std::shared_ptr<std::unordered_map<std::size_t,unsigned int>> m_systAllTTreeIndex; - std::shared_ptr<std::unordered_map<std::size_t,unsigned int>> m_systAllTTreeLooseIndex; - - // Private function only to simplify the setting of AFII values - void ReadIsAFII(top::ConfigurationSettings* const& settings); - - -}; -} // namespace top + // AFII? + inline bool isAFII() const {return m_isAFII;} + inline void setIsAFII(const bool value) { + if (!m_configFixed) { + m_isAFII = value; + } + } + + // List of branches to be removed + inline std::vector<std::string> filterBranches() const {return m_filterBranches;} + inline void setFilterBranches(const std::vector<std::string>& value) { + if (!m_configFixed) { + m_filterBranches = value; + } + } + + // List of PartonLevel branches to be removed + inline std::vector<std::string> filterPartonLevelBranches() const {return m_filterPartonLevelBranches;} + inline void setFilterPartonLevelBranches(const std::vector<std::string>& value) { + if (!m_configFixed) { + m_filterPartonLevelBranches = value; + } + } + + // List of ParticleLevel branches to be removed + inline std::vector<std::string> filterParticleLevelBranches() const {return m_filterParticleLevelBranches;} + inline void setFilterParticleLevelBranches(const std::vector<std::string>& value) { + if (!m_configFixed) { + m_filterParticleLevelBranches = value; + } + } + + // List of NominalLoose branches to be removed + inline std::vector<std::string> filterNominalLooseBranches() const {return m_filterNominalLooseBranches;} + inline void setFilterNominalLooseBranches(const std::vector<std::string>& value) { + if (!m_configFixed) { + m_filterNominalLooseBranches = value; + } + } + + // Generators name + inline std::string getGenerators() const {return m_generators;} + inline void setGenerators(const std::string value) { + if (!m_configFixed) { + m_generators = value; + } + } + + // AMITag + inline std::string getAMITag() const {return m_AMITag;} + inline void setAMITag(const std::string value) { + if (!m_configFixed) { + m_AMITag = value; + } + } + + // Is this a Primary xAOD? + inline bool isPrimaryxAOD() const {return m_isPrimaryxAOD;} + inline void setIsPrimaryxAOD(const bool value) { + if (!m_configFixed) { + m_isPrimaryxAOD = value; + } + } + + // Is this a Truth DxAOD? + inline bool isTruthDxAOD() const {return m_isTruthDxAOD;} + inline void setIsTruthDxAOD(const bool value) { + if (!m_configFixed) { + m_isTruthDxAOD = value; + } + } + + // What derivation type is it? + inline std::string getDerivationStream() const {return m_derivationStream;} + inline void setDerivationStream(const std::string value) { + if (!m_configFixed) { + m_derivationStream = value; + } + } + + // AMI tag from metadata + std::string const& getAmiTag() const; + void setAmiTag(std::string const& amiTag); + + inline unsigned int getDSID() const {return m_DSID;} + inline void setDSID(unsigned int value) { + // Check here if this is a sherpa 2.2 V+jets sample + // (see below to set DSIDs) + setIsSherpa22Vjets(value); + m_DSID = value; + } + + // Is this Sherpa 2.2 V+jets? + // (if so then we need to reweight based on num truth jets) + inline bool isSherpa22Vjets() const {return m_is_sherpa_22_vjets;} + inline void setIsSherpa22Vjets(unsigned int dsid) { + // m_is_sherpa_22_vjets = false by default + // Sherpa 2.2 W+jets (from TopDataPrep) + if (dsid >= 363331 && dsid <= 363354) m_is_sherpa_22_vjets = true; + if (dsid >= 363436 && dsid <= 363483) m_is_sherpa_22_vjets = true; + // Sherpa 2.2 Z+jets (from TopDataPrep) + if (dsid >= 363102 && dsid <= 363122) m_is_sherpa_22_vjets = true; + if (dsid >= 363361 && dsid <= 363435) m_is_sherpa_22_vjets = true; + } + + // map index for MC/MC b-tagging scale factors + inline unsigned int getMapIndex() const {return m_MapIndex;} + inline void setMapIndex(unsigned int value) {m_MapIndex = value;} + + // Run normal (Tight) selection and dumps the non-Loose trees + // Default is true for both Data and MC + inline bool doTightEvents() const {return m_doTightEvents;} + // Run Loose selection and dumps the Loose trees + // Default is true for Data and false for MC + inline bool doLooseEvents() const {return m_doLooseEvents;} + + // Run systematics on Loose selection + // Default is true + inline bool doTightSysts() const {return m_doTightSysts;} + // Run systematics on Loose selection + // Default is true + inline bool doLooseSysts() const {return m_doLooseSysts;} + + // Do fakes MM weight calculation using FakeBkgTools from IFF + inline bool doFakesMMWeightsIFF() const {return m_doFakesMMWeightsIFF;} + + // Configurations for MM fake estimate using FakeBkgTools from IFF + inline std::string FakesMMConfigIFF() const {return m_FakesMMConfigIFF;} + + // Debug mode for MM fake estimate using FakeBkgTools from IFF + inline bool FakesMMIFFDebug() const {return m_doFakesMMIFFDebug;} + + // enables calculation of MM weights using FakeBkgTools from IFF + // only possible for data loose + // doing it on MC loose is explicitly forbidden + inline void setFakesMMWeightsCalculationIFF() + {m_doFakesMMWeightsIFF = true;} + inline void setFakesMMConfigIFF(const std::string& configIFF) + {m_FakesMMConfigIFF = configIFF;} + inline void setFakesMMIFFDebug() + {m_doFakesMMIFFDebug = true;} + + //by default AT uses always tight objects in MET re-building; these options allow for using loose objects instead in the loose analysis and/or in the nominal analysis + inline void setUseLooseObjectsInMETInLooseTree() {if (!m_configFixed) m_useLooseObjectsInMETInLooseTree = true;} + inline bool useLooseObjectsInMETInLooseTree() const {return m_useLooseObjectsInMETInLooseTree;} + inline void setUseLooseObjectsInMETInNominalTree() {if (!m_configFixed) m_useLooseObjectsInMETInNominalTree = true;} + inline bool useLooseObjectsInMETInNominalTree() const {return m_useLooseObjectsInMETInNominalTree;} + //this will write a separate branch with the met built using loose objects + inline void setWriteMETBuiltWithLooseObjects() {if (!m_configFixed) m_writeMETBuiltWithLooseObjects=true;} + inline bool writeMETBuiltWithLooseObjects() {return m_writeMETBuiltWithLooseObjects;} + + // By default the top group does overlap removal on the tight lepton definitions + // If you use this you are going off piste and need to report + // your findings to the top reconstruction meeting + inline void setOverlapRemovalOnLooseLeptonDef() { + if (!m_configFixed) { + m_doOverlapRemovalOnLooseLeptonDef = true; + } + } + + inline bool doOverlapRemovalOnLooseLeptonDef() const {return m_doOverlapRemovalOnLooseLeptonDef;} + + inline std::string overlapRemovalProcedure() const + {return m_overlap_removal_procedure;} + + inline float overlapRemovalSlidingInnerDRel() const + {return m_overlapRemovalSlidingInnerDRel;} + + inline float overlapRemovalSlidingInnerDRmu() const + {return m_overlapRemovalSlidingInnerDRmu;} + + // do overlap removal also with large-R jets + // (using whatever procedure is used in the official tools) + inline void setLargeJetOverlapRemoval() { + if (!m_configFixed) { + m_doLargeJetOverlapRemoval = true; + } + } + + inline bool doLargeJetOverlapRemoval() const {return m_doLargeJetOverlapRemoval;} + + // In the *_Loose trees, lepton SFs are calculated considering + // tight ID and isolation instead of loose + // Only tight leptons are considered in the event SF calculation + inline void setApplyTightSFsInLooseTree() { + if (!m_configFixed) { + m_applyTightSFsInLooseTree = true; + } + } + + inline bool applyTightSFsInLooseTree() const {return m_applyTightSFsInLooseTree;} + + // Apply Electron In Jet subtraction + // For boosted analysis + inline bool applyElectronInJetSubtraction() const {return m_applyElectronInJetSubtraction;} + inline void setApplyElectronInJetSubtraction() { + if (!m_configFixed) { + m_applyElectronInJetSubtraction = true; + } + } + + // Dump truth block info + inline bool doTruthBlockInfo() const {return m_doTruthBlockInfo;} + inline void setTruthBlockInfo() { + if (!m_configFixed) { + m_doTruthBlockInfo = true; + } + } + + // Write truth PDF info + inline bool doTruthPDFInfo() const {return m_doTruthPDFInfo;} + inline void setTruthPDFInfo() { + if (!m_configFixed) { + m_doTruthPDFInfo = true; + } + } + + // Write truth PDF info in reco tree + inline bool doTruthPDFInfoInNominalTrees() const {return m_doTruthPDFInfoInNominalTrees;} + inline void setTruthPDFInfoInNominalTrees() { + if (!m_configFixed) { + m_doTruthPDFInfoInNominalTrees = true; + } + } + + // Write MC generator weights + inline bool doMCGeneratorWeights() const {return m_doMCGeneratorWeights;} + inline void setMCGeneratorWeights() { + if (!m_configFixed) { + m_doMCGeneratorWeights = true; + } + } + + // Write truth PDF info in reco tree + inline bool doMCGeneratorWeightsInNominalTrees() const {return m_doMCGeneratorWeightsInNominalTrees;} + inline void setMCGeneratorWeightsInNominalTrees() { + if (!m_configFixed) { + m_doMCGeneratorWeightsInNominalTrees = true; + } + } + + inline const std::vector<std::string>& nominalWeightNames() const {return m_nominalWeightNames;} + inline void setNominalWeightName(const std::string& name) { + m_nominalWeightName = name; + } + inline void setNominalWeightIndex(size_t index) { + m_nominalWeightIndex = index; + } + inline std::string nominalWeightName() const {return m_nominalWeightName;} + inline size_t nominalWeightIndex() const {return m_nominalWeightIndex;} + inline bool forceNominalWeightFallbackIndex() const {return m_forceWeightIndex;} + + inline void setMCweightsVectorSize(size_t weights_size) { + m_MCweightsSize = weights_size; + } + + inline size_t MCweightsVectorSize() const {return m_MCweightsSize;} + + // Top Parton History + inline bool doTopPartonHistory() const {return m_doTopPartonHistory;} + inline void setTopPartonHistory() { + if (!m_configFixed) { + m_doTopPartonHistory = true; + } + } + + // Register Top Parton History in flat ntuple + // This doesn't use m_configFixed - this is bad :( + // This is a simple implementation of saving xAOD objects to ntuples + // John has more advanced ideas on how to do this + // This is just a quick fix for now to get the concept working + inline bool isTopPartonHistoryRegisteredInNtuple() const {return m_isTopPartonHistoryRegisteredInNtuple;} + inline void setTopPartonHistoryRegisteredInNtuple() + {m_isTopPartonHistoryRegisteredInNtuple = true;} + + inline bool doTopPartonLevel() const {return m_doTopPartonLevel;} + inline void setTopPartonLevel(bool in) { + if (!m_configFixed) { + m_doTopPartonLevel = in; + } + } + + // TopParticleLevel + inline bool doTopParticleLevel() const {return m_doTopParticleLevel;} + inline void setTopParticleLevel(bool in) { + if (!m_configFixed) { + m_doTopParticleLevel = in; + } + } + + inline bool doParticleLevelOverlapRemovalMuJet() const {return m_doParticleLevelOverlapRemovalMuJet;} + inline bool doParticleLevelOverlapRemovalElJet() const {return m_doParticleLevelOverlapRemovalElJet;} + inline bool doParticleLevelOverlapRemovalJetPhoton() const {return m_doParticleLevelOverlapRemovalJetPhoton;} + inline void setParticleLevelOverlapRemovalMuJet(bool value) { + if (!m_configFixed) { + m_doParticleLevelOverlapRemovalMuJet = value; + } + } + + inline void setParticleLevelOverlapRemovalElJet(bool value) { + if (!m_configFixed) { + m_doParticleLevelOverlapRemovalElJet = value; + } + } + + inline void setParticleLevelOverlapRemovalJetPhoton(bool value) { + if (!m_configFixed) { + m_doParticleLevelOverlapRemovalJetPhoton = value; + } + } + + // KLFitter + inline bool doKLFitter() const {return m_doKLFitter;} + inline void setKLFitter() { + if (!m_configFixed) { + m_doKLFitter = true; + } + } + + inline const std::string& KLFitterTransferFunctionsPath() const {return m_KLFitterTransferFunctionsPath;} + inline const std::string& KLFitterOutput() const {return m_KLFitterOutput;} + inline const std::string& KLFitterJetSelectionMode() const {return m_KLFitterJetSelectionMode;} + inline const std::string& KLFitterBTaggingMethod() const {return m_KLFitterBTaggingMethod;} + inline const std::string& KLFitterLH() const {return m_KLFitterLH;} + + inline bool KLFitterTopMassFixed() const {return m_KLFitterTopMassFixed;} + inline bool KLFitterSaveAllPermutations() const {return m_KLFitterSaveAllPermutations;} + + inline bool KLFitterFailOnLessThanXJets() const {return m_KLFitterFailOnLessThanXJets;} + // PseudoTop + inline bool doPseudoTop() const {return m_doPseudoTop;} + inline void setPseudoTop() { + if (!m_configFixed) { + m_doPseudoTop = true; + } + } + + // Triggers + inline virtual void allTriggers_Tight(std::shared_ptr<std::unordered_map<std::string, + std::vector<std::string> > > triggers) { + if (!m_configFixed) { + m_allTriggers_Tight = triggers; + } + } + + inline virtual void electronTriggers_Tight(std::shared_ptr<std::unordered_map<std::string, + std::vector<std::string> > > triggers) { + if (!m_configFixed) { + m_electronTriggers_Tight = triggers; + } + } + + inline virtual void muonTriggers_Tight(std::shared_ptr<std::unordered_map<std::string, + std::vector<std::string> > > triggers) { + if (!m_configFixed) { + m_muonTriggers_Tight = triggers; + } + } + + inline virtual void tauTriggers_Tight(std::shared_ptr<std::unordered_map<std::string, + std::vector<std::string> > > triggers) { + if (!m_configFixed) { + m_tauTriggers_Tight = triggers; + } + } + + inline virtual void allTriggers_Loose(std::shared_ptr<std::unordered_map<std::string, + std::vector<std::string> > > triggers) { + if (!m_configFixed) { + m_allTriggers_Loose = triggers; + } + } + + inline virtual void electronTriggers_Loose(std::shared_ptr<std::unordered_map<std::string, + std::vector<std::string> > > triggers) { + if (!m_configFixed) { + m_electronTriggers_Loose = triggers; + } + } + + inline virtual void muonTriggers_Loose(std::shared_ptr<std::unordered_map<std::string, + std::vector<std::string> > > triggers) { + if (!m_configFixed) { + m_muonTriggers_Loose = triggers; + } + } + + inline virtual void tauTriggers_Loose(std::shared_ptr<std::unordered_map<std::string, + std::vector<std::string> > > triggers) { + if (!m_configFixed) { + m_tauTriggers_Loose = triggers; + } + } + + inline std::shared_ptr<std::vector<std::string> > allSelectionNames() const {return m_allSelectionNames;} + virtual const std::vector<std::string>& allTriggers_Tight(const std::string& selection) const; + virtual const std::vector<std::string>& electronTriggers_Tight(const std::string& selection) const; + virtual const std::vector<std::string>& muonTriggers_Tight(const std::string& selection) const; + virtual const std::vector<std::string>& tauTriggers_Tight(const std::string& selection) const; + + virtual const std::vector<std::string>& allTriggers_Loose(const std::string& selection) const; + virtual const std::vector<std::string>& electronTriggers_Loose(const std::string& selection) const; + virtual const std::vector<std::string>& muonTriggers_Loose(const std::string& selection) const; + virtual const std::vector<std::string>& tauTriggers_Loose(const std::string& selection) const; + + // StoreGate Keys + virtual void sgKeyMCParticle(const std::string& s); + virtual void sgKeyPhotons(const std::string& s); + virtual void sgKeyElectrons(const std::string& s); + virtual void sgKeyFwdElectrons(const std::string& s); + virtual void sgKeyMuons(const std::string& s); + virtual void sgKeySoftMuons(const std::string& s); + virtual void sgKeyTaus(const std::string& s); + virtual void sgKeyJets(const std::string& s); + virtual void sgKeyLargeRJets(const std::string& s); + virtual void sgKeyTrackJets(const std::string& s); + virtual void sgKeyTracks(const std::string& s); + + virtual void sgKeyTruthElectrons(const std::string& s); + virtual void sgKeyTruthMuons(const std::string& s); + virtual void sgKeyTruthPhotons(const std::string& s); + virtual void sgKeyTruthMET(const std::string& s); + virtual void sgKeyTruthJets(const std::string& s); + virtual void sgKeyTruthLargeRJets(const std::string& s); + virtual void sgKeyTruthTaus(const std::string& s); + + inline virtual void sgKeyMissingEt(const std::string& s) { + if (!m_configFixed) { + m_sgKeyMissingEt = s; + } + } + + inline virtual void sgKeyMissingEtLoose(const std::string& s) { + if (!m_configFixed) { + m_sgKeyMissingEtLoose = s; + } + } + + inline float jetResponseMatchingDeltaR() const {return m_jetResponseMatchingDeltaR;} + inline void setJetResponseMatchingDeltaR(const float value) {m_jetResponseMatchingDeltaR = value;} + + inline const std::string& sgKeyEventInfo() const {return m_sgKeyEventInfo;} + inline const std::string& sgKeyPrimaryVertices() const {return m_sgKeyPrimaryVertices;} + inline virtual const std::string& sgKeyPhotons() const {return m_sgKeyPhotons;} + inline virtual const std::string& sgKeyElectrons() const {return m_sgKeyElectrons;} + inline virtual const std::string& sgKeyFwdElectrons() const {return m_sgKeyFwdElectrons;} + inline virtual const std::string& sgKeyMuons() const {return m_sgKeyMuons;} + inline virtual const std::string& sgKeySoftMuons() const {return m_sgKeySoftMuons;} + inline virtual const std::string& sgKeyTaus() const {return m_sgKeyTaus;} + inline virtual const std::string& sgKeyJets() const {return m_sgKeyJets;} + inline virtual const std::string& sgKeyJetsType() const {return m_sgKeyJetsType;} + inline virtual const std::string& sgKeyLargeRJets() const {return m_sgKeyLargeRJets;} + inline virtual const std::string& sgKeyTrackJets() const {return m_sgKeyTrackJets;} + inline virtual const std::string& sgKeyTracks() const {return m_sgKeyTracks;} + inline virtual const std::string& sgKeyTrackJetsType() const {return m_sgKeyTrackJetsType;} + inline virtual const std::string& sgKeyMissingEt() const {return m_sgKeyMissingEt;} + inline virtual const std::string& sgKeyMissingEtLoose() const {return m_sgKeyMissingEtLoose;} + inline const std::string& sgKeyInDetTrackParticles() const {return m_sgKeyInDetTrackParticles;} + + inline const std::string& sgKeyTruthEvent() const {return m_sgKeyTruthEvent;} + inline virtual const std::string& sgKeyMCParticle() const {return m_sgKeyMCParticle;} + inline const std::string& sgKeyTruthPhotons() const {return m_sgKeyTruthPhotons;} + inline const std::string& sgKeyTruthElectrons() const {return m_sgKeyTruthElectrons;} + inline const std::string& sgKeyTruthMuons() const {return m_sgKeyTruthMuons;} + inline const std::string& sgKeyTruthTaus() const {return m_sgKeyTruthTaus;} + inline virtual const std::string& sgKeyTruthJets() const {return m_sgKeyTruthJets;} + inline virtual const std::string& sgKeyTruthLargeRJets() const {return m_sgKeyTruthLargeRJets;} + inline const std::string& sgKeyTruthMET() const {return m_sgKeyTruthMET;} + inline const std::string& sgKeyTopPartonHistory() const {return m_sgKeyTopPartonHistory;} + + inline const std::string& sgKeyTopSystematicEvents() const {return m_sgKeyTopSystematicEvents;} + inline const std::string& sgKeyTopSystematicEventsLoose() const {return m_sgKeyTopSystematicEventsLoose;} + inline const std::string& passEventSelectionDecoration() const {return m_passEventSelectionDecoration;} + virtual void decoKeyJetGhostTrack(const std::string& key); + inline virtual const std::string& decoKeyJetGhostTrack() const {return m_decoKeyJetGhostTrack;} + virtual void runPeriodJetGhostTrack(const std::vector<std::uint32_t>& vect); + virtual void runPeriodTrack(const std::vector<std::uint32_t>& vect); + + virtual const std::string& sgKeyPhotons(const std::size_t hash) const; + virtual const std::string& sgKeyElectrons(const std::size_t hash) const; + virtual const std::string& sgKeyFwdElectrons(const std::size_t hash) const; + virtual const std::string& sgKeyElectronsStandAlone(const std::size_t hash) const; + virtual const std::string& sgKeyFwdElectronsStandAlone(const std::size_t hash) const; + virtual const std::string& sgKeyMuons(const std::size_t hash) const; + virtual const std::string& sgKeySoftMuons(const std::size_t hash) const; + virtual const std::string& sgKeyTaus + (const std::size_t hash) const; + virtual const std::string& sgKeyJets(const std::size_t hash, const bool useLooseLeptonJets) const; + virtual const std::string& sgKeyJetsStandAlone(const std::size_t hash) const; + virtual const std::string& sgKeyLargeRJets(const std::size_t hash) const; + virtual const std::string& sgKeyTrackJets(const std::size_t hash) const; + virtual const std::string& sgKeyTracks(const std::size_t hash) const; + virtual const std::string& sgKeyMissingEt(const std::size_t hash) const; + virtual const std::string& sgKeyMissingEtLoose(const std::size_t hash) const; + + // For top::TopEventMaker + const std::string& sgKeyPhotonsTDS(const std::size_t hash) const; + const std::string& sgKeyPhotonsTDSAux(const std::size_t hash) const; + const std::string& sgKeyElectronsTDS(const std::size_t hash) const; + const std::string& sgKeyElectronsTDSAux(const std::size_t hash) const; + const std::string& sgKeyFwdElectronsTDS(const std::size_t hash) const; + const std::string& sgKeyFwdElectronsTDSAux(const std::size_t hash) const; + const std::string& sgKeyMuonsTDS(const std::size_t hash) const; + const std::string& sgKeyMuonsTDSAux(const std::size_t hash) const; + const std::string& sgKeySoftMuonsTDS(const std::size_t hash) const; + const std::string& sgKeySoftMuonsTDSAux(const std::size_t hash) const; + const std::string& sgKeyTausTDS(const std::size_t hash) const; + const std::string& sgKeyTausTDSAux(const std::size_t hash) const; + const std::string& sgKeyJetsTDS(const std::size_t hash, const bool useLooseLeptonJets) const; + const std::string& sgKeyJetsTDSAux(const std::size_t hash, const bool useLooseLeptonJets) const; + const std::string& sgKeyLargeRJetsTDS(const std::size_t hash) const; + const std::string& sgKeyLargeRJetsTDSAux(const std::size_t hash) const; + const std::string& sgKeyTrackJetsTDS(const std::size_t hash) const; + const std::string& sgKeyTrackJetsTDSAux(const std::size_t hash) const; + const std::string& sgKeyTracksTDS(const std::size_t hash) const; + const std::string& sgKeyTracksTDSAux(const std::size_t hash) const; + + // KLFitter + const std::string& sgKeyKLFitter(const std::size_t hash) const; + const std::string& sgKeyKLFitterLoose(const std::size_t hash) const; + + // PseudoTop + const std::string& sgKeyPseudoTop(const std::size_t hash) const; + const std::string& sgKeyPseudoTop(const std::string) const; + const std::string& sgKeyPseudoTopLoose(const std::size_t hash) const; + const std::string& sgKeyPseudoTopLoose(const std::string) const; + + // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + // Jet Ghost-Track Systematics and selection + + // The jet decoration name for a given systematic (nominal also possible). + const std::string& decoKeyJetGhostTrack(const std::size_t hash) const; + + // Retrieve names of all (registered) systematics that affect ghost tracks. + const std::vector<std::string>& systematicsJetGhostTrack() const {return m_jetGhostTrackSystematics;} + + // Retrieve run periods for ghost tracks. + const std::vector<std::uint32_t>& runPeriodsJetGhostTrack() const {return m_jetGhostTrackRunPeriods;} + + // Retrieve run periods for tracks. + const std::vector<std::uint32_t>& runPeriodsTrack() const {return m_trackRunPeriods;} + + // Retrieve mapping from systematic hash to CP::SystematicSet. + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapJetGhostTrack() const { + return m_systMapJetGhostTrack; + } + + // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + + // special: allow to dump the systematics-shifted b-tagging SFs in the systematics trees + inline virtual void dumpBtagSystsInSystTrees(const bool& b) { + if (!m_configFixed) { + m_dumpBtagSystsInSystTrees = b; + } + } + + inline virtual const bool& dumpBtagSystsInSystTrees() {return m_dumpBtagSystsInSystTrees;} + + // special: store per-jet btag SGs + inline virtual void storePerJetBtagSFs(const bool& b) { + if (!m_configFixed) { + m_storePerJetBtagSFs = b; + } + } + + inline virtual const bool& storePerJetBtagSFs() {return m_storePerJetBtagSFs;} + + // Electron configuration + inline virtual void egammaSystematicModel(const std::string& s) { + if (!m_configFixed) { + m_egammaSystematicModel = s; + } + } + + inline virtual void electronEfficiencySystematicModel(const std::string& s) { + if (!m_configFixed) { + m_electronEfficiencySystematicModel = s; + } + } + + inline virtual void electronEfficiencySystematicModelEtaBinning(const std::string& s) { + if (!m_configFixed) { + m_electronEfficiencySystematicModelEtaBinning = s; + } + } + + inline virtual void electronEfficiencySystematicModelEtBinning(const std::string& s) { + if (!m_configFixed) { + m_electronEfficiencySystematicModelEtBinning = s; + } + } + + inline virtual void electronID(const std::string& s) { + if (!m_configFixed) { + m_electronID = s; + } + } + + inline virtual void electronIDLoose(const std::string& s) { + if (!m_configFixed) { + m_electronIDLoose = s; + } + } + + inline void removeElectronVetoLArCrack() { + if (!m_configFixed) { + m_electronVetoLArCrack = false; + } + } + + inline virtual void electronVetoLArCrack(const bool b) { + if (!m_configFixed) { + m_electronVetoLArCrack = b; + } + } + + inline virtual void electronPtcut(const float pt) { + if (!m_configFixed) { + m_electronPtcut = pt; + } + } + + inline virtual void electronIsolation(const std::string& iso) { + if (!m_configFixed) { + m_electronIsolation = iso; + } + } + + inline virtual void electronIsolationLoose(const std::string& iso) { + if (!m_configFixed) { + m_electronIsolationLoose = iso; + } + } + + void electronIsolationSF(std::string const& iso) { + if (!m_configFixed) { + m_electronIsolationSF = iso; + } + } + + void electronIsolationSFLoose(std::string const& iso) { + if (!m_configFixed) { + m_electronIsolationSFLoose = iso; + } + } + + inline virtual void useElectronChargeIDSelection(const std::string& s) { + if (!m_configFixed) { + m_useElectronChargeIDSelection = (s == "True" || s == "true"); + } + } + + inline virtual void useEgammaLeakageCorrection(const std::string& s) { + if (!m_configFixed) { + m_useEgammaLeakageCorrection = (s == "True" || s == "true"); + } + } + + inline virtual void enablePromptLeptonImprovedVetoStudies(const std::string& s) { + if (!m_configFixed) { + m_enablePromptLeptonImprovedVetoStudies = (s == "True" || s == "true"); + } + } + + inline virtual const std::string& egammaSystematicModel() {return m_egammaSystematicModel;} + inline virtual const std::string& electronEfficiencySystematicModel() {return m_electronEfficiencySystematicModel;} + inline virtual const std::string& electronEfficiencySystematicModelEtaBinning() { + return m_electronEfficiencySystematicModelEtaBinning; + } + inline virtual const std::string& electronEfficiencySystematicModelEtBinning() { + return m_electronEfficiencySystematicModelEtBinning; + } + inline virtual const std::string& electronID() const {return m_electronID;} + inline virtual const std::string& electronIDLoose() const {return m_electronIDLoose;} + inline virtual bool electronVetoLArCrack() const {return m_electronVetoLArCrack;} + inline virtual float electronPtcut() const {return m_electronPtcut;} + inline virtual const std::string& electronIsolation() const {return m_electronIsolation;} + inline virtual const std::string& electronIsolationLoose() const {return m_electronIsolationLoose;} + std::string const& electronIsolationSF() const {return m_electronIsolationSF;} + std::string const& electronIsolationSFLoose() const {return m_electronIsolationSFLoose;} + inline virtual bool electronIsoSFs() const {return m_electronIsoSFs;} + inline const std::string& electronIDDecoration() const {return m_electronIDDecoration;} + inline const std::string& electronIDLooseDecoration() const {return m_electronIDLooseDecoration;} + inline bool useElectronChargeIDSelection() const {return m_useElectronChargeIDSelection;} + inline bool useEgammaLeakageCorrection() const {return m_useEgammaLeakageCorrection;} + inline bool enablePromptLeptonImprovedVetoStudies() const {return m_enablePromptLeptonImprovedVetoStudies;} + + // Fwd electron + inline virtual void fwdElectronID(const std::string& s) { + if (!m_configFixed) { + m_fwdElectronID = s; + } + } + + inline virtual void fwdElectronIDLoose(const std::string& s) { + if (!m_configFixed) { + m_fwdElectronIDLoose = s; + } + } + + inline virtual void fwdElectronPtcut(const float pt) { + if (!m_configFixed) { + m_fwdElectronPtcut = pt; + } + } + + inline virtual void fwdElectronMinEtacut(const float eta) { + if (!m_configFixed) { + m_fwdElectronMinEtacut = eta; + } + } + + inline virtual void fwdElectronMaxEtacut(const float eta) { + if (!m_configFixed) { + m_fwdElectronMaxEtacut = eta; + } + } + + inline virtual void fwdElectronBCIDCleaningMinRun(const int fwdElectronBCIDCleaningMinRun) { + if (!m_configFixed) { + m_fwdElectronBCIDCleaningMinRun = fwdElectronBCIDCleaningMinRun; + } + } + + inline virtual void fwdElectronBCIDCleaningMaxRun(const int fwdElectronBCIDCleaningMaxRun) { + if (!m_configFixed) { + m_fwdElectronBCIDCleaningMaxRun = fwdElectronBCIDCleaningMaxRun; + } + } + + inline virtual const std::string& fwdElectronID() const {return m_fwdElectronID;} + inline virtual const std::string& fwdElectronIDLoose() const {return m_fwdElectronIDLoose;} + inline virtual float fwdElectronPtcut() const {return m_fwdElectronPtcut;} + inline virtual float fwdElectronMinEtacut() const {return m_fwdElectronMinEtacut;} + inline virtual float fwdElectronMaxEtacut() const {return m_fwdElectronMaxEtacut;} + inline virtual int fwdElectronBCIDCleaningMinRun() const {return m_fwdElectronBCIDCleaningMinRun;} + inline virtual int fwdElectronBCIDCleaningMaxRun() const {return m_fwdElectronBCIDCleaningMaxRun;} + + // Photon configuration + inline virtual void photonPtcut(const float pt) { + if (!m_configFixed) { + m_photon_configuration.pt = pt; + } + } + + inline virtual void photonEtacut(const float eta) { + if (!m_configFixed) { + m_photon_configuration.eta = eta; + } + } + + inline virtual void photonIdentification(const std::string& quality) { + if (!m_configFixed) { + m_photon_configuration.identification = quality; + } + } + + inline virtual void photonIdentificationLoose(const std::string& quality) { + if (!m_configFixed) { + m_photon_configuration_loose.identification = quality; + } + } + + inline virtual void photonIsolation(const std::string& quality) { + if (!m_configFixed) { + m_photon_configuration.isolation = quality; + } + } + + inline virtual void photonIsolationLoose(const std::string& quality) { + if (!m_configFixed) { + m_photon_configuration_loose.isolation = quality; + } + } + + // Muon configuration + inline virtual void muonPtcut(const float pt) { + if (!m_configFixed) { + m_muonPtcut = pt; + } + } + + inline virtual void muonEtacut(const float eta) { + if (!m_configFixed) { + m_muonEtacut = eta; + } + } + + inline virtual void muonQuality(const std::string& quality) { + if (!m_configFixed) { + m_muonQuality = quality; + } + } + + void muonUseMVALowPt(const bool& UseMVALowPt) { + if (!m_configFixed) { + m_muonUseMVALowPt = UseMVALowPt; + } + } + + void muonUse2stationMuonsHighPt(const bool& Use2stationMuonsHighPt) { + if (!m_configFixed) { + m_muonUse2stationMuonsHighPt = Use2stationMuonsHighPt; + } + } + + void muonUseMVALowPtLoose(const bool& UseMVALowPtLoose) { + if (!m_configFixed) { + m_muonUseMVALowPtLoose = UseMVALowPtLoose; + } + } + + void muonUse2stationMuonsHighPtLoose(const bool& Use2stationMuonsHighPtLoose) { + if (!m_configFixed) { + m_muonUse2stationMuonsHighPtLoose = Use2stationMuonsHighPtLoose; + } + } + + inline virtual void muonQualityLoose(const std::string& quality) { + if (!m_configFixed) { + m_muonQualityLoose = quality; + } + } + + inline virtual void muonIsolation(const std::string& iso) { + if (!m_configFixed) { + m_muonIsolation = iso; + } + } + + inline virtual void muonIsolationLoose(const std::string& iso) { + if (!m_configFixed) { + m_muonIsolationLoose = iso; + } + } + + void muonIsolationSF(std::string const& iso) { + if (!m_configFixed) { + m_muonIsolationSF = iso; + } + } + + void muonIsolationSFLoose(std::string const& iso) { + if (!m_configFixed) { + m_muonIsolationSFLoose = iso; + } + } + + void muonMuonDoSmearing2stationHighPt(const bool& MuonDoSmearing2stationHighPt) { + if (!m_configFixed) { + m_muonMuonDoSmearing2stationHighPt = MuonDoSmearing2stationHighPt; + } + } + + void muonMuonDoExtraSmearingHighPt(const bool& MuonDoExtraSmearingHighPt) { + if (!m_configFixed) { + m_muonMuonDoExtraSmearingHighPt = MuonDoExtraSmearingHighPt; + } + } + + inline virtual float muonPtcut() const {return m_muonPtcut;} + inline virtual float muonEtacut() const {return m_muonEtacut;} + inline virtual const std::string& muonQuality() const {return m_muonQuality;} + inline virtual const std::string& muonQualityLoose() const {return m_muonQualityLoose;} + inline virtual bool muonUseMVALowPt() const {return m_muonUseMVALowPt;} + inline virtual bool muonUse2stationMuonsHighPt() const {return m_muonUse2stationMuonsHighPt;} + inline virtual bool muonUseMVALowPtLoose() const {return m_muonUseMVALowPtLoose;} + inline virtual bool muonUse2stationMuonsHighPtLoose() const {return m_muonUse2stationMuonsHighPtLoose;} + inline virtual const std::string& muonIsolation() const {return m_muonIsolation;} + inline virtual const std::string& muonIsolationLoose() const {return m_muonIsolationLoose;} + std::string const& muonIsolationSF() const {return m_muonIsolationSF;} + std::string const& muonIsolationSFLoose() const {return m_muonIsolationSFLoose;} + inline virtual bool muonMuonDoSmearing2stationHighPt() const {return m_muonMuonDoSmearing2stationHighPt;} + inline virtual bool muonMuonDoExtraSmearingHighPt() const {return m_muonMuonDoExtraSmearingHighPt;} + + // Soft Muon configuration + inline virtual void softmuonPtcut(const float pt) { + if (!m_configFixed) { + m_softmuonPtcut = pt; + } + } + + inline virtual void softmuonEtacut(const float eta) { + if (!m_configFixed) { + m_softmuonEtacut = eta; + } + } + + inline virtual void softmuonQuality(const std::string& quality) { + if (!m_configFixed) { + m_softmuonQuality = quality; + } + } + + void softmuonUseMVALowPt(const bool UseMVALowPtSoftMuon) { + if (!m_configFixed) { + m_softmuonUseMVALowPt = UseMVALowPtSoftMuon; + } + } + + inline virtual void softmuonDRJetcut(const float DRJet) { + if (!m_configFixed) { + m_softmuonDRJetcut = DRJet; + } + } + + inline virtual void softmuonDRJetcutUseRapidity(const bool in) { + if (!m_configFixed) { + m_softmuonDRJetcutUseRapidity = in; + } + } + + inline virtual void softmuonAdditionalTruthInfo(bool in) { + if (!m_configFixed) { + m_softmuonAdditionalTruthInfo=in; + } + } + + inline virtual void softmuonAdditionalTruthInfoCheckPartonOrigin(bool in) { + if (!m_configFixed) { + m_softmuonAdditionalTruthInfoCheckPartonOrigin=in; + } + } + + inline virtual void softmuonAdditionalTruthInfoDoVerbose(bool in) { + if (!m_configFixed) { + m_softmuonAdditionalTruthInfoDoVerbose=in; + } + } + + inline virtual float softmuonPtcut() const {return m_softmuonPtcut;} + inline virtual float softmuonEtacut() const {return m_softmuonEtacut;} + inline virtual const std::string& softmuonQuality() const {return m_softmuonQuality;} + inline virtual bool softmuonUseMVALowPt() const {return m_softmuonUseMVALowPt;} + inline virtual float softmuonDRJetcut() const {return m_softmuonDRJetcut;} + inline virtual bool softmuonDRJetcutUseRapidity() const {return m_softmuonDRJetcutUseRapidity;} + inline virtual bool softmuonAdditionalTruthInfo() const { return m_softmuonAdditionalTruthInfo;} + inline virtual bool softmuonAdditionalTruthInfoCheckPartonOrigin() const { return m_softmuonAdditionalTruthInfoCheckPartonOrigin;} + inline virtual bool softmuonAdditionalTruthInfoDoVerbose() const { return m_softmuonAdditionalTruthInfoDoVerbose;} + + // Jet configuration + inline virtual void jetPtcut(const float pt) { + if (!m_configFixed) { + m_jetPtcut = pt; + } + } + + inline virtual void jetEtacut(const float eta) { + if (!m_configFixed) { + m_jetEtacut = eta; + } + } + + inline virtual void jetPtGhostTracks(const float pt, const float small_jet_pt) { + if (!m_configFixed) { + if ( small_jet_pt >= pt+4999){ + m_jetPtGhostTracks = pt; + } + else { + m_jetPtGhostTracks = (small_jet_pt - 5000) > 20000 ? (small_jet_pt - 5000) : 20000; + } + } + } + + inline virtual void jetEtaGhostTracks(const float eta) { + if (!m_configFixed) { + m_jetEtaGhostTracks = eta; + } + } + + inline virtual void ghostTrackspT(const float pt) { + if (!m_configFixed) { + m_ghostTrackspT = pt; + } + } + + inline virtual void ghostTracksVertexAssociation(const std::string& vertexassociation) { + if (!m_configFixed) { + m_ghostTracksVertexAssociation = vertexassociation; + } + } + + inline virtual void ghostTracksQuality(const std::string& ghostTracksQuality) { + if (!m_configFixed) { + m_ghostTracksQuality = ghostTracksQuality; + } + } + + inline virtual float jetPtcut() const {return m_jetPtcut;} + inline virtual float jetEtacut() const {return m_jetEtacut;} + + inline virtual float ghostTrackspT() const {return m_ghostTrackspT;} + inline virtual const std::string& ghostTracksVertexAssociation() const {return m_ghostTracksVertexAssociation;} + inline virtual const std::string& ghostTracksQuality() const {return m_ghostTracksQuality;} + + inline virtual float jetPtGhostTracks() const {return m_jetPtGhostTracks;} + inline virtual float jetEtaGhostTracks() const {return m_jetEtaGhostTracks;} + + + inline virtual void largeRJetPtcut(const float pt) { + if (!m_configFixed) { + m_largeRJetPtcut = pt; + } + } + + inline virtual void largeRJetEtacut(const float eta) { + if (!m_configFixed) { + m_largeRJetEtacut = eta; + } + } + + inline virtual void largeRJetUncertainties_NPModel(const std::string& largeR_config) { + if (!m_configFixed) { + m_largeRJetUncertainties_NPModel = largeR_config; + } + } + + inline virtual void largeRJetUncertaintiesConfigDir(const std::string& largeRConfigDir) { + if (!m_configFixed) { + m_largeRJetUncertaintiesConfigDir = largeRConfigDir; + } + } + + inline virtual void largeRJESJMSConfig(const std::string& largeR_config) { + if (!m_configFixed) { + m_largeRJESJMSConfig = largeR_config; + } + } + + inline virtual float largeRJetPtcut() const {return m_largeRJetPtcut;} + inline virtual float largeRJetEtacut() const {return m_largeRJetEtacut;} + inline virtual const std::map<std::string,std::string> largeRJetSubstructureVariables() const {return m_largeRJetSubstructureVariables;} + inline virtual const std::string& largeRJetUncertainties_NPModel() const {return m_largeRJetUncertainties_NPModel;} + inline virtual const std::string& largeRJetUncertaintiesConfigDir() const {return m_largeRJetUncertaintiesConfigDir;} + inline virtual const std::string& largeRJESJMSConfig() const {return m_largeRJESJMSConfig;} + + inline virtual void trackJetPtcut(const float pt) { + if (!m_configFixed) { + m_trackJetPtcut = pt; + } + } + + inline virtual void trackJetEtacut(const float eta) { + if (!m_configFixed) { + m_trackJetEtacut = eta; + } + } + + inline virtual float trackJetPtcut() const {return m_trackJetPtcut;} + inline virtual float trackJetEtacut() const {return m_trackJetEtacut;} + + + inline virtual void trackPtcut(const float pt) { + if (!m_configFixed) { + m_trackPtcut = pt; + } + } + + inline virtual void trackEtacut(const float eta) { + if (!m_configFixed) { + m_trackEtacut = eta; + } + } + + inline virtual void trackQuality(const std::string& quality) { + if (!m_configFixed) { + m_trackQuality = quality; + } + } + + + inline virtual const std::string& trackQuality() const {return m_trackQuality;} + inline virtual float trackPtcut() const {return m_trackPtcut;} + inline virtual float trackEtacut() const {return m_trackEtacut;} + + + + + inline virtual float RCJetPtcut() const {return m_RCJetPtcut;} + inline virtual float RCJetEtacut() const {return m_RCJetEtacut;} + inline virtual float RCInputJetPtMin() const {return m_RCInputJetPtMin;} + inline virtual float RCInputJetEtaMax() const {return m_RCInputJetEtaMax;} + inline virtual float RCJetTrimcut() const {return m_RCJetTrimcut;} + inline virtual float RCJetRadius() const {return m_RCJetRadius;} + inline virtual bool useRCJetSubstructure() const {return m_useRCJetSubstructure;} + inline virtual bool useRCJetAdditionalSubstructure() const {return m_useRCJetAdditionalSubstructure;} + + inline virtual void RCJetPtcut(const float pt) { + if (!m_configFixed) { + m_RCJetPtcut = pt; + } + } + + inline virtual void RCJetEtacut(const float eta) { + if (!m_configFixed) { + m_RCJetEtacut = eta; + } + } + + inline virtual void RCInputJetPtMin(const float pt) { + if (!m_configFixed) { + m_RCInputJetPtMin = pt; + } + } + + inline virtual void RCInputJetEtaMax(const float eta) { + if (!m_configFixed) { + m_RCInputJetEtaMax = eta; + } + } + + inline virtual void RCJetTrimcut(const float trim) { + if (!m_configFixed) { + m_RCJetTrimcut = trim; + } + } + + inline virtual void RCJetRadius(const float radius) { + if (!m_configFixed) { + m_RCJetRadius = radius; + } + } + + inline virtual void useRCJetSubstructure(const bool use) { + if (!m_configFixed) { + m_useRCJetSubstructure = use; + } + } + + inline virtual void useRCJetAdditionalSubstructure(const bool use) { + if (!m_configFixed) { + m_useRCJetAdditionalSubstructure = use; + } + } + + inline virtual float VarRCJetPtcut() const {return m_VarRCJetPtcut;} + inline virtual float VarRCJetEtacut() const {return m_VarRCJetEtacut;} + inline virtual float VarRCJetTrimcut() const {return m_VarRCJetTrimcut;} + inline virtual float VarRCJetMaxRadius() const {return m_VarRCJetMaxRadius;} + inline virtual const std::string& VarRCJetRho() const {return m_VarRCJetRho;} + inline virtual const std::string& VarRCJetMassScale() const {return m_VarRCJetMassScale;} + inline virtual bool useVarRCJetSubstructure() const {return m_useVarRCJetSubstructure;} + inline virtual bool useVarRCJetAdditionalSubstructure() const {return m_useVarRCJetAdditionalSubstructure;} + + inline virtual void VarRCJetPtcut(const float pt) { + if (!m_configFixed) { + m_VarRCJetPtcut = pt; + } + } + + inline virtual void VarRCJetEtacut(const float eta) { + if (!m_configFixed) { + m_VarRCJetEtacut = eta; + } + } + + inline virtual void VarRCJetTrimcut(const float trim) { + if (!m_configFixed) { + m_VarRCJetTrimcut = trim; + } + } + + inline virtual void VarRCJetMaxRadius(const float radius) { + if (!m_configFixed) { + m_VarRCJetMaxRadius = radius; + } + } + + inline virtual void VarRCJetRho(const std::string& rho) { + if (!m_configFixed) { + m_VarRCJetRho = rho; + } + } + + inline virtual void VarRCJetMassScale(const std::string& mass_scale) { + if (!m_configFixed) { + m_VarRCJetMassScale = mass_scale; + } + } + + inline virtual void useVarRCJetSubstructure(const bool use) { + if (!m_configFixed) { + m_useVarRCJetSubstructure = use; + } + } + + inline virtual void useVarRCJetAdditionalSubstructure(const bool use) { + if (!m_configFixed) { + m_useVarRCJetAdditionalSubstructure = use; + } + } + + + virtual void jetUncertainties_NPModel(const std::string& s); + virtual void jetUncertainties_QGFracFile(const std::string& s); + virtual void jetUncertainties_QGHistPatterns(const std::string& s); + inline bool doMultipleJES() const {return m_doMultipleJES;} + inline virtual const std::string& jetUncertainties_NPModel() const {return m_jetUncertainties_NPModel;} + inline virtual const std::string& jetUncertainties_QGFracFile() const {return m_jetUncertainties_QGFracFile;} + inline virtual const std::vector<std::string>& jetUncertainties_QGHistPatterns() const { + return m_jetUncertainties_QGHistPatterns; + } + + inline virtual void jetJERSmearingModel(const std::string& s) { + if (!m_configFixed) { + m_jetJERSmearingModel = s; + } + } + + inline virtual const std::string& jetJERSmearingModel() const {return m_jetJERSmearingModel;} + + inline virtual void jetCalibSequence(const std::string& s) { + if (!m_configFixed) { + m_jetCalibSequence = s; + } + } + + inline virtual const std::string& jetCalibSequence() const {return m_jetCalibSequence;} + + inline virtual void jetStoreTruthLabels(bool b) { + if (!m_configFixed) { + m_jetStoreTruthLabels = b; + } + } + + inline virtual bool jetStoreTruthLabels() const {return m_jetStoreTruthLabels;} + + inline virtual void doJVTinMET(const bool& doJVT) { + if (!m_configFixed) { + m_doJVTInMETCalculation = doJVT; + } + } + + inline virtual bool doJVTinMET() const {return m_doJVTInMETCalculation;} + inline virtual void saveFailJVTJets(const bool& doJVT) { + if (!m_configFixed) { + m_saveFailJVTJets = doJVT; + } + } + + inline virtual bool saveFailJVTJets() const {return m_saveFailJVTJets;} + + inline const std::string& getJVTWP() const {return m_JVTWP;} + inline void setJVTWP(const std::string& value) {m_JVTWP = value;} + + inline virtual void doForwardJVTinMET(const bool& dofJVT) { + if (!m_configFixed) { + m_doForwardJVTInMETCalculation = dofJVT; + } + } + + inline virtual bool doForwardJVTinMET() const {return m_doForwardJVTInMETCalculation;} + inline virtual void saveFailForwardJVTJets(const bool& dofJVT) { + if (!m_configFixed) { + m_saveFailForwardJVTJets = dofJVT; + } + } + + inline virtual bool saveFailForwardJVTJets() const {return m_saveFailForwardJVTJets;} + + inline const std::string& getfJVTWP() const {return m_fJVTWP;} + inline void setfJVTWP(const std::string& value) {m_fJVTWP = value;} + + inline virtual float JSF() const {return m_JSF;} + inline virtual float bJSF() const {return m_bJSF;} + + // MET Configuration + inline virtual void METUncertaintiesConfigDir(const std::string& METConfigDir) { + if (!m_configFixed) { + m_METUncertaintiesConfigDir = METConfigDir; + } + } + inline virtual const std::string& METUncertaintiesConfigDir() const {return m_METUncertaintiesConfigDir;} + + // Tau configuration setters + inline virtual void tauPtcut(const float pt) { + if (!m_configFixed) { + m_tau_configuration.pt = pt; + m_tau_configuration_loose.pt = pt; + } + } + + inline virtual void tauEtaRegions(const std::string& etaRegions) { + if (!m_configFixed) { + m_tau_configuration.etaRegions = etaRegions; + m_tau_configuration_loose.etaRegions = etaRegions; + } + } + + inline virtual void tauJetIDWP(const std::string& s) { + if (!m_configFixed) m_tau_configuration.jetIDWP = s; + } + + inline virtual void tauJetIDWPLoose(const std::string& s) { + if (!m_configFixed) m_tau_configuration_loose.jetIDWP = s; + } + + inline virtual void tauEleBDTWP(const std::string& s) { + if (!m_configFixed) m_tau_configuration.eleBDTWP = s; + } + + inline virtual void tauEleBDTWPLoose(const std::string& s) { + if (!m_configFixed) m_tau_configuration_loose.eleBDTWP = s; + } + + inline virtual void tauEleOLR(bool do_tau_ele_olr) { + if (!m_configFixed) m_tau_configuration.eleOLR = do_tau_ele_olr; + } + + inline virtual void tauEleOLRLoose(bool do_tau_ele_olr) { + if (!m_configFixed) m_tau_configuration_loose.eleOLR = do_tau_ele_olr; + } + + inline virtual void tauSFDoRNNID(bool do_tau_rnn_id) { + if (!m_configFixed) m_tau_configuration.doRNNID = do_tau_rnn_id; + } + + inline virtual void tauSFDoBDTID(bool do_tau_bdt_id) { + if (!m_configFixed) m_tau_configuration.doBDTID = do_tau_bdt_id; + } + + inline virtual void tauJetConfigFile(const std::string& s) { + if (!m_configFixed) m_tau_configuration.fileName = s; + } -std::ostream& operator<<(std::ostream& os, const top::TopConfig& config); + inline virtual void tauJetConfigFileLoose(const std::string& s) { + if (!m_configFixed) m_tau_configuration_loose.fileName = s; + } + + inline virtual void tauSubstructureSF(bool do_tau_substructure_sf) { + if (!m_configFixed) m_tau_configuration.substructureSF = do_tau_substructure_sf; + } + + inline virtual void tauSubstructureSFLoose(bool do_tau_substructure_sf) { + if (!m_configFixed) m_tau_configuration_loose.substructureSF = do_tau_substructure_sf; + } + + // Tau configuration getters + inline virtual float tauPtcut() const { + return m_tau_configuration.pt; + } + + inline const std::string& tauEtaRegions() const { + return m_tau_configuration.etaRegions; + } + + inline const std::string& tauJetIDWP() const { + return m_tau_configuration.jetIDWP; + } + + inline const std::string& tauJetIDWPLoose() const { + return m_tau_configuration_loose.jetIDWP; + } + + inline const std::string& tauEleBDTWP() const { + return m_tau_configuration.eleBDTWP; + } + + inline const std::string& tauEleBDTWPLoose() const { + return m_tau_configuration_loose.eleBDTWP; + } + + inline virtual bool tauEleOLR() { + return m_tau_configuration.eleOLR; + } + + inline virtual bool tauEleOLRLoose() { + return m_tau_configuration_loose.eleOLR; + } + + inline const std::string& tauJetConfigFile() { + return m_tau_configuration.fileName; + } + + inline const std::string& tauJetConfigFileLoose() { + return m_tau_configuration_loose.fileName; + } + + inline virtual bool tauSubstructureSF() { + return m_tau_configuration.substructureSF; + } + + inline virtual bool tauSubstructureSFLoose() { + return m_tau_configuration_loose.substructureSF; + } + + // Applying new tau energy calibration + inline bool applyTauMVATES() { + return true; + } + + inline bool tauSFDoRNNID() const { + return m_tau_configuration.doRNNID; + } + + inline bool tauSFDoBDTID() const { + return m_tau_configuration.doBDTID; + } + + // photon getters + inline virtual float photonPtcut() const { + return m_photon_configuration.pt; + } + + inline virtual float photonEtacut() const { + return m_photon_configuration.eta; + } + + inline const std::string& photonIdentification() { + return m_photon_configuration.identification; + } + + inline const std::string& photonIdentificationLoose() { + return m_photon_configuration_loose.identification; + } + + inline const std::string& photonIsolation() { + return m_photon_configuration.isolation; + } + + inline const std::string& photonIsolationLoose() { + return m_photon_configuration_loose.isolation; + } + + // inline const std::string& tauJetID() const {return m_tauJetID;} + // inline const std::string& tauJetIDBkg() const {return m_tauJetIDBkg;} + // inline const std::string& tauEVetoID() const {return m_tauEVetoID;} + // inline virtual bool tauVetoLArCrack() const {return m_tauVetoLArCrack;} + // inline virtual float tauPtcut() const {return m_tauPtcut;} + + // [[[----------------------------------------------- + // Particle Level (Truth) configuration + + // electrons + inline virtual void truth_electron_PtCut(const float pt) { + if (!m_configFixed) { + m_truth_electron.PtCut = pt; + } + } + + inline virtual void truth_electron_EtaCut(const float eta) { + if (!m_configFixed) { + m_truth_electron.EtaCut = eta; + } + } + + inline virtual float truth_electron_PtCut() const {return m_truth_electron.PtCut;} + inline virtual float truth_electron_EtaCut() const {return m_truth_electron.EtaCut;} + inline virtual bool truth_electron_NotFromHadron() const {return m_truth_electron.NotFromHadron;} + inline virtual bool truth_electron_TauIsHadron() const {return m_truth_electron.TauIsHadron;} + + // muons + inline virtual void truth_muon_PtCut(const float pt) { + if (!m_configFixed) { + m_truth_muon.PtCut = pt; + } + } + + inline virtual void truth_muon_EtaCut(const float eta) { + if (!m_configFixed) { + m_truth_muon.EtaCut = eta; + } + } + + inline virtual float truth_muon_PtCut() const {return m_truth_muon.PtCut;} + inline virtual float truth_muon_EtaCut() const {return m_truth_muon.EtaCut;} + inline virtual bool truth_muon_NotFromHadron() const {return m_truth_muon.NotFromHadron;} + inline virtual bool truth_muon_TauIsHadron() const {return m_truth_muon.TauIsHadron;} + + // soft muons + inline virtual void truth_softmuon_PtCut(const float pt) { + if (!m_configFixed) { + m_truth_softmuon.PtCut = pt; + } + } + + inline virtual void truth_softmuon_EtaCut(const float eta) { + if (!m_configFixed) { + m_truth_softmuon.EtaCut = eta; + } + } + + inline virtual float truth_softmuon_PtCut() const {return m_truth_softmuon.PtCut;} + inline virtual float truth_softmuon_EtaCut() const {return m_truth_softmuon.EtaCut;} + + // photons + inline virtual void truth_photon_PtCut(const float pt) { + if (!m_configFixed) { + m_truth_photon.PtCut = pt; + } + } + + inline virtual void truth_photon_EtaCut(const float eta) { + if (!m_configFixed) { + m_truth_photon.EtaCut = eta; + } + } + + inline virtual void truth_photon_Origin(const std::string& value) { + if (!m_configFixed) { + m_truth_photon.Origin = value; + } + } + + inline virtual void truth_photon_Isolation(const std::string& value) { + if (!m_configFixed) { + m_truth_photon.Isolation = value; + } + } + + inline virtual float truth_photon_PtCut() const {return m_truth_photon.PtCut;} + inline virtual float truth_photon_EtaCut() const {return m_truth_photon.EtaCut;} + inline virtual const std::string& truth_photon_Origin() const {return m_truth_photon.Origin;} + inline virtual const std::string& truth_photon_Isolation() const {return m_truth_photon.Isolation;} + + // jets + inline virtual void truth_jet_PtCut(const float pt) { + if (!m_configFixed) { + m_truth_jet.PtCut = pt; + } + } + + inline virtual void truth_jet_EtaCut(const float eta) { + if (!m_configFixed) { + m_truth_jet.EtaCut = eta; + } + } + + inline virtual float truth_jet_PtCut() const {return m_truth_jet.PtCut;} + inline virtual float truth_jet_EtaCut() const {return m_truth_jet.EtaCut;} + + // large R jets + inline virtual void truth_jet_largeR_PtCut(const float pt) { + if (!m_configFixed) { + m_truth_largeRJet.PtCut = pt; + } + } + + inline virtual void truth_jet_largeR_EtaCut(const float eta) { + if (!m_configFixed) { + m_truth_largeRJet.EtaCut = eta; + } + } + + inline virtual float truth_jet_largeR_PtCut() const {return m_truth_largeRJet.PtCut;} + inline virtual float truth_jet_largeR_EtaCut() const {return m_truth_largeRJet.EtaCut;} + + inline virtual void truth_tau_PtCut(const float pt) { + if (!m_configFixed) { + m_truth_tau.PtCut = pt; + } + } + + inline virtual void truth_tau_EtaCut(const float eta) { + if (!m_configFixed) { + m_truth_tau.EtaCut = eta; + } + } + + inline virtual float truth_tau_PtCut() const {return m_truth_tau.PtCut;} + inline virtual float truth_tau_EtaCut() const {return m_truth_tau.EtaCut;} + + // -----------------------------------------------]]] + + /// HL LHC studies + inline virtual void HLLHC(const bool s) { + if (!m_configFixed) { + m_HLLHC = s; + } + } + + inline virtual bool HLLHC() const {return m_HLLHC;} + inline virtual void HLLHCFakes(const bool s) { + if (!m_configFixed) { + m_HLLHCFakes = s; + } + } + + inline virtual bool HLLHCFakes() const {return m_HLLHCFakes;} + + void setBTaggingSFSysts(std::string WP, const std::set<std::string>& btagging_SFs, bool isTrackJet = false); + + inline virtual std::set<std::string> btagging_namedSysts(std::string WP) const {return bTag_named_systs.at(WP);} + inline virtual unsigned int btagging_num_B_eigenvars(std::string WP) const {return bTag_eigen_B.at(WP);} + inline virtual unsigned int btagging_num_C_eigenvars(std::string WP) const {return bTag_eigen_C.at(WP);} + inline virtual unsigned int btagging_num_Light_eigenvars(std::string WP) const {return bTag_eigen_light.at(WP);} + + inline virtual std::set<std::string> trkjet_btagging_namedSysts(std::string WP) const {return bTag_named_systs_trkJet.at(WP);} + inline virtual unsigned int trkjet_btagging_num_B_eigenvars(std::string WP) const {return bTag_eigen_B_trkJet.at(WP);} + inline virtual unsigned int trkjet_btagging_num_C_eigenvars(std::string WP) const {return bTag_eigen_C_trkJet.at(WP);} + inline virtual unsigned int trkjet_btagging_num_Light_eigenvars(std::string WP) const {return bTag_eigen_light_trkJet.at(WP);} + + + const std::vector<std::pair<std::string, std::string> > boostedJetTaggers() const {return m_chosen_boostedJetTaggers;} + const std::unordered_map<std::string, std::string> boostedTaggerSFnames() const {return m_boostedTaggerSFnames;} + void setCalibBoostedJetTagger(const std::string& WP, const std::string& SFname); + // B-tagging WPs requested by user (updated to pair of strings to hold algorithm and WP) + const std::vector<std::pair<std::string, std::string> > bTagWP() const {return m_chosen_btaggingWP_caloJet;} + const std::vector<std::pair<std::string, std::string> > bTagWP_trkJet() const {return m_chosen_btaggingWP_trkJet;} + // parse b-tagging configuration from config file into a vector of pair <algorithm, WP> + void parse_bTagWPs(const std::string& btagWPsettingString, + std::vector<std::pair<std::string, std::string>>& btagWPlist, + const std::string& jetCollectionName); + // B-tagging systematics requested by user to be excluded from EV treatment, separated by semi-colons + const std::string bTagSystsExcludedFromEV() const {return m_bTagSystsExcludedFromEV;} + + // B-tagging WPs actually available, according to CDI file + // will be set in TopCPTools + void setBTagWP_available(std::string btagging_WP); + void setBTagWP_available_trkJet(std::string btagging_WP); + const std::vector<std::string>& bTagWP_available() const {return m_available_btaggingWP;} + const std::vector<std::string>& bTagWP_available_trkJet() const {return m_available_btaggingWP_trkJet;} + // B-tagging WPs actually calibrated, according to CDI file + // will be set in TopCPTools + void setBTagWP_calibrated(std::string btagging_WP); + void setBTagWP_calibrated_trkJet(std::string btagging_WP); + const std::vector<std::string>& bTagWP_calibrated() const {return m_calibrated_btaggingWP;} + const std::vector<std::string>& bTagWP_calibrated_trkJet() const {return m_calibrated_btaggingWP_trkJet;} + // B-tagging algorithms, e.g. DL1, DL1r, DL1rmu + // which of them can be initialized for the given CDI file + // used for e.g. storing algorithm discriminant in the event saver + void setBTagAlgo_available(std::string algo, std::string toolName); + void setBTagAlgo_available_trkJet(std::string algo, std::string toolName); + const std::set<std::string>& bTagAlgo_available() const {return m_available_btaggingAlgos;} + const std::set<std::string>& bTagAlgo_available_trkJet() const {return m_available_btaggingAlgos_trkJet;} + // since MV2c10 is the only non-DL1 b-tagger, we just expose a bool to check if MV2c10 is used or not + bool bTagAlgo_MV2c10_used() const {return m_MV2c10_algo_used;} + bool bTagAlgo_MV2c10_used_trkJet() const {return m_MV2c10_algo_used_trkJet;} + + const std::unordered_map<std::string, std::string>& bTagAlgo_selToolNames() const {return m_algo_selTools;} + const std::unordered_map<std::string, std::string>& bTagAlgo_selToolNames_trkJet() const {return m_algo_selTools_trkJet;} + + std::string FormatedWP(std::string raw_WP); + + bool printCDIpathWarning() const + {return m_cdi_path_warning;} + void setPrintCDIpathWarning(bool flag) + {m_cdi_path_warning = flag;} + const std::string bTaggingCDIPath() const + {return m_btagging_cdi_path;} + const std::string& bTaggingCalibration_B() const + {return m_btagging_calibration_B;}; + const std::string& bTaggingCalibration_C() const + {return m_btagging_calibration_C;}; + const std::string& bTaggingCalibration_Light() const + {return m_btagging_calibration_Light;}; + + // LHAPDF settings + + inline virtual std::vector<std::string> LHAPDFSets() {return m_lhapdf_options.pdf_set_names;} + inline virtual bool doLHAPDF() {return m_lhapdf_options.doLHAPDF;} + inline virtual std::string baseLHAPDF() {return m_lhapdf_options.baseLHAPDF;} + inline virtual bool doLHAPDFInNominalTrees() {return m_lhapdf_options.doLHAPDFInNominalTrees;} + inline virtual bool saveLHAPDFEvent() {return m_lhapdf_options.save_per_event;} + void addLHAPDFResult(const std::string& pdf_name, + std::vector<float> sum_of_weights); + + std::unordered_map<std::string, std::vector<float> >& getLHAPDFResults() {return m_lhapdf_options.pdf_results;}; + + + // Pileup Reweighting Settings + bool doPileupReweighting() {return m_pileup_reweighting.apply;}; + bool PileupUseGRLTool() {return m_pileup_reweighting.use_grl_tool;}; + + const std::vector<std::string>& PileupConfig() {return m_pileup_reweighting.config_files;}; + const std::vector<std::string>& PileupLumiCalc() {return m_pileup_reweighting.lumi_calc_files;}; + + bool PileupMuDependent() {return m_pileup_reweighting.mu_dependent;}; + + // Update for R21 + const std::vector<std::string>& PileupConfig_FS() {return m_pileup_reweighting.config_files_FS;}; + const std::vector<std::string>& PileupConfig_AF() {return m_pileup_reweighting.config_files_AF;}; + const std::vector<std::string>& PileupActualMu_FS() {return m_pileup_reweighting.actual_mu_FS;}; + const std::vector<std::string>& PileupActualMu_AF() {return m_pileup_reweighting.actual_mu_AF;}; + inline virtual float PileupDataTolerance() const {return m_pileup_reweighting.unrepresented_data_tol;}; + const std::vector<int>& PileupPeriodAssignments() const {return m_pileup_reweighting.periodAssignments;}; + + const std::vector<double>& PileUpCustomScaleFactors() {return m_pileup_reweighting.custom_SF;}; + + inline const std::string& muonTriggerSF() const {return m_muon_trigger_SF;} + + inline bool demandPriVtx() const {return m_demandPriVtx;} + + // Where the sum of event weights + // before derivation framework is kept + inline const std::string& sumOfEventWeightsMetaData() const {return m_sumOfEventWeightsMetaData;} + + // Object Selector Name + inline virtual void objectSelectionName(const std::string& s) { + if (!m_configFixed) { + m_objectSelectionName = s; + } + } + + inline virtual const std::string& objectSelectionName() const {return m_objectSelectionName;} + // Output Format + inline virtual void outputFormat(const std::string& s) { + if (!m_configFixed) { + m_outputFormat = s; + } + } + + inline virtual const std::string& outputFormat() const {return m_outputFormat;} + // Output Events + virtual void outputEvents(const std::string& s); + inline virtual const std::string& outputEvents() const {return m_outputEvents;} + inline bool saveOnlySelectedEvents() const {return m_saveOnlySelectedEvents;} + + // SetAutoFlush(0) on EventSaverFlatNtuple for ANALYSISTO-44 workaround + inline bool outputFileSetAutoFlushZero() const {return m_outputFileSetAutoFlushZero;} + // Better configurable settings for TTree memory optimisation (ANALYSISTO-44, ANALYSISTO-463) + inline int outputFileNEventAutoFlush() const {return m_outputFileNEventAutoFlush;} + inline int outputFileBasketSizePrimitive() const {return m_outputFileBasketSizePrimitive;} + inline int outputFileBasketSizeVector() const {return m_outputFileBasketSizeVector;} + + // Number of events to run on (only for testing) + inline virtual unsigned int numberOfEventsToRun() const {return m_numberOfEventsToRun;} + inline virtual void numberOfEventsToRun(const unsigned int& n_events) { + if (!m_configFixed) { + m_numberOfEventsToRun = n_events; + } + } + + // Number of events to skip (only for testing) + inline virtual unsigned int numberOfEventsToSkip() const {return m_numberOfEventsToSkip;} + inline virtual void numberOfEventsToSkip(const unsigned int& n_events) { + if (!m_configFixed) { + m_numberOfEventsToSkip = n_events; + } + } + + // systematics + inline virtual void systematics(const std::string& s) { + if (!m_configFixed) { + m_systematics = s; + } + } + + inline virtual const std::string& systematics() const {return m_systematics;} + + /// syst helper functions + bool isSystNominal(const std::string& syst) const; + bool isSystAll(const std::string& syst) const; + bool getSystematicsList(const std::string& syst, std::set<std::string>& systList) const; + bool contains(const std::set<std::string>& systList, const std::string& name) const; + + virtual void systematicsPhotons(const std::list<CP::SystematicSet>& syst); + virtual void systematicsElectrons(const std::list<CP::SystematicSet>& syst); + virtual void systematicsFwdElectrons(const std::list<CP::SystematicSet>& syst); + virtual void systematicsMuons(const std::list<CP::SystematicSet>& syst); + virtual void systematicsSoftMuons(const std::list<CP::SystematicSet>& syst); + virtual void systematicsTaus(const std::list<CP::SystematicSet>& syst); + virtual void systematicsJets(const std::list<CP::SystematicSet>& syst); + virtual void systematicsLargeRJets(const std::list<CP::SystematicSet>& syst); + virtual void systematicsTrackJets(const std::list<CP::SystematicSet>& syst); + virtual void systematicsTracks(const std::list<CP::SystematicSet>& syst); + virtual void systematicsMET(const std::list<CP::SystematicSet>& syst); + + virtual void systematicsJetGhostTrack(const std::list<CP::SystematicSet>& syst); + + inline virtual void jetSubstructureName(const std::string& s) { + if (!m_configFixed) { + m_jetSubstructureName = s; + } + } + + inline virtual const std::string& jetSubstructureName() const {return m_jetSubstructureName;} + + // Systematic hash values + inline std::size_t nominalHashValue() const {return m_nominalHashValue;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashPhotons() const {return m_systHashPhotons;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashElectrons() const {return m_systHashElectrons;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashFwdElectrons() const {return m_systHashFwdElectrons;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashMuons() const {return m_systHashMuons;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashSoftMuons() const {return m_systHashSoftMuons;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashTaus() const {return m_systHashTaus;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashJets() const {return m_systHashJets;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashAll() const {return m_systHashAll;} + inline std::shared_ptr<std::unordered_set<std::size_t> > systHashElectronInJetSubtraction() const {return m_systHash_electronInJetSubtraction;} + + // Systematic Maps + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapPhotons() const {return m_systMapPhotons;} + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapElectrons() const {return m_systMapElectrons;} + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapFwdElectrons() const {return m_systMapFwdElectrons;} + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapMuons() const {return m_systMapMuons;} + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapSoftMuons() const {return m_systMapSoftMuons;} + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapTaus() const {return m_systMapTaus;} + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapJets() const {return m_systMapJets;} + inline std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > systMapLargeRJets() const {return m_systMapLargeRJets;} + + // Systematic StoreGate key Maps + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapPhotons() const {return m_systSgKeyMapPhotons;} + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapElectrons() const {return m_systSgKeyMapElectrons;} + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapFwdElectrons() const {return m_systSgKeyMapFwdElectrons;} + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapMuons() const {return m_systSgKeyMapMuons;} + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapSoftMuons() const {return m_systSgKeyMapSoftMuons;} + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapTaus() const {return m_systSgKeyMapTaus;} + std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapJets(const bool useLooseLeptonJets) const; + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapLargeRJets() const {return m_systSgKeyMapLargeRJets;} + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapTrackJets() const {return m_systSgKeyMapTrackJets;} + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systSgKeyMapTracks() const {return m_systSgKeyMapTracks;} + + // TTree names + inline std::shared_ptr<std::unordered_map<std::size_t, std::string> > systAllTTreeNames() const {return m_systAllTTreeNames;} + const std::string& systematicName(const std::size_t hash) const; + // TTree index + unsigned int ttreeIndex(const std::size_t hash) const; + unsigned int ttreeIndexLoose(const std::size_t hash) const; + + AodMetaDataAccess& aodMetaData(); + AodMetaDataAccess const& aodMetaData() const {return *m_aodMetaData;} + + // Function to handle release series such that it can be cleaner to update in the future + void setReleaseSeries(); + inline int getReleaseSeries() const {return m_release_series;} + + // Create bootstrapping weights + inline bool saveBootstrapWeights() const {return m_saveBootstrapWeights;} + inline void setSaveBootstrapWeights(const bool value) {m_saveBootstrapWeights = value;} + inline int getNumberOfBootstrapReplicas() const {return m_BootstrapReplicas;} + inline void setNumberOfBootstrapReplicas(const int value) {m_BootstrapReplicas = value;} + + // Switch to use BadBatmanCleaning + inline bool useBadBatmanCleaning() const {return m_useBadBatmanCleaning;} + inline void setUseBadBatmanCleaning(const bool value) {m_useBadBatmanCleaning = value;} + inline unsigned int badBatmanCleaningMin() const {return m_badBatmanCleaningMin;} + inline void setBadBatmanCleaningMin(const unsigned int value) {m_badBatmanCleaningMin = value;} + inline unsigned int badBatmanCleaningMax() const {return m_badBatmanCleaningMax;} + inline void setBadBatmanCleaningMax(const unsigned int value) {m_badBatmanCleaningMax = value;} + + // Switch to use event-level jet cleaning tool for studies + inline bool useEventLevelJetCleaningTool() const {return m_useEventLevelJetCleaningTool;} + inline void setUseEventLevelJetCleaningTool(const bool value) {m_useEventLevelJetCleaningTool = value;} + + // Just a function that might need to be used in multiple places - return the running year (2015, 2016, 2017) + std::string getYear(unsigned int runnumber, const bool isMC); + + const std::string& getYear(){return m_year;} + void SetYear(const std::string& year){m_year = year;} + + void SetTriggersToYear(const bool isMC); + + // Setter and getter functions for recording whether we have configured the nominal objects + inline virtual void setNominalAvailable(const bool s) {m_isNominalAvailable = s;} + inline bool isNominalAvailable() const {return m_isNominalAvailable;} + + // Function to set the options for global trigger tool + void setGlobalTriggerConfiguration(std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::string>); + inline bool useGlobalTrigger() const {return m_trigGlobalConfiguration.isActivated;} // Was this requested by the + // user + inline auto const& getGlobalTriggers() const {return m_trigGlobalConfiguration.trigger;} + inline auto const& getGlobalTriggersLoose() const {return m_trigGlobalConfiguration.trigger_loose;} + inline bool useGlobalTriggerConfiguration() const {return m_trigGlobalConfiguration.isConfigured;} // Was this + // subsequently + // configured + inline std::vector<std::string> getGlobalTriggerElectronSystematics() const {return m_trigGlobalConfiguration.electron_trigger_systematics;} + inline std::vector<std::string> getGlobalTriggerMuonSystematics() const {return m_trigGlobalConfiguration.muon_trigger_systematics;} + inline std::vector<std::string> getGlobalTriggerElectronTools() const {return m_trigGlobalConfiguration.electron_trigger_tool_names;} + inline std::vector<std::string> getGlobalTriggerMuonTools() const {return m_trigGlobalConfiguration.muon_trigger_tool_names;} + + inline const TreeFilter* getTreeFilter() const { return m_treeFilter.get();} + + inline const std::unordered_map<std::string, std::string>& GetMCMCTranslator() const {return m_showerMCMCtranslator;} + + private: + // Prevent any more configuration + bool m_configFixed; + + // Make all CP Tools, or just the SF + bool m_makeAllCPTools; + + // GRL file + std::string m_grlDir; + std::vector<std::string> m_grlFile = {}; + + // TDP + std::string m_topDataPreparationPath; + + // Use which objects + bool m_usePhotons; + bool m_useElectrons; + bool m_useFwdElectrons; + bool m_useMuons; + bool m_useSoftMuons; + bool m_useAntiMuons; + bool m_useTaus; + bool m_useJets; + bool m_useLargeRJets; + bool m_useTrackJets; + bool m_useRCJets; + bool m_useVarRCJets; + + // Ghost Tracks on jets can not really be disabled because they are always + // available. However, we want the systematics to be executed automatically + // whenever the user has "configured" ghost tracks. + bool m_useJetGhostTrack; + + bool m_useTracks; + + // Are we using particle flow jets + // Need this as some things aren't supported at the moment + // C++11 so nice inline initialization (we should make this consistent) + bool m_useParticleFlowJets = false; + + bool m_useTruthParticles; + bool m_useTruthElectrons; + bool m_useTruthMuons; + bool m_useTruthPhotons; + bool m_useTruthJets; + bool m_useTruthLargeRJets; + bool m_useTruthTaus; + bool m_useTruthMET; + + // define if d0/z0 cut should be used at all + bool m_applyTTVACut; + + bool m_demandPriVtx; // whether at leas one primary vertex is required for each event + + std::string m_jetSubstructureName; + + // recompute CP vars? + bool m_recomputeCPvars; + + // Store in config a boolean which lets us know if we called the nominal object setup + bool m_isNominalAvailable; + + // Do systematics? - this needs many more configuration options + std::string m_systematics; + std::string m_nominalSystName; + std::string m_allSystName; + + unsigned int m_DSID; + unsigned int m_MapIndex; + SampleXsection::showering m_showeringAlgo; + bool m_is_sherpa_22_vjets = false; + + bool m_isMC; + bool m_isAFII; + std::vector<std::string> m_filterBranches, m_filterPartonLevelBranches, m_filterParticleLevelBranches, m_filterNominalLooseBranches; + std::string m_generators; + std::string m_AMITag; + bool m_isPrimaryxAOD; + bool m_isTruthDxAOD = false; + std::string m_derivationStream; + std::string m_amiTag; + int m_amiTagSet = 0; + + // Do fakes MM weights calculation? - only for data loose + bool m_doFakesMMWeightsIFF; + // Configurations for MM fake estimate + std::string m_FakesMMConfigIFF; + // Debug mode? + bool m_doFakesMMIFFDebug; + + //options to select if you want to use loose objects for MET rebuilding instead of the tight ones + bool m_useLooseObjectsInMETInLooseTree; + bool m_useLooseObjectsInMETInNominalTree; + //this will write a separate branch with the met built using loose objects + bool m_writeMETBuiltWithLooseObjects; + + // By default the top group does overlap removal on + // the tight lepton definitions. + // If you turn this to true you are going off piste and need to report + // your findings to the top reconstruction meeting. + bool m_doOverlapRemovalOnLooseLeptonDef; + + // String to describe which overlap removal procedure is used + // Current options are whether to use the ASG recommended + // overlap removal (recommended) + // procedure, or the one developed by the harmonization + // task force and use throughout 2015 (harmonized) + std::string m_overlap_removal_procedure = "recommended"; + + float m_overlapRemovalSlidingInnerDRel = 0.2; + float m_overlapRemovalSlidingInnerDRmu = 0.2; + + // do overlap removal also with large-R jets + // (using whatever procedure is used in the official tools) + bool m_doLargeJetOverlapRemoval; + + // Dumps the normal, non-"*_Loose" trees (on demand) + bool m_doTightEvents; + // Dumps the "*_Loose trees (on demand) + bool m_doLooseEvents; + + // Run systematics on the given selection + bool m_doTightSysts; + bool m_doLooseSysts; + + // In the *_Loose trees, lepton SFs are calculated considering + // tight ID and isolation instead of loose + // Only tight leptons are considered in the event SF calculation + bool m_applyTightSFsInLooseTree; + + // Apply Electron In Jet subtraction + // For boosted analysis + bool m_applyElectronInJetSubtraction; + + // Write Truth block info + bool m_doTruthBlockInfo; + + // Write Truth PDF info + bool m_doTruthPDFInfo; + bool m_doTruthPDFInfoInNominalTrees; + + // Write MC generator weights + bool m_doMCGeneratorWeights; + bool m_doMCGeneratorWeightsInNominalTrees; + + // list of names of nominal weight + // attempts to find nominal weight in the order as specified here + std::vector<std::string> m_nominalWeightNames; + std::string m_nominalWeightName; + size_t m_nominalWeightIndex; + size_t m_MCweightsSize; + bool m_forceWeightIndex; // to force useage of index instead of metadata + + // Top Parton History + bool m_doTopPartonHistory; + bool m_isTopPartonHistoryRegisteredInNtuple; + bool m_doTopPartonLevel; + + // Top Particle Level + bool m_doTopParticleLevel; + bool m_doParticleLevelOverlapRemovalMuJet; + bool m_doParticleLevelOverlapRemovalElJet; + bool m_doParticleLevelOverlapRemovalJetPhoton; + + // KLFitter + bool m_doKLFitter; + std::string m_KLFitterTransferFunctionsPath; + std::string m_KLFitterOutput; + std::string m_KLFitterJetSelectionMode; + std::string m_KLFitterBTaggingMethod; + std::string m_KLFitterLH; + bool m_KLFitterTopMassFixed; + bool m_KLFitterSaveAllPermutations; + bool m_KLFitterFailOnLessThanXJets; + + // PseudoTop + bool m_doPseudoTop; + + // StoreGate / TStore keys + std::string m_sgKeyDummy; + std::string m_sgKeyEventInfo; + std::string m_sgKeyPrimaryVertices; + std::string m_sgKeyPhotons; + std::string m_sgKeyElectrons; + std::string m_sgKeyFwdElectrons; + std::string m_sgKeyMuons; + std::string m_sgKeySoftMuons; + std::string m_sgKeyTaus; + std::string m_sgKeyJets; + std::string m_sgKeyJetsType; + std::string m_sgKeyLargeRJets; + std::string m_sgKeyTrackJets; + std::string m_sgKeyTrackJetsType; + + std::string m_sgKeyMissingEt; + std::string m_sgKeyMissingEtLoose; + + std::string m_sgKeyTruthEvent; + std::string m_sgKeyMCParticle; + std::string m_sgKeyTruthPhotons; + std::string m_sgKeyTruthElectrons; + std::string m_sgKeyTruthMuons; + std::string m_sgKeyTruthTaus; + std::string m_sgKeyTruthJets; + std::string m_sgKeyTruthLargeRJets; + std::string m_sgKeyTruthMET; + std::string m_sgKeyTopPartonHistory; + + std::string m_sgKeyTopSystematicEvents; + std::string m_sgKeyTopSystematicEventsLoose; + std::string m_passEventSelectionDecoration; + + std::string m_decoKeyJetGhostTrack; + std::vector<std::string> m_jetGhostTrackSystematics; + std::vector<std::uint32_t> m_jetGhostTrackRunPeriods; + + std::string m_sgKeyInDetTrackParticles; + std::string m_sgKeyTracks; + std::string m_sgKeyTracksType; + std::vector<std::uint32_t> m_trackRunPeriods; + + + + float m_jetResponseMatchingDeltaR; + + // special: allow to dump the systematics-shifted b-tagging SFs in the systematics trees + bool m_dumpBtagSystsInSystTrees; + + bool m_storePerJetBtagSFs; + + // Electron configuration + std::string m_egammaSystematicModel; + std::string m_electronEfficiencySystematicModel; + std::string m_electronEfficiencySystematicModelEtaBinning; + std::string m_electronEfficiencySystematicModelEtBinning; + std::string m_electronID; + std::string m_electronIDLoose; + bool m_electronVetoLArCrack; + float m_electronPtcut; + std::string m_electronIsolation; + std::string m_electronIsolationLoose; + std::string m_electronIsolationSF; + std::string m_electronIsolationSFLoose; + bool const m_electronIsoSFs; // no longer supported, always true (use m_electronIsolationSF instead) + int m_electron_d0SigCut; + float m_electron_delta_z0; + + std::string m_electronIDDecoration; + std::string m_electronIDLooseDecoration; + bool m_useElectronChargeIDSelection; + bool m_useEgammaLeakageCorrection; + bool m_enablePromptLeptonImprovedVetoStudies; + + //Fwd electron configuration + float m_fwdElectronPtcut; + float m_fwdElectronMinEtacut; + float m_fwdElectronMaxEtacut; + std::string m_fwdElectronID; + std::string m_fwdElectronIDLoose; + int m_fwdElectronBCIDCleaningMinRun; + int m_fwdElectronBCIDCleaningMaxRun; + + // Muon configuration + float m_muonPtcut; // muon object selection pT cut + float m_muonEtacut; // muon object selection (abs) eta cut + std::string m_muonQuality; // muon quality used in object selection + bool m_muonUseMVALowPt; //to turn on MVA for low-pT muons + bool m_muonUse2stationMuonsHighPt; //to allow muon reco with 2-station + std::string m_muonQualityLoose; // loose muon quality used in object selection + bool m_muonUseMVALowPtLoose; //to turn on MVA for low-pT muons (loose tree) + bool m_muonUse2stationMuonsHighPtLoose; //to allow muon reco with 2-station (loose tree) + std::string m_muonIsolation; + std::string m_muonIsolationLoose; + std::string m_muonIsolationSF; + std::string m_muonIsolationSFLoose; + int m_muon_d0SigCut; + float m_muon_delta_z0; + bool m_muonMuonDoSmearing2stationHighPt; //to turn on/off special correction for the reco with 2-station muons with missing inner MS station allowed for abs(eta)<1.3, only HighPt WP + bool m_muonMuonDoExtraSmearingHighPt; //to turn on/off a special correction for the muon with high momenta. + + //Soft muon configuration + float m_softmuonPtcut; // soft muon object selection pT cut + float m_softmuonEtacut; // soft muon object selection (abs) eta cut + std::string m_softmuonQuality; // soft muon quality used in object selection + bool m_softmuonUseMVALowPt; //to turn on MVA for low-pT muons + float m_softmuonDRJetcut; // soft muon object selection DR wrt jets cut + bool m_softmuonDRJetcutUseRapidity; // true -> use rapidity for DR(jet,mu) matching; false -> use pseudorapidity + bool m_softmuonAdditionalTruthInfo; //additional info on the particle-level origin of the muon, see TopParticleLevel/TruthTools.h + bool m_softmuonAdditionalTruthInfoCheckPartonOrigin; //additional info on the parton-level origin of the muon, see TopParticleLevel/TruthTools.h + bool m_softmuonAdditionalTruthInfoDoVerbose; //to help debugging the above options + + // Jet configuration + float m_jetPtcut; // jet object selection pT cut + float m_jetEtacut; // jet object selection (abs) eta cut + float m_jetPtGhostTracks; // jet pt threshold for ghost track systematic variations calculation + float m_jetEtaGhostTracks; // jet eta threshold for ghost track systematic variations calculation + std::string m_jetUncertainties_NPModel; // AllNuisanceParameters, 19NP or 3NP + std::string m_jetUncertainties_QGFracFile; // to improve Flavour composition and response + std::vector<std::string> m_jetUncertainties_QGHistPatterns; // to improve Flavour composition and response, with + // more flexibility + bool m_doMultipleJES; + std::string m_jetJERSmearingModel; // Full or Simple + std::string m_jetCalibSequence; // GCC or JMS + bool m_jetStoreTruthLabels; // True or False + bool m_doJVTInMETCalculation; + bool m_saveFailJVTJets; + std::string m_JVTWP; + bool m_doForwardJVTInMETCalculation; + bool m_saveFailForwardJVTJets; + std::string m_fJVTWP; + + // MET configuration + std::string m_METUncertaintiesConfigDir; //Path prefix for directory with MET calibration configs + + //Ghost tracks quality + float m_ghostTrackspT; + std::string m_ghostTracksVertexAssociation; + std::string m_ghostTracksQuality; + + // Large R jet configuration + float m_largeRJetPtcut; // large R jet object selection pT cut + float m_largeRJetEtacut; // large R jet object selection (abs) eta cut + std::map<std::string,std::string> m_largeRJetSubstructureVariables; + std::string m_largeRJetUncertainties_NPModel; //large R JES/(plus old JMS, JMR, JER) uncertainties configuration + std::string m_largeRJetUncertaintiesConfigDir; //Relative path to directory with large R JES config + // file + //See https://twiki.cern.ch/twiki/bin/view/AtlasProtected/JetUncertaintiesRel21Summer2019LargeR + std::string m_largeRJESJMSConfig; // large R jet JES/JMS calibration choice - see ANALYSISTO-210 + + // Track jet configuration + float m_trackJetPtcut; // track jet object selection pT cut + float m_trackJetEtacut; // track jet object selection (abs) eta cut + + // Tracks + float m_trackPtcut; // track object selection pT cut + float m_trackEtacut; // track object selection (abs) eta cut + + // Jet configuration for reclustered jets + float m_RCJetPtcut; + float m_RCJetEtacut; + float m_RCInputJetPtMin; + float m_RCInputJetEtaMax; + float m_RCJetTrimcut; + float m_RCJetRadius; + bool m_useRCJetSubstructure; + bool m_useRCJetAdditionalSubstructure; + + // Jet configuration for variable large-R jets + float m_VarRCJetPtcut; + float m_VarRCJetEtacut; + float m_VarRCJetTrimcut; + float m_VarRCJetMaxRadius; + std::string m_VarRCJetRho; + std::string m_VarRCJetMassScale; + bool m_useVarRCJetSubstructure; + bool m_useVarRCJetAdditionalSubstructure; + + std::string m_trackQuality; // track quality to be used in track selection + + // these are needed for the top mass analysis, per default should be 1.0 + float m_JSF; + float m_bJSF; + + // Tau configuration + struct { + // filename to load tau configuration from. + // If this is an empty string then take the 'default' + std::string fileName = "Default"; + // The jetIDWP in CamelCase + // see + // https://svnweb.cern.ch/trac/atlasoff/browser/PhysicsAnalysis/TauID/TauAnalysisTools/trunk/doc/README-TauSelectionTool.rst + // for supported WPs + std::string jetIDWP = "RNNMedium"; + bool doRNNID = true; + bool doBDTID = false; + // the electron BDTWP + std::string eleBDTWP = "Medium"; + bool substructureSF = false; + // Whether to perform electron overlap removal + bool eleOLR = false; + // pT cut on taus + float pt = 20000; + std::string etaRegions="[0., 1.37, 1.52, 2.5]"; + } m_tau_configuration, m_tau_configuration_loose; + + // photon configuration + struct { + // pT cut on photons + float pt = 25000; + float eta = 2.5; + std::string isolation = "None"; + std::string identification = "None"; + } m_photon_configuration, m_photon_configuration_loose; + + // [[[----------------------------------------------- + // Particle Level (truth) configuration + + // electrons + struct { + float PtCut; // [ParticleLevel / Truth] Electron Object + // Selection minimum pT Cut (Standard ATLAS + // units, [MeV]). + float EtaCut; // [ParticleLevel / Truth] Electron Object + // Selection maximum absolute eta Cut. + bool NotFromHadron; // [ParticleLevel / Truth] Whether to apply the + // 'NotFromHadron' requirement onto the objects. + bool TauIsHadron; // [ParticleLevel / Truth] Whether a tauon is a + // hadron during the 'NotFromHadron' check + } m_truth_electron; + + // muons + struct { + float PtCut; // [ParticleLevel / Truth] Muon Object + // Selection minimum pT Cut (Standard ATLAS + // units, [MeV]). + float EtaCut; // [ParticleLevel / Truth] Muon Object + // Selection maximum absolute eta Cut. + bool NotFromHadron; // [ParticleLevel / Truth] Whether to apply the + // 'NotFromHadron' requirement onto the objects. + bool TauIsHadron; // [ParticleLevel / Truth] Whether a tauon is a + // hadron during the 'NotFromHadron' check + } m_truth_muon; + + // soft muons + struct { + float PtCut; // [ParticleLevel / Truth] Muon Object + // Selection minimum pT Cut (Standard ATLAS + // units, [MeV]). + float EtaCut; // [ParticleLevel / Truth] Muon Object + // Selection maximum absolute eta Cut. + } m_truth_softmuon; + + // photons + struct { + float PtCut; // [ParticleLevel / Truth] Photon Object + // Selection minimum pT Cut (Standard ATLAS + // units, [MeV]). + float EtaCut; // [ParticleLevel / Truth] Photon Object + // Selection maximum absolute eta Cut. + std::string Origin; // [ParticleLevel / Truth] Photon Object + // Selection truth origin configuration. + std::string Isolation; // [ParticleLevel / Truth] Photon Object + // Selection truth isolation configuration. + } m_truth_photon; + + // taus + struct { + float PtCut; // [ParticleLevel / Truth] Tau Object + // Selection minimum pT Cut (Standard ATLAS + // units, [MeV]). + float EtaCut; // [ParticleLevel / Truth] Tau Object + // Selection maximum absolute eta Cut. + } m_truth_tau; + + // normal / large R jets + struct { + float PtCut; // [ParticleLevel / Truth] Jet Object + // Selection minimum pT Cut (Standard ATLAS + // units, [MeV]). + float EtaCut; // [ParticleLevel / Truth] Jet Object + // Selection maximum absolute eta Cut. + } m_truth_jet, m_truth_largeRJet; + + + // -----------------------------------------------]]] + + // Options for upgrade studies + bool m_HLLHC; + bool m_HLLHCFakes; + + // Boosted jet taggers requested by user + std::vector<std::pair<std::string, std::string> > m_chosen_boostedJetTaggers; + std::unordered_map<std::string, std::string> m_boostedTaggerSFnames; + + // B-tagging WPs requested by the user (updated to pair of string to hold algorithm and WP) + std::vector<std::pair<std::string, std::string> > m_chosen_btaggingWP; + std::vector<std::pair<std::string, std::string> > m_chosen_btaggingWP_caloJet; + std::vector<std::pair<std::string, std::string> > m_chosen_btaggingWP_trkJet; + // B-tagging systematics requested by user to be excluded from EV treatment, separated by semi-colons + std::string m_bTagSystsExcludedFromEV = ""; + + // list of B-tagging WP actualy available + std::vector<std::string> m_available_btaggingWP; + std::vector<std::string> m_available_btaggingWP_trkJet; + // list of B-tagging WP actualy calibrated + std::vector<std::string> m_calibrated_btaggingWP; + std::vector<std::string> m_calibrated_btaggingWP_trkJet; + // list of B-tagging algorithms requested + std::set<std::string> m_available_btaggingAlgos; + std::set<std::string> m_available_btaggingAlgos_trkJet; + bool m_MV2c10_algo_used = false; + bool m_MV2c10_algo_used_trkJet = false; + + std::unordered_map<std::string, std::string> m_algo_selTools; + std::unordered_map<std::string, std::string> m_algo_selTools_trkJet; + + // B-tagging calibration to be used + bool m_cdi_path_warning = false; + std::string m_btagging_cdi_path = "Default"; + std::string m_btagging_calibration_B = "default"; + std::string m_btagging_calibration_C = "default"; + std::string m_btagging_calibration_Light = "default"; + + // b-tag SF helpers - one of each per WP + // will be set in the BTagScaleFactorCalculator + // These are the base names of the SF systematics (without __up/__down) + std::unordered_map<std::string, std::set<std::string> > bTag_base_names; + std::unordered_map<std::string, std::set<std::string> > bTag_base_names_trkJet; + // and those of them which are not eigenvectors + std::unordered_map<std::string, std::set<std::string> > bTag_named_systs; + std::unordered_map<std::string, std::set<std::string> > bTag_named_systs_trkJet; + // how many B eigen-variations do we have? + std::unordered_map<std::string, unsigned int> bTag_eigen_B; + std::unordered_map<std::string, unsigned int> bTag_eigen_B_trkJet; + // how many C eigen-variations do we have? + std::unordered_map<std::string, unsigned int> bTag_eigen_C; + std::unordered_map<std::string, unsigned int> bTag_eigen_C_trkJet; + // how many Light eigen-variations do we have? + std::unordered_map<std::string, unsigned int> bTag_eigen_light; + std::unordered_map<std::string, unsigned int> bTag_eigen_light_trkJet; + + // LHAPDF options + struct { + std::vector<std::string> pdf_set_names = {}; + std::string baseLHAPDF = ""; // used only if XF1*XF2==0 + + // options + bool doLHAPDF = false; + bool doLHAPDFInNominalTrees = false; + + bool save_per_event = false; + + // we pass the results back to config in PDFScaleFactor::finalize + std::unordered_map< std::string, std::vector<float> > pdf_results; + } m_lhapdf_options; + + // Pile-up reweighting + struct { + std::vector<std::string> lumi_calc_files = {}; + + std::vector<std::string> config_files = {}; + + // R21 - Need to allow configuration for FS and AF2 + std::vector<std::string> config_files_FS = {}; + std::vector<std::string> config_files_AF = {}; + std::vector<std::string> actual_mu_FS = {}; + std::vector<std::string> actual_mu_AF = {}; + float unrepresented_data_tol = 0.05; + + bool apply = false; + + bool use_grl_tool = false; + + // Whether or not to perform mu dependent + // pile-up reweighting. Optional because can + // result in a possible loss of statistics + // that are crucial for things like MVA training. + bool mu_dependent = true; + + std::vector<double> custom_SF = {}; + + std::vector<int> periodAssignments = {}; + } m_pileup_reweighting; + + // Struct for holding TrigGlobalEfficiencyCorrectionTool settings in order to + // manage systematic variations through this tool + + struct { + typedef std::unordered_map<std::string, std::vector<std::string> > triggermap_t; + // -- Set from cutfile --// + // Boolean to be set to true if the user activates a flag + bool isActivated = false; + // Maps of periods -> list of triggers + triggermap_t trigger; + triggermap_t trigger_loose; + + // -- Set from TopCPTools --// + // Boolean to be set to true if we set this information + bool isConfigured = false; + // Names of CP::SystematicSet from electron trigger tools + std::vector<std::string> electron_trigger_systematics; + // Names of CP::SystematicSet from muon trigger tools + std::vector<std::string> muon_trigger_systematics; + // Name of the underlying electron tools, to be accessed and passes CP::SystematicSet + std::vector<std::string> electron_trigger_tool_names; + // Name of the underlying muon tools, to be accessed and passes CP::SystematicSet + std::vector<std::string> muon_trigger_tool_names; + } m_trigGlobalConfiguration; + + // Muon Trigger SF configuration + std::string m_muon_trigger_SF; + + + // Selections + std::shared_ptr<std::vector<std::string> > m_allSelectionNames; + // Trigger configuration + // First string is the selection name, second string is the trigger + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > m_allTriggers_Tight; + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > m_electronTriggers_Tight; + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > m_muonTriggers_Tight; + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > m_tauTriggers_Tight; + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > m_allTriggers_Loose; + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > m_electronTriggers_Loose; + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > m_muonTriggers_Loose; + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > m_tauTriggers_Loose; + std::vector<std::string> m_dummyTrigger; + + // Where the sum of event weights + // before derivation framework is kept + std::string m_sumOfEventWeightsMetaData; + + // Object Selector name + std::string m_objectSelectionName; + // Output Format + std::string m_outputFormat; + // Output Events + std::string m_outputEvents; + bool m_saveOnlySelectedEvents; + // SetAutoFlush(0) on EventSaverFlatNtuple for ANALYSISTO-44 workaround + bool m_outputFileSetAutoFlushZero; + // Better configurable settings for TTree memory optimisation (ANALYSISTO-44, ANALYSISTO-463) + int m_outputFileNEventAutoFlush; + int m_outputFileBasketSizePrimitive; + int m_outputFileBasketSizeVector; + // Number of events to run on (for testing) + unsigned int m_numberOfEventsToRun; + + // Number of events to skip (for testing) + unsigned int m_numberOfEventsToSkip; + + // AOD meta-data access service + AodMetaDataAccess* m_aodMetaData; + + // Systematics + std::size_t m_nominalHashValue; + + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashPhotons; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashElectrons; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashFwdElectrons; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashMuons; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashSoftMuons; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashTaus; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashJets; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashLargeRJets; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashTrackJets; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashTracks; + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashMET; + + std::shared_ptr<std::unordered_set<std::size_t> > m_systHashAll; + std::shared_ptr<std::list<std::size_t> > m_list_systHashAll; + + std::shared_ptr<std::unordered_set<std::size_t> > m_systHash_electronInJetSubtraction; + std::shared_ptr<std::list<std::size_t> > m_list_systHash_electronInJetSubtraction; + + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapPhotons; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapElectrons; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapFwdElectrons; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapMuons; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapSoftMuons; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapTaus; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapJets; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapLargeRJets; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapTrackJets; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapTracks; + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapMET; + + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapPhotons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapElectrons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapFwdElectrons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapMuons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapSoftMuons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapTaus; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapJets; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapJets_electronInJetSubtraction; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapJetsLoose_electronInJetSubtraction; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapLargeRJets; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapTrackJets; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapTracks; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapMET; + + // For TopEvent/SingleSystEvent - will return the nominal key if not under variation + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapPhotons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapElectrons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapFwdElectrons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapMuons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapSoftMuons; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTaus; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJets; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapLargeRJets; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTrackJets; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTracks; + + // The boosted case is a bit more complex, we need additional collections + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapElectrons_electronInJetSubtraction; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJets_electronInJetSubtraction; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJetsLoose_electronInJetSubtraction; + + // For top::TopEventMaker + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapPhotonsTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapPhotonsTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapElectronsTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapElectronsTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapFwdElectronsTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapFwdElectronsTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapMuonsTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapMuonsTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapSoftMuonsTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapSoftMuonsTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTausTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTausTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJetsTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJetsTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapLargeRJetsTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapLargeRJetsTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTrackJetsTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTrackJetsTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTracksTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapTracksTDSAux; + + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapElectrons_electronInJetSubtractionTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapElectrons_electronInJetSubtractionTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJets_electronInJetSubtractionTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJets_electronInJetSubtractionTDSAux; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDS; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllSgKeyMapJetsLoose_electronInJetSubtractionTDSAux; + + // Missing ET + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapMissingET; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapMissingETLoose; + + // KLFitter + std::string m_sgKeyKLFitter; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapKLFitter; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapKLFitterLoose; + + // PseudoTop + std::string m_sgKeyPseudoTop; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapPseudoTop; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systSgKeyMapPseudoTopLoose; + + // Map from systematic hash to CP::SystematicSet + std::shared_ptr<std::unordered_map<std::size_t, CP::SystematicSet> > m_systMapJetGhostTrack; + // Map from systematic hash to decoration key. + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systDecoKeyMapJetGhostTrack; + + // Output TTree names + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systAllTTreeNames; + std::shared_ptr<std::unordered_map<std::size_t, std::string> > m_systPersistantAllTTreeNames; + // Output TTree index + std::shared_ptr<std::unordered_map<std::size_t, unsigned int> > m_systAllTTreeIndex; + std::shared_ptr<std::unordered_map<std::size_t, unsigned int> > m_systAllTTreeLooseIndex; + + // Private function only to simplify the setting of AFII values + void ReadIsAFII(top::ConfigurationSettings* const& settings); + + // Int holding the release series value + int m_release_series; + + // Bool to hold whether we generate and store poisson bootstrap weights + bool m_saveBootstrapWeights; + int m_BootstrapReplicas; + + // Switch to use BadBatmanCleaning + bool m_useBadBatmanCleaning; + unsigned int m_badBatmanCleaningMin; + unsigned int m_badBatmanCleaningMax; + + // Switch to use event-level jet cleaning tool for testing + bool m_useEventLevelJetCleaningTool; + + std::shared_ptr<TreeFilter> m_treeFilter; + + std::unordered_map<std::string, std::string> m_showerMCMCtranslator; + + std::string m_year; + + //ReadFloatOption + float readFloatOption(top::ConfigurationSettings* const& settings, std::string in) const; + }; + + std::ostream& operator << (std::ostream& os, const TopConfig& config); +} // namespace top #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TopPersistentSettings.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TopPersistentSettings.h index 20d1f3d03d5a..ed72fa8a0d4f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TopPersistentSettings.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TopPersistentSettings.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOP_TOPCONFIGURATION_TOPPERSISTENTSETTINGS_H #define ANALYSISTOP_TOPCONFIGURATION_TOPPERSISTENTSETTINGS_H @@ -9,11 +9,11 @@ * @author John Morris <john.morris@cern.ch> * * @brief TopPersistentSettings - * We presist this information into the mini-xAOD + * We presist this information into the mini-xAOD * It allows us to reconstruct the state of the top-xaod code * - * $Revision: 790409 $ - * $Date: 2016-12-19 01:46:29 +0100 (Mon, 19 Dec 2016) $ + * $Revision: 809568 $ + * $Date: 2017-08-18 14:09:22 +0100 (Fri, 18 Aug 2017) $ * * **/ @@ -23,78 +23,99 @@ #include <vector> #include <map> #include <unordered_map> +#include <utility> -namespace top{ - class TopPersistentSettings{ - public: - TopPersistentSettings(); - virtual ~TopPersistentSettings(){} - - bool m_isMC; - bool m_isAFII; - bool m_applyElectronInJetSubtraction; - bool m_doOverlapRemovalOnLooseLeptonDef; - bool m_doKLFitter; - bool m_doPseudoTop; - - std::string m_sgKeyTopSystematicEvents; - std::string m_sgKeyTopSystematicEventsLoose; - - std::string m_sgKeyEventInfo; - std::string m_sgKeyPrimaryVertices; - std::string m_sgKeyPhotons; - std::string m_sgKeyElectrons; - std::string m_sgKeyMuons; - std::string m_sgKeyTaus; - std::string m_sgKeyJets; - std::string m_sgKeyLargeRJets; - std::string m_sgKeyTrackJets; - std::string m_sgKeyMissingEt; - std::string m_sgKeyMissingEtLoose; - - std::string m_electronID; - std::string m_electronIDLoose; - std::string m_electronIsolation; - std::string m_electronIsolationLoose; - - std::string m_muon_trigger_SF; - std::string m_muonQuality; - std::string m_muonQualityLoose; - std::string m_muonIsolation; - std::string m_muonIsolationLoose; - - std::vector<std::string> m_chosen_btaggingWP; - - std::map<std::size_t,std::string> m_systSgKeyMapPhotons; - std::map<std::size_t,std::string> m_systSgKeyMapElectrons; - std::map<std::size_t,std::string> m_systSgKeyMapMuons; - std::map<std::size_t,std::string> m_systSgKeyMapTaus; - std::map<std::size_t,std::string> m_systSgKeyMapJets; - std::map<std::size_t,std::string> m_systSgKeyMapJets_electronInJetSubtraction; - std::map<std::size_t,std::string> m_systSgKeyMapJetsLoose_electronInJetSubtraction; - std::map<std::size_t,std::string> m_systSgKeyMapLargeRJets; - std::map<std::size_t,std::string> m_systSgKeyMapTrackJets; - std::map<std::size_t,std::string> m_systSgKeyMapMissingET; - std::map<std::size_t,std::string> m_systSgKeyMapMissingETLoose; - std::map<std::size_t,std::string> m_systSgKeyMapKLFitter; - std::map<std::size_t,std::string> m_systSgKeyMapKLFitterLoose; - std::map<std::size_t,std::string> m_systSgKeyMapPseudoTop; - std::map<std::size_t,std::string> m_systPersistantAllTTreeNames; - - std::map<std::size_t,std::string> m_systDecoKeyMapJetGhostTrack; - - std::vector<std::size_t> m_list_systHashAll; - std::vector<std::size_t> m_list_systHash_electronInJetSubtraction; - - std::vector<std::string> m_allSelectionNames; - - std::unordered_map<std::string, std::vector<std::string> > m_allTriggers; - std::unordered_map<std::string, std::vector<std::string> > m_electronTriggers; - std::unordered_map<std::string, std::vector<std::string> > m_muonTriggers; - std::unordered_map<std::string, std::vector<std::string> > m_tauTriggers; +namespace top { + class TopPersistentSettings { + public: + TopPersistentSettings(); + virtual ~TopPersistentSettings() {} + + bool m_isMC; + bool m_isAFII; + bool m_applyElectronInJetSubtraction; + bool m_doOverlapRemovalOnLooseLeptonDef; + bool m_doKLFitter; + bool m_doPseudoTop; + + std::string m_sgKeyTopSystematicEvents; + std::string m_sgKeyTopSystematicEventsLoose; + + std::string m_sgKeyEventInfo; + std::string m_sgKeyPrimaryVertices; + std::string m_sgKeyPhotons; + std::string m_sgKeyElectrons; + std::string m_sgKeyFwdElectrons; + std::string m_sgKeyMuons; + std::string m_sgKeySoftMuons; + std::string m_sgKeyTaus; + std::string m_sgKeyJets; + std::string m_sgKeyLargeRJets; + std::string m_sgKeyTrackJets; + std::string m_sgKeyTracks; + std::string m_sgKeyMissingEt; + std::string m_sgKeyMissingEtLoose; + + std::string m_electronID; + std::string m_electronIDLoose; + std::string m_electronIsolation; + std::string m_electronIsolationLoose; + bool m_useElectronChargeIDSelection; + bool m_useEgammaLeakageCorrection; + bool m_enablePromptLeptonImprovedVetoStudies; + + std::string m_fwdElectronID; + + std::string m_muon_trigger_SF; + std::string m_muonQuality; + std::string m_muonQualityLoose; + std::string m_muonIsolation; + std::string m_muonIsolationLoose; + + std::string m_softmuonQuality; + + std::string m_trackQuality; + + std::vector<std::pair<std::string, std::string> > m_chosen_btaggingWP; + + std::map<std::size_t, std::string> m_systSgKeyMapPhotons; + std::map<std::size_t, std::string> m_systSgKeyMapElectrons; + std::map<std::size_t, std::string> m_systSgKeyMapFwdElectrons; + std::map<std::size_t, std::string> m_systSgKeyMapMuons; + std::map<std::size_t, std::string> m_systSgKeyMapSoftMuons; + std::map<std::size_t, std::string> m_systSgKeyMapTaus; + std::map<std::size_t, std::string> m_systSgKeyMapJets; + std::map<std::size_t, std::string> m_systSgKeyMapJets_electronInJetSubtraction; + std::map<std::size_t, std::string> m_systSgKeyMapJetsLoose_electronInJetSubtraction; + std::map<std::size_t, std::string> m_systSgKeyMapLargeRJets; + std::map<std::size_t, std::string> m_systSgKeyMapTrackJets; + std::map<std::size_t, std::string> m_systSgKeyMapMissingET; + std::map<std::size_t, std::string> m_systSgKeyMapMissingETLoose; + std::map<std::size_t, std::string> m_systSgKeyMapKLFitter; + std::map<std::size_t, std::string> m_systSgKeyMapKLFitterLoose; + std::map<std::size_t, std::string> m_systSgKeyMapPseudoTop; + std::map<std::size_t, std::string> m_systSgKeyMapPseudoTopLoose; + std::map<std::size_t, std::string> m_systPersistantAllTTreeNames; + + std::map<std::size_t, std::string> m_systDecoKeyMapJetGhostTrack; + std::map<std::size_t, std::string> m_systSgKeyMapTracks; + + std::vector<std::size_t> m_list_systHashAll; + std::vector<std::size_t> m_list_systHash_electronInJetSubtraction; + + std::vector<std::string> m_allSelectionNames; + + std::unordered_map<std::string, std::vector<std::string> > m_allTriggers_Tight; + std::unordered_map<std::string, std::vector<std::string> > m_electronTriggers_Tight; + std::unordered_map<std::string, std::vector<std::string> > m_muonTriggers_Tight; + std::unordered_map<std::string, std::vector<std::string> > m_tauTriggers_Tight; + + std::unordered_map<std::string, std::vector<std::string> > m_allTriggers_Loose; + std::unordered_map<std::string, std::vector<std::string> > m_electronTriggers_Loose; + std::unordered_map<std::string, std::vector<std::string> > m_muonTriggers_Loose; + std::unordered_map<std::string, std::vector<std::string> > m_tauTriggers_Loose; }; } // Dictonaries -CLASS_DEF( top::TopPersistentSettings , 117063636 , 1 ) +CLASS_DEF(top::TopPersistentSettings, 117063636, 1) #endif - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TreeFilter.h b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TreeFilter.h new file mode 100644 index 000000000000..cfd3e0607ccd --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/TopConfiguration/TreeFilter.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPCONFIGURATION_TREEFILTER_H +#define ANALYSISTOP_TOPCONFIGURATION_TREEFILTER_H + +#include <string> +#include <vector> + +namespace top { + + class TreeFilter { + private: + std::vector<std::string> m_vecFilters; + + public: + TreeFilter(); + TreeFilter(const std::string& longstring); + void init(const std::string& longstring); + bool filterTree(const std::string& treename) const; + + }; + +} + + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/CMakeLists.txt index db669697fa29..84d0e64bfc50 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/CMakeLists.txt @@ -10,12 +10,16 @@ atlas_depends_on_subdirs( PUBLIC TopEvent PileupReweighting ElectronEfficiencyCorrection - MuonEfficiencyCorrections - xAODBTaggingEfficiency TauAnalysisTools JetJvtEfficiency PhotonEfficiencyCorrection - PMGTools ) + PMGTools + PATInterfaces + FTagAnalysisInterfaces + MuonAnalysisInterfaces + TriggerAnalysisInterfaces + PMGAnalysisInterfaces + EgammaAnalysisInterfaces) # This package uses LHAPDF: find_package( Lhapdf ) @@ -25,22 +29,31 @@ find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) # Custom definitions needed for this package: add_definitions( -g -std=c++14 ) +# Add a ROOT dictionary +atlas_add_root_dictionary( TopCorrections _cintDictSource + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) + # Build a library that other components can link against: atlas_add_library( TopCorrections Root/*.cxx Root/*.h Root/*.icc TopCorrections/*.h TopCorrections/*.icc TopCorrections/*/*.h - TopCorrections/*/*.icc + TopCorrections/*/*.icc ${_cintDictSource} PUBLIC_HEADERS TopCorrections LINK_LIBRARIES xAODEgamma xAODMuon TopEvent PileupReweightingLib ElectronEfficiencyCorrectionLib - MuonEfficiencyCorrectionsLib - xAODBTaggingEfficiencyLib TauAnalysisToolsLib JetJvtEfficiencyLib PhotonEfficiencyCorrectionLib PMGToolsLib + PATInterfaces + FTagAnalysisInterfacesLib + MuonAnalysisInterfacesLib + #TriggerAnalysisInterfacesLib + PMGAnalysisInterfacesLib + EgammaAnalysisInterfacesLib ${LHAPDF_LIBRARIES} ${ROOT_LIBRARIES} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/BTagScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/BTagScaleFactorCalculator.cxx index f1ce0e7a7d72..68374fec6a39 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/BTagScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/BTagScaleFactorCalculator.cxx @@ -1,9 +1,10 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -// $Id: BTagScaleFactorCalculator.cxx 802983 2017-04-16 18:31:29Z tpelzer $ +// $Id: BTagScaleFactorCalculator.cxx 809570 2017-08-18 13:15:17Z iconnell $ #include "TopCorrections/BTagScaleFactorCalculator.h" +#include "TopCorrections/TopCorrectionsTools.h" #include "TopConfiguration/TopConfig.h" #include "TopEvent/EventTools.h" @@ -12,86 +13,76 @@ #include <algorithm> #include <functional> -namespace top{ +// For debug function +#include "PATInterfaces/SystematicCode.h" +#include "PATInterfaces/SystematicSet.h" +#include "PATInterfaces/SystematicVariation.h" +#include "CalibrationDataInterface/CalibrationDataInterfaceROOT.h" +#include "PathResolver/PathResolver.h" - BTagScaleFactorCalculator::BTagScaleFactorCalculator( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + BTagScaleFactorCalculator::BTagScaleFactorCalculator(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), - m_nominal( CP::SystematicSet() ) - { - declareProperty( "config" , m_config ); - + m_nominal(CP::SystematicSet()) { + declareProperty("config", m_config); } - StatusCode BTagScaleFactorCalculator::initialize() - { - ATH_MSG_INFO(" top::BTagScaleFactorCalculator initialize" ); - - std::string release_series = ""; - const char* rel_temp = std::getenv("ROOTCORE_RELEASE_SERIES"); - if (rel_temp) { - release_series = std::string(rel_temp); - } else { - ATH_MSG_WARNING("Can not access ROOTCORE_RELEASE_SERIES"); - } + StatusCode BTagScaleFactorCalculator::initialize() { + ATH_MSG_INFO(" top::BTagScaleFactorCalculator initialize"); - if (release_series == "23") { - ATH_MSG_INFO("Setting release series to 2.3"); - m_release_series = 23; - } else if (release_series == "24") { - m_release_series = 24; - ATH_MSG_INFO("Setting release series to 2.4"); - } else { - ATH_MSG_WARNING("Unknown release series, assuming 2.4"); - } - // for calo jets std::vector<std::string> availableWPs = m_config->bTagWP_available(); for (auto& WP : availableWPs) { - m_btagSelTools[WP] = "BTaggingSelectionTool_"+WP+"_"+m_config->sgKeyJets(); - top::check( m_btagSelTools[WP].retrieve(), "Failed to retrieve b-tagging Selection tool" ); + m_btagSelTools[WP] = "BTaggingSelectionTool_" + WP + "_" + m_config->sgKeyJets(); + top::check(m_btagSelTools[WP].retrieve(), "Failed to retrieve b-tagging Selection tool"); if (std::find(m_config->bTagWP_calibrated().begin(), - m_config->bTagWP_calibrated().end(), WP) != m_config->bTagWP_calibrated().end()) {// need scale-factors only for calibrated WPs - m_btagEffTools[WP] = "BTaggingEfficiencyTool_"+WP+"_"+m_config->sgKeyJets(); - top::check( m_btagEffTools[WP].retrieve(), "Failed to retrieve b-tagging Efficiency tool" ); + m_config->bTagWP_calibrated().end(), WP) != m_config->bTagWP_calibrated().end()) {// need + // scale-factors + // only for + // calibrated WPs + m_btagEffTools[WP] = "BTaggingEfficiencyTool_" + WP + "_" + m_config->sgKeyJets(); + top::check(m_btagEffTools[WP].retrieve(), "Failed to retrieve b-tagging Efficiency tool"); m_systs[WP] = m_btagEffTools[WP]->affectingSystematics(); std::set<std::string> base_names = m_systs[WP].getBaseNames(); - m_config->setBTaggingSFSysts( WP, base_names ); + m_config->setBTaggingSFSysts(WP, base_names); } } // for track jets availableWPs = m_config->bTagWP_available_trkJet(); for (auto& WP : availableWPs) { - m_trkjet_btagSelTools[WP] = "BTaggingSelectionTool_"+WP+"_"+m_config->sgKeyTrackJets(); - top::check( m_trkjet_btagSelTools[WP].retrieve(), "Failed to retrieve b-tagging Selection tool" ); + m_trkjet_btagSelTools[WP] = "BTaggingSelectionTool_" + WP + "_" + m_config->sgKeyTrackJets(); + top::check(m_trkjet_btagSelTools[WP].retrieve(), "Failed to retrieve b-tagging Selection tool"); if (std::find(m_config->bTagWP_calibrated_trkJet().begin(), - m_config->bTagWP_calibrated_trkJet().end(), WP) != m_config->bTagWP_calibrated_trkJet().end()) {// need scale-factors only for calibrated WPs - m_trkjet_btagEffTools[WP] = "BTaggingEfficiencyTool_"+WP+"_"+m_config->sgKeyTrackJets(); - top::check( m_trkjet_btagEffTools[WP].retrieve(), "Failed to retrieve b-tagging Efficiency tool" ); + m_config->bTagWP_calibrated_trkJet().end(), WP) != m_config->bTagWP_calibrated_trkJet().end()) {// need + // scale-factors + // only + // for + // calibrated + // WPs + m_trkjet_btagEffTools[WP] = "BTaggingEfficiencyTool_" + WP + "_" + m_config->sgKeyTrackJets(); + top::check(m_trkjet_btagEffTools[WP].retrieve(), "Failed to retrieve b-tagging Efficiency tool"); m_trkjet_systs[WP] = m_trkjet_btagEffTools[WP]->affectingSystematics(); std::set<std::string> base_names = m_trkjet_systs[WP].getBaseNames(); - m_config->setBTaggingSFSysts( WP, base_names, true ); + m_config->setBTaggingSFSysts(WP, base_names, true); } } - + return StatusCode::SUCCESS; } - - StatusCode BTagScaleFactorCalculator::execute() - { - - top::check( apply( m_config->systSgKeyMapJets(false) ), - "Failed to apply btagging SFs" ); - if( m_config->useTrackJets() ) - top::check( apply( m_config->systSgKeyMapTrackJets(), true ), - "Failed to apply track jet btagging SFs" ); + StatusCode BTagScaleFactorCalculator::execute() { + top::check(apply(m_config->systSgKeyMapJets(false)), + "Failed to apply btagging SFs"); + if (m_config->useTrackJets()) top::check(apply(m_config->systSgKeyMapTrackJets(), true), + "Failed to apply track jet btagging SFs"); return StatusCode::SUCCESS; - } - StatusCode BTagScaleFactorCalculator::apply( const std::shared_ptr<std::unordered_map<std::size_t,std::string>>& jet_syst_collections, bool use_trackjets ){ + StatusCode BTagScaleFactorCalculator::apply(const std::shared_ptr<std::unordered_map<std::size_t, + std::string> >& jet_syst_collections, + bool use_trackjets) { ///-- Loop over all jet collections --/// ///-- Lets assume that we're not doing ElectronInJet subtraction --/// for (auto currentSystematic : *jet_syst_collections) { @@ -99,99 +90,101 @@ namespace top{ top::check(evtStore()->retrieve(jets, currentSystematic.second), "failed to retrieve jets"); ///-- Tell the SF tools to use the nominal systematic --/// - /// -- Loop over all jets in each collection --/// for (auto jetPtr : *jets) { - - bool passSelection(false); - if (jetPtr->isAvailable<char>("passPreORSelection")) { - if (jetPtr->auxdataConst<char>("passPreORSelection") == 1) { - passSelection = true; - } - } - if (jetPtr->isAvailable<char>("passPreORSelectionLoose")) { - if (jetPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) { - passSelection = true; - } - } - - if (passSelection) { - - // now loop over all available WPs - - for( auto& tagWP : (use_trackjets ? m_config->bTagWP_available_trkJet() : m_config->bTagWP_available()) ){ + bool passSelection(false); + if (jetPtr->isAvailable<char>("passPreORSelection")) { + if (jetPtr->auxdataConst<char>("passPreORSelection") == 1) { + passSelection = true; + } + } + if (jetPtr->isAvailable<char>("passPreORSelectionLoose")) { + if (jetPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) { + passSelection = true; + } + } + + if (passSelection) { + // now loop over all available WPs + + for (auto& tagWP : (use_trackjets ? m_config->bTagWP_available_trkJet() : m_config->bTagWP_available())) { // skip uncalibrated though available WPs - if (use_trackjets && + if (use_trackjets && std::find(m_config->bTagWP_calibrated_trkJet().begin(), m_config->bTagWP_calibrated_trkJet().end(), tagWP) - == m_config->bTagWP_calibrated_trkJet().end()) continue; - else if (!use_trackjets && - std::find(m_config->bTagWP_calibrated().begin(), - m_config->bTagWP_calibrated().end(), tagWP) - == m_config->bTagWP_calibrated().end()) continue; - ToolHandle<IBTaggingEfficiencyTool>& btageff = use_trackjets ? m_trkjet_btagEffTools[tagWP] : m_btagEffTools[tagWP]; - ToolHandle<IBTaggingSelectionTool>& btagsel = use_trackjets ? m_trkjet_btagSelTools[tagWP] : m_btagSelTools[tagWP]; + == m_config->bTagWP_calibrated_trkJet().end()) continue; + else if (!use_trackjets && + std::find(m_config->bTagWP_calibrated().begin(), + m_config->bTagWP_calibrated().end(), tagWP) + == m_config->bTagWP_calibrated().end()) continue; + ToolHandle<IBTaggingEfficiencyTool>& btageff = + use_trackjets ? m_trkjet_btagEffTools[tagWP] : m_btagEffTools[tagWP]; + ToolHandle<IBTaggingSelectionTool>& btagsel = + use_trackjets ? m_trkjet_btagSelTools[tagWP] : m_btagSelTools[tagWP]; CP::SystematicSet& sysSet = use_trackjets ? m_trkjet_systs[tagWP] : m_systs[tagWP]; // need now the DSID to find out which shower was used in the sample - unsigned int MapIndex = m_config -> getMapIndex(); - - btageff -> setMapIndex("Light", MapIndex); - btageff -> setMapIndex("C", MapIndex); - btageff -> setMapIndex("B", MapIndex); - btageff -> setMapIndex("T", MapIndex); - - top::check( btageff->applySystematicVariation(m_nominal), - "Failed to set new b-tagging SF to nominal" ); - - float btag_SF(1.0); - bool isTagged = false;//unused in case of Continuous - if (std::fabs(jetPtr->eta()) < 2.5 ) { - if (tagWP != "Continuous") { - isTagged = btagsel->accept(*jetPtr); - if(isTagged) - top::check( btageff->getScaleFactor(*jetPtr, btag_SF), - "Failed to get nominal b-tagging SF" ); - else - top::check( btageff->getInefficiencyScaleFactor(*jetPtr, btag_SF), - "Failed to get nominal b-tagging SF" ); - } - else { - top::check( btageff->getScaleFactor(*jetPtr, btag_SF), - "Failed to get nominal Continuous b-tagging SF" ); - } + unsigned int MapIndex = m_config->getMapIndex(); + + btageff->setMapIndex("Light", MapIndex); + btageff->setMapIndex("C", MapIndex); + btageff->setMapIndex("B", MapIndex); + btageff->setMapIndex("T", MapIndex); + + // Check if this jet collection systematic matches with one removed from the EV decomposition + // (TopCorrectionsTools) + std::string bTagSystName = top::bTagNamedSystCheck(m_config, currentSystematic.second, tagWP, use_trackjets, false); + // If this string is not empty, we need to search and find the appropriate systematic set to apply + if (bTagSystName != "") { + CP::SystematicSet bTagSyst; + bTagSyst.insert(sysSet.getSystematicByBaseName(bTagSystName)); + top::check(btageff->applySystematicVariation(bTagSyst), + "Failed to set new b-tagging SF to a shifted systematic set : " + bTagSystName); + } else { + top::check(btageff->applySystematicVariation(m_nominal), + "Failed to set new b-tagging SF to nominal"); } - jetPtr->auxdecor<float>("btag_SF_"+tagWP+"_nom") = btag_SF; - ///-- For nominal calibration, vary the SF systematics --/// - if (currentSystematic.first == m_config->nominalHashValue()) { + float btag_SF(1.0); + bool isTagged = false;//unused in case of Continuous + if (std::fabs(jetPtr->eta()) <= 2.5) { + if (tagWP.find("Continuous") == std::string::npos) { + isTagged = static_cast<bool>(btagsel->accept(*jetPtr)); + if (isTagged) top::check(btageff->getScaleFactor(*jetPtr, btag_SF), + "Failed to get nominal b-tagging SF"); + else top::check(btageff->getInefficiencyScaleFactor(*jetPtr, btag_SF), + "Failed to get nominal b-tagging SF"); + } else { + top::check(btageff->getScaleFactor(*jetPtr, btag_SF), + "Failed to get nominal Continuous b-tagging SF"); + } + } + jetPtr->auxdecor<float>("btag_SF_" + tagWP + "_nom") = btag_SF; - for( const auto& variation : sysSet ) { + ///-- For nominal calibration, vary the SF systematics --/// + if (currentSystematic.first == m_config->nominalHashValue()) { + for (const auto& variation : sysSet) { btag_SF = 1.; CP::SystematicSet syst_set; - syst_set.insert( variation ); - top::check( btageff->applySystematicVariation(syst_set), - "Failed to set new b-tagging systematic variation "+syst_set.name() ); - if (std::fabs(jetPtr->eta()) < 2.5 ) { - if (tagWP != "Continuous") { - if (isTagged) - top::check( btageff->getScaleFactor(*jetPtr, btag_SF), - "Failed to get b-tagging SF for variation "+syst_set.name() ); - else - top::check( btageff->getInefficiencyScaleFactor(*jetPtr, btag_SF), - "Failed to get b-tagging SF for variation "+syst_set.name() ); - } - else { - top::check( btageff->getScaleFactor(*jetPtr, btag_SF), - "Failed to get Continuous b-tagging SF for variation "+syst_set.name() ); + syst_set.insert(variation); + top::check(btageff->applySystematicVariation(syst_set), + "Failed to set new b-tagging systematic variation " + syst_set.name()); + if (std::fabs(jetPtr->eta()) <= 2.5) { + if (tagWP.find("Continuous") == std::string::npos) { + if (isTagged) top::check(btageff->getScaleFactor(*jetPtr, btag_SF), + "Failed to get b-tagging SF for variation " + syst_set.name()); + else top::check(btageff->getInefficiencyScaleFactor(*jetPtr, btag_SF), + "Failed to get b-tagging SF for variation " + syst_set.name()); + } else { + top::check(btageff->getScaleFactor(*jetPtr, btag_SF), + "Failed to get Continuous b-tagging SF for variation " + syst_set.name()); } } - jetPtr->auxdecor<float>( "btag_SF_"+tagWP+"_"+variation.name() ) = btag_SF; + jetPtr->auxdecor<float>("btag_SF_" + tagWP + "_" + variation.name()) = btag_SF; } // loop through b-tagging systematic variations - } // Calibration systematic is nominal, so calculate SF systematics - - } - } + } // Calibration systematic is nominal, so calculate SF systematics + } + } } } @@ -199,4 +192,59 @@ namespace top{ return StatusCode::SUCCESS; } + StatusCode BTagScaleFactorCalculator::debug() { + ATH_MSG_INFO("BTagScaleFactorCalculator::debug function"); + // Use after package is initialised otherwise vectors will be empty + for (auto& tagWP : m_config->bTagWP_available()) { + ATH_MSG_INFO("Tagger working point : " << tagWP); + ToolHandle<IBTaggingEfficiencyTool>& btageff = m_btagEffTools[tagWP]; + // Retrieve tool + top::check(btageff.retrieve(), "Failed to retrieve tool"); + // Retrieve list of systematics included + CP::SystematicSet systs = btageff->affectingSystematics(); + CP::SystematicSet recsysts = btageff->recommendedSystematics(); + + ATH_MSG_INFO("-----------------------------------------------------------------------"); + + const std::map<CP::SystematicVariation, + std::vector<std::string> > allowed_variations = btageff->listSystematics(); + + ATH_MSG_INFO("Allowed systematics variations for tool " << btageff->name()); + for (auto var : allowed_variations) { + std::string flvs = ""; + for (auto flv : var.second) flvs += flv; + ATH_MSG_INFO(" (" << flvs << ") - " << var.first); + } + + // Now use the new functions added into xAODBTaggingEfficiency-00-00-39 + // std::map<std::string, std::vector<std::string> > + ATH_MSG_INFO("-----------------------------------------------------------------------"); + ATH_MSG_INFO("List of b-tagging scale factor systematics"); + std::map<std::string, + std::vector<std::string> > listOfScaleFactorSystematics = btageff->listScaleFactorSystematics(false); + for (auto var : listOfScaleFactorSystematics) { + ATH_MSG_INFO("Jet flavour : " << var.first); + std::vector<std::string> systs = var.second; + std::sort(systs.begin(), systs.end()); + for (auto sys : systs) { + ATH_MSG_INFO(" (" << var.first << ") - " << sys); + } + ATH_MSG_INFO(" "); + } + + ATH_MSG_INFO("List of (named) b-tagging scale factor systematics"); + listOfScaleFactorSystematics = btageff->listScaleFactorSystematics(true); + for (auto var : listOfScaleFactorSystematics) { + ATH_MSG_INFO("Jet flavour : " << var.first); + std::vector<std::string> systs = var.second; + std::sort(systs.begin(), systs.end()); + for (auto sys : systs) { + ATH_MSG_INFO(" (" << var.first << ") - " << sys); + } + ATH_MSG_INFO(" "); + } + ATH_MSG_INFO("-----------------------------------------------------------------------"); + } + return StatusCode::SUCCESS; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ElectronScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ElectronScaleFactorCalculator.cxx index 3ae5e1323d66..cf6ade66fce6 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ElectronScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ElectronScaleFactorCalculator.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // $Id: ElectronScaleFactorCalculator.cxx 799556 2017-03-05 19:46:03Z tpelzer $ #include "TopCorrections/ElectronScaleFactorCalculator.h" @@ -8,40 +8,36 @@ #include "TopEvent/EventTools.h" #include "xAODEgamma/ElectronContainer.h" +#include "TString.h" - -namespace top{ - - ElectronScaleFactorCalculator::ElectronScaleFactorCalculator( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + ElectronScaleFactorCalculator::ElectronScaleFactorCalculator(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), - m_systNominal( CP::SystematicSet() ), - m_systTrigger_UP( CP::SystematicSet() ), - m_systTrigger_DOWN( CP::SystematicSet() ), - m_systReco_UP( CP::SystematicSet() ), - m_systReco_DOWN( CP::SystematicSet() ), - m_systID_UP( CP::SystematicSet() ), - m_systID_DOWN( CP::SystematicSet() ), - m_systIso_UP( CP::SystematicSet() ), - m_systIso_DOWN( CP::SystematicSet() ), - m_systChargeID_UP( CP::SystematicSet() ), - m_systChargeID_DOWN( CP::SystematicSet() ), - m_systChargeMisID_STAT_UP( CP::SystematicSet() ), - m_systChargeMisID_STAT_DOWN( CP::SystematicSet() ), - m_systChargeMisID_SYST_UP( CP::SystematicSet() ), - m_systChargeMisID_SYST_DOWN( CP::SystematicSet() ), + m_systNominal(CP::SystematicSet()), + m_systTrigger_UP(CP::SystematicSet()), + m_systTrigger_DOWN(CP::SystematicSet()), + m_systReco_UP(CP::SystematicSet()), + m_systReco_DOWN(CP::SystematicSet()), + m_systID_UP(CP::SystematicSet()), + m_systID_DOWN(CP::SystematicSet()), + m_systIso_UP(CP::SystematicSet()), + m_systIso_DOWN(CP::SystematicSet()), + m_systChargeID_UP(CP::SystematicSet()), + m_systChargeID_DOWN(CP::SystematicSet()), + m_systChargeMisID_STAT_UP(CP::SystematicSet()), + m_systChargeMisID_STAT_DOWN(CP::SystematicSet()), + m_systChargeMisID_SYST_UP(CP::SystematicSet()), + m_systChargeMisID_SYST_DOWN(CP::SystematicSet()), m_electronEffSFTrigger("AsgElectronEfficiencyCorrectionTool_TriggerSF"), m_electronEffSFTriggerLoose("AsgElectronEfficiencyCorrectionTool_TriggerSFLoose"), m_electronEffTrigger("AsgElectronEfficiencyCorrectionTool_Trigger"), m_electronEffTriggerLoose("AsgElectronEfficiencyCorrectionTool_TriggerLoose"), - m_electronEffSFReco("AsgElectronEfficiencyCorrectionTool_Reco"), - m_electronEffSFID("AsgElectronEfficiencyCorrectionTool_ID"), m_electronEffSFIDLoose("AsgElectronEfficiencyCorrectionTool_IDLoose"), - m_electronEffIso_exists(false), m_electronEffIsoLoose_exists(false), m_electronEffSFIso("AsgElectronEfficiencyCorrectionTool_Iso"), @@ -55,6 +51,16 @@ namespace top{ m_electronEffSFChargeMisID("ElectronChargeEfficiencyCorrection"), m_electronEffSFChargeMisIDLoose("ElectronChargeEfficiencyCorrectionLoose"), + m_electronEffSFTriggerCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_TriggerSF"), + m_electronEffSFTriggerLooseCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_TriggerSFLoose"), + m_electronEffTriggerCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_Trigger"), + m_electronEffTriggerLooseCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_TriggerLoose"), + m_electronEffSFRecoCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_Reco"), + m_electronEffSFIDCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_ID"), + m_electronEffSFIDLooseCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_IDLoose"), + m_electronEffSFIsoCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_Iso"), + m_electronEffSFIsoLooseCorrModel("AsgElectronEfficiencyCorrectionTool_CorrModel_IsoLoose"), + m_decor_triggerEff("SetMe"), m_decor_triggerEff_loose("SetMe"), m_decor_triggerSF("SetMe"), @@ -67,143 +73,230 @@ namespace top{ m_decor_chargeidSF("SetMe"), m_decor_chargeidSF_loose("SetMe"), m_decor_chargemisidSF("SetMe"), - m_decor_chargemisidSF_loose("SetMe") - { - declareProperty( "config" , m_config ); + m_decor_chargemisidSF_loose("SetMe") { + declareProperty("config", m_config); } - StatusCode ElectronScaleFactorCalculator::initialize() - { - ATH_MSG_INFO(" top::ElectronScaleFactorCalculator initialize" ); + StatusCode ElectronScaleFactorCalculator::initialize() { + ATH_MSG_INFO(" top::ElectronScaleFactorCalculator initialize"); - top::check( m_electronEffSFTrigger.retrieve() , "Failed to retrieve electron SF Tool" ); - top::check( m_electronEffSFTriggerLoose.retrieve() , "Failed to retrieve electron SF Tool" ); + top::check(m_electronEffSFTrigger.retrieve(), "Failed to retrieve electron SF Tool"); + top::check(m_electronEffSFTriggerLoose.retrieve(), "Failed to retrieve electron SF Tool"); + + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + top::check(m_electronEffSFTriggerCorrModel.retrieve(), + "Failed to retrieve electron SF Tool for correlation model"); + top::check( + m_electronEffSFTriggerLooseCorrModel.retrieve(), "Failed to retrieve electron SF Tool for correlation model"); + } - top::check( m_electronEffSFReco.retrieve() , "Failed to retrieve electron SF Tool" ); + top::check(m_electronEffSFReco.retrieve(), "Failed to retrieve electron SF Tool"); + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + top::check(m_electronEffSFRecoCorrModel.retrieve(), "Failed to retrieve electron SF Tool for correlation model"); + } - if ( asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool> ("AsgElectronEfficiencyCorrectionTool_Iso") ){ + if (asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool> ("AsgElectronEfficiencyCorrectionTool_Iso")) { m_electronEffIso_exists = true; - top::check( m_electronEffSFIso.retrieve() , "Failed to retrieve electron SF Tool" ); + top::check(m_electronEffSFIso.retrieve(), "Failed to retrieve electron SF Tool"); + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + top::check(m_electronEffSFIsoCorrModel.retrieve(), "Failed to retrieve electron SF Tool for correlation model"); + } } - if ( asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool> ("AsgElectronEfficiencyCorrectionTool_IsoLoose") ){ + if (asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool> ("AsgElectronEfficiencyCorrectionTool_IsoLoose")) + { m_electronEffIsoLoose_exists = true; - top::check( m_electronEffSFIsoLoose.retrieve() , "Failed to retrieve loose electron SF Tool" ); + top::check(m_electronEffSFIsoLoose.retrieve(), "Failed to retrieve loose electron SF Tool"); + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + top::check( + m_electronEffSFIsoLooseCorrModel.retrieve(), + "Failed to retrieve loose electron SF Tool for correlation model"); + } } - // ChargeID efficiency and Charge mis-identification scale factors: to apply when enabling Electron Charge ID Selector - if ( asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool> ("AsgElectronEfficiencyCorrectionTool_ChargeID") ){ + std::ostream& msgInfo = msg(MSG::Level::INFO); + // ChargeID efficiency and Charge mis-identification scale factors: to apply when enabling Electron Charge ID + // Selector + if (asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool> ("AsgElectronEfficiencyCorrectionTool_ChargeID")) + { m_electronEffChargeID_exists = true; // this scale factor currently exists only for MediumLHH electron - top::check( m_electronEffSFChargeID.retrieve() , "Failed to retrieve electron charge flip efficiency SF Tool" ); - std::cout<<"------>Systematics:"<<std::endl; + top::check(m_electronEffSFChargeID.retrieve(), "Failed to retrieve electron charge flip efficiency SF Tool"); + msgInfo << "------>Systematics:\n"; for (auto sys:m_electronEffSFChargeID->recommendedSystematics()) - std::cout<<"---> "<<sys<<std::endl; + msgInfo << "---> " << sys << "\n"; } - if ( asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool> ("AsgElectronEfficiencyCorrectionTool_ChargeIDLoose") ){ + if (asg::ToolStore::contains<IAsgElectronEfficiencyCorrectionTool> ( + "AsgElectronEfficiencyCorrectionTool_ChargeIDLoose")) { m_electronEffChargeIDLoose_exists = true; // this scale factor currently exists only for MediumLHH electron - top::check( m_electronEffSFChargeIDLoose.retrieve() , "Failed to retrieve electron charge flip efficiency SF Tool" ); - std::cout<<"------>Systematics:"<<std::endl; + top::check(m_electronEffSFChargeIDLoose.retrieve(), "Failed to retrieve electron charge flip efficiency SF Tool"); + msgInfo << "------>Systematics:\n"; for (auto sys:m_electronEffSFChargeIDLoose->recommendedSystematics()) - std::cout<<"---> "<<sys<<std::endl; + msgInfo << "---> " << sys << "\n"; } - if ( asg::ToolStore::contains<CP::ElectronChargeEfficiencyCorrectionTool> ("ElectronChargeEfficiencyCorrection") && - m_config->doPileupReweighting() ){ // tool requires RandomRunNumber set from it + if (asg::ToolStore::contains<CP::ElectronChargeEfficiencyCorrectionTool> ("ElectronChargeEfficiencyCorrection") && + m_config->doPileupReweighting()) { // tool requires RandomRunNumber set from it m_electronEffChargeMisID_exists = true; - top::check( m_electronEffSFChargeMisID.retrieve() , "Failed to retrieve electron charge mis-id SF Tool" ); - std::cout<<"------>Systematics:"<<std::endl; + top::check(m_electronEffSFChargeMisID.retrieve(), "Failed to retrieve electron charge mis-id SF Tool"); + msgInfo << "------>Systematics:\n"; for (auto sys:m_electronEffSFChargeMisID->recommendedSystematics()) - std::cout<<"---> "<<sys<<std::endl; + msgInfo << "---> " << sys << "\n"; } - if ( asg::ToolStore::contains<CP::ElectronChargeEfficiencyCorrectionTool> ("ElectronChargeEfficiencyCorrectionLoose") && - m_config->doPileupReweighting() ){ // tool requires RandomRunNumber set from it + if (asg::ToolStore::contains<CP::ElectronChargeEfficiencyCorrectionTool> ("ElectronChargeEfficiencyCorrectionLoose") + && + m_config->doPileupReweighting()) { // tool requires RandomRunNumber set from it m_electronEffChargeMisIDLoose_exists = true; - top::check( m_electronEffSFChargeMisIDLoose.retrieve() , "Failed to retrieve electron charge mis-id SF Tool" ); - std::cout<<"------>Systematics:"<<std::endl; + top::check(m_electronEffSFChargeMisIDLoose.retrieve(), "Failed to retrieve electron charge mis-id SF Tool"); + msgInfo << "------>Systematics:\n"; for (auto sys:m_electronEffSFChargeMisIDLoose->recommendedSystematics()) - std::cout<<"---> "<<sys<<std::endl; + msgInfo << "---> " << sys << "\n"; } // If the isolation tool doesn't exist then check why... // valid reasons include you want no isolation or you know you are using an unsupported WP - if( !m_electronEffIso_exists ) - if( m_config->electronIsolation() != "None" ) - if( m_config->electronIsoSFs() ){ // ... check if we want to continue anyway without SFs anyway - ATH_MSG_WARNING( "No electron isolation SFs available. You can run with ElectronIsolation set to None if you don't want isolation, or add:\tElectronIsoSFs False\tto your config file." ); - return StatusCode::FAILURE; - } - - if( !m_electronEffIsoLoose_exists ) // If the electron isolation SFs don't exist - if( m_config->electronIsolationLoose() != "None" ) // If the isolation is not 'None' then... - if( m_config->electronIsoSFs() ){ // ... check if we want to continue anyway without SFs anyway - ATH_MSG_WARNING( "No (loose) electron isolation SFs available. You can run with ElectronIsolationLoose set to None if you don't want isolation, or add:\tElectronIsoSFs False\tto your config file." ); - return StatusCode::FAILURE; - } - - top::check( m_electronEffSFID.retrieve() , "Failed to retrieve electron SF Tool" ); - top::check( m_electronEffSFIDLoose.retrieve() , "Failed to retrieve electron SF Tool" ); - - m_systTrigger_UP.insert( CP::SystematicVariation("EL_EFF_Trigger_TOTAL_1NPCOR_PLUS_UNCOR" , 1 )); - m_systTrigger_DOWN.insert( CP::SystematicVariation("EL_EFF_Trigger_TOTAL_1NPCOR_PLUS_UNCOR" , -1 )); - m_systReco_UP.insert( CP::SystematicVariation("EL_EFF_Reco_TOTAL_1NPCOR_PLUS_UNCOR" , 1 )); - m_systReco_DOWN.insert( CP::SystematicVariation("EL_EFF_Reco_TOTAL_1NPCOR_PLUS_UNCOR" , -1 )); - m_systID_UP.insert( CP::SystematicVariation("EL_EFF_ID_TOTAL_1NPCOR_PLUS_UNCOR" , 1 )); - m_systID_DOWN.insert( CP::SystematicVariation("EL_EFF_ID_TOTAL_1NPCOR_PLUS_UNCOR" , -1 )); - m_systIso_UP.insert( CP::SystematicVariation("EL_EFF_Iso_TOTAL_1NPCOR_PLUS_UNCOR" , 1 )); - m_systIso_DOWN.insert( CP::SystematicVariation("EL_EFF_Iso_TOTAL_1NPCOR_PLUS_UNCOR" , -1 )); - m_systIso_UP.insert( CP::SystematicVariation("EL_EFF_Iso_TOTAL_1NPCOR_PLUS_UNCOR" , 1 )); - m_systIso_DOWN.insert( CP::SystematicVariation("EL_EFF_Iso_TOTAL_1NPCOR_PLUS_UNCOR" , -1 )); - m_systChargeID_UP.insert( CP::SystematicVariation("EL_EFF_ChargeIDSel_TOTAL_1NPCOR_PLUS_UNCOR" , 1 )); - m_systChargeID_DOWN.insert( CP::SystematicVariation("EL_EFF_ChargeIDSel_TOTAL_1NPCOR_PLUS_UNCOR" , -1 )); - m_systChargeMisID_STAT_UP.insert( CP::SystematicVariation("EL_CHARGEID_STAT" , 1 )); - m_systChargeMisID_STAT_DOWN.insert( CP::SystematicVariation("EL_CHARGEID_STAT" , -1 )); - m_systChargeMisID_SYST_UP.insert( CP::SystematicVariation("EL_CHARGEID_SYStotal" , 1 )); - m_systChargeMisID_SYST_DOWN.insert( CP::SystematicVariation("EL_CHARGEID_SYStotal" , -1 )); - - m_decor_triggerEff = "EL_EFF_Trigger_" + m_config->electronID(); - m_decor_triggerEff_loose = "EL_EFF_Trigger_" + m_config->electronIDLoose(); - m_decor_triggerSF = "EL_SF_Trigger_" + m_config->electronID(); - m_decor_triggerSF_loose = "EL_SF_Trigger_" + m_config->electronIDLoose(); - m_decor_recoSF = "EL_SF_Reco"; - m_decor_idSF = "EL_SF_ID_" + m_config->electronID(); - m_decor_idSF_loose = "EL_SF_ID_" + m_config->electronIDLoose(); - m_decor_isoSF = "EL_SF_Iso_" + m_config->electronIsolation(); - m_decor_isoSF_loose = "EL_SF_Iso_" + m_config->electronIsolationLoose(); - m_decor_chargeidSF = "EL_SF_ChargeID_" + m_config->electronID() + "_" + m_config->electronIsolation(); - m_decor_chargeidSF_loose = "EL_SF_ChargeID_" + m_config->electronIDLoose() + "_" + m_config->electronIsolationLoose(); - m_decor_chargemisidSF = "EL_SF_ChargeMisID_" + m_config->electronID() + "_" + m_config->electronIsolation(); - m_decor_chargemisidSF_loose = "EL_SF_ChargeMisID_" + m_config->electronIDLoose() + "_" + m_config->electronIsolationLoose(); + if (!m_electronEffIso_exists) + if (m_config->electronIsolation() != "None") + if (m_config->electronIsoSFs()) { // ... check if we want to continue anyway without SFs anyway + ATH_MSG_WARNING( + "No electron isolation SFs available. You can run with ElectronIsolation set to None if you don't want isolation, or add:\tElectronIsoSFs False\tto your config file."); + return StatusCode::FAILURE; + } + + if (!m_electronEffIsoLoose_exists) // If the electron isolation SFs don't + // exist + if (m_config->electronIsolationLoose() != "None") // If + // the + // isolation + // is + // not + // 'None' + // then... + if (m_config->electronIsoSFs()) { // ... check if we want to continue anyway without SFs anyway + ATH_MSG_WARNING( + "No (loose) electron isolation SFs available. You can run with ElectronIsolationLoose set to None if you don't want isolation, or add:\tElectronIsoSFs False\tto your config file."); + return StatusCode::FAILURE; + } + + top::check(m_electronEffSFID.retrieve(), "Failed to retrieve electron SF Tool"); + top::check(m_electronEffSFIDLoose.retrieve(), "Failed to retrieve electron SF Tool"); + + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + top::check(m_electronEffSFIDCorrModel.retrieve(), "Failed to retrieve electron SF Tool for correlation model"); + top::check(m_electronEffSFIDLooseCorrModel.retrieve(), + "Failed to retrieve electron SF Tool for correlation model"); + } + + m_systTrigger_UP.insert(CP::SystematicVariation("EL_EFF_Trigger_TOTAL_1NPCOR_PLUS_UNCOR", 1)); + m_systTrigger_DOWN.insert(CP::SystematicVariation("EL_EFF_Trigger_TOTAL_1NPCOR_PLUS_UNCOR", -1)); + m_systReco_UP.insert(CP::SystematicVariation("EL_EFF_Reco_TOTAL_1NPCOR_PLUS_UNCOR", 1)); + m_systReco_DOWN.insert(CP::SystematicVariation("EL_EFF_Reco_TOTAL_1NPCOR_PLUS_UNCOR", -1)); + m_systID_UP.insert(CP::SystematicVariation("EL_EFF_ID_TOTAL_1NPCOR_PLUS_UNCOR", 1)); + m_systID_DOWN.insert(CP::SystematicVariation("EL_EFF_ID_TOTAL_1NPCOR_PLUS_UNCOR", -1)); + m_systIso_UP.insert(CP::SystematicVariation("EL_EFF_Iso_TOTAL_1NPCOR_PLUS_UNCOR", 1)); + m_systIso_DOWN.insert(CP::SystematicVariation("EL_EFF_Iso_TOTAL_1NPCOR_PLUS_UNCOR", -1)); + m_systIso_UP.insert(CP::SystematicVariation("EL_EFF_Iso_TOTAL_1NPCOR_PLUS_UNCOR", 1)); + m_systIso_DOWN.insert(CP::SystematicVariation("EL_EFF_Iso_TOTAL_1NPCOR_PLUS_UNCOR", -1)); + m_systChargeID_UP.insert(CP::SystematicVariation("EL_EFF_ChargeIDSel_TOTAL_1NPCOR_PLUS_UNCOR", 1)); + m_systChargeID_DOWN.insert(CP::SystematicVariation("EL_EFF_ChargeIDSel_TOTAL_1NPCOR_PLUS_UNCOR", -1)); + m_systChargeMisID_STAT_UP.insert(CP::SystematicVariation("EL_CHARGEID_STAT", 1)); + m_systChargeMisID_STAT_DOWN.insert(CP::SystematicVariation("EL_CHARGEID_STAT", -1)); + m_systChargeMisID_SYST_UP.insert(CP::SystematicVariation("EL_CHARGEID_SYStotal", 1)); + m_systChargeMisID_SYST_DOWN.insert(CP::SystematicVariation("EL_CHARGEID_SYStotal", -1)); + + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + CP::SystematicSet triggerSet = m_electronEffSFTrigger->recommendedSystematics(); //currently we have only the + // TOTAL model implemented for + // trigger SF, it's useless to + // use an advanced model here + CP::SystematicSet recoSet = m_electronEffSFRecoCorrModel->recommendedSystematics(); + CP::SystematicSet idSet = m_electronEffSFIDCorrModel->recommendedSystematics(); + CP::SystematicSet isoSet = m_electronEffSFIsoCorrModel->recommendedSystematics(); + + m_systTriggerCorrModel = CP::make_systematics_vector(triggerSet); + m_systRecoCorrModel = CP::make_systematics_vector(recoSet); + m_systIDCorrModel = CP::make_systematics_vector(idSet); + m_systIsoCorrModel = CP::make_systematics_vector(isoSet); + + ATH_MSG_INFO( + "For electron RECO, ID, ISOLATION using the correlation model " << + m_config->electronEfficiencySystematicModel()); + int count = 0, count2 = 0; + for (const CP::SystematicSet& isyst : m_systRecoCorrModel) { + count++; + if (count % 2 == 1) continue; + TString name = isyst.name(); + name.ReplaceAll("__1down", ""); + ATH_MSG_INFO( + "--->electron RECO " << m_config->electronEfficiencySystematicModel() << " component " << (count2++) << " is " << + name); + } + count = 0; + count2 = 0; + for (const CP::SystematicSet& isyst : m_systIDCorrModel) { + count++; + if (count % 2 == 1) continue; + TString name = isyst.name(); + name.ReplaceAll("__1down", ""); + ATH_MSG_INFO( + "--->electron ID " << m_config->electronEfficiencySystematicModel() << " component " << (count2++) << " is " << + name); + } + count = 0; + count2 = 0; + for (const CP::SystematicSet& isyst : m_systIsoCorrModel) { + count++; + if (count % 2 == 1) continue; + TString name = isyst.name(); + name.ReplaceAll("__1down", ""); + ATH_MSG_INFO( + "--->electron ISO " << m_config->electronEfficiencySystematicModel() << " component " << (count2++) << " is " << + name); + } + } + + m_decor_triggerEff = "EL_EFF_Trigger_" + m_config->electronID(); + m_decor_triggerEff_loose = "EL_LOOSE_EFF_Trigger_" + m_config->electronIDLoose(); + m_decor_triggerSF = "EL_SF_Trigger_" + m_config->electronID(); + m_decor_triggerSF_loose = "EL_LOOSE_SF_Trigger_" + m_config->electronIDLoose(); + m_decor_recoSF = "EL_SF_Reco"; + m_decor_idSF = "EL_SF_ID_" + m_config->electronID(); + m_decor_idSF_loose = "EL_LOOSE_SF_ID_" + m_config->electronIDLoose(); + m_decor_isoSF = "EL_SF_Iso_" + m_config->electronIsolation(); + m_decor_isoSF_loose = "EL_LOOSE_SF_Iso_" + m_config->electronIsolationLoose(); + m_decor_chargeidSF = "EL_SF_ChargeID_" + m_config->electronID() + "_" + m_config->electronIsolation(); + m_decor_chargeidSF_loose = "EL_LOOSE_SF_ChargeID_" + m_config->electronIDLoose() + "_" + + m_config->electronIsolationLoose(); + m_decor_chargemisidSF = "EL_SF_ChargeMisID_" + m_config->electronID() + "_" + m_config->electronIsolation(); + m_decor_chargemisidSF_loose = "EL_LOOSE_SF_ChargeMisID_" + m_config->electronIDLoose() + "_" + + m_config->electronIsolationLoose(); return StatusCode::SUCCESS; } - - StatusCode ElectronScaleFactorCalculator::execute() - { + StatusCode ElectronScaleFactorCalculator::execute() { ///-- Loop over all electron collections --/// for (auto currentSystematic : *m_config->systSgKeyMapElectrons()) { const xAOD::ElectronContainer* electrons(nullptr); top::check(evtStore()->retrieve(electrons, currentSystematic.second), "failed to retrieve electrons"); ///-- Tell the SF tools to use the nominal systematic --/// - top::check(m_electronEffSFTrigger->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - top::check(m_electronEffSFTriggerLoose->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - top::check(m_electronEffSFReco->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - top::check(m_electronEffSFID->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - top::check(m_electronEffSFIDLoose->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - if( m_electronEffIso_exists ) - top::check(m_electronEffSFIso->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - if( m_electronEffIsoLoose_exists ) - top::check(m_electronEffSFIsoLoose->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - if( m_electronEffChargeID_exists ) - top::check(m_electronEffSFChargeID->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - if( m_electronEffChargeIDLoose_exists ) - top::check(m_electronEffSFChargeIDLoose->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - if( m_electronEffChargeMisID_exists ) - top::check(m_electronEffSFChargeMisID->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - if( m_electronEffChargeMisIDLoose_exists ) - top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( m_systNominal ),"Failed to set systematic"); + top::check(m_electronEffSFTrigger->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFTriggerLoose->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFReco->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFID->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFIDLoose->applySystematicVariation(m_systNominal), "Failed to set systematic"); + if (m_electronEffIso_exists) top::check(m_electronEffSFIso->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + if (m_electronEffIsoLoose_exists) top::check(m_electronEffSFIsoLoose->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + if (m_electronEffChargeID_exists) top::check(m_electronEffSFChargeID->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + if (m_electronEffChargeIDLoose_exists) top::check(m_electronEffSFChargeIDLoose->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + if (m_electronEffChargeMisID_exists) top::check(m_electronEffSFChargeMisID->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + if (m_electronEffChargeMisIDLoose_exists) top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( + m_systNominal), "Failed to set systematic"); /// -- Loop over all electrons in each collection --/// for (auto electronPtr : *electrons) { - /// -- Does the electron pass object selection? --/// bool passSelection(false); if (electronPtr->isAvailable<char>("passPreORSelection")) { @@ -218,278 +311,599 @@ namespace top{ } if (passSelection) { - - double Eff_Trigger(1.), Eff_TriggerLoose(1.); - double SF_Trigger(1.), SF_TriggerLoose(1.); - double SF_Reco(1.); - double SF_ID(1.),SF_IDLoose(1.); - double SF_Isol(1.),SF_IsolLoose(1.); - double SF_ChargeID(1.), SF_ChargeIDLoose(1.); - double SF_ChargeMisID(1.), SF_ChargeMisIDLoose(1.); - - ///-- Get Efficiencies --/// - top::check(m_electronEffTrigger -> getEfficiencyScaleFactor( *electronPtr , Eff_Trigger ) , "Failed to get SF"); - top::check(m_electronEffTriggerLoose -> getEfficiencyScaleFactor( *electronPtr , Eff_TriggerLoose ) , "Failed to get SF"); - - ///-- Get Scale Factors --/// - top::check(m_electronEffSFTrigger -> getEfficiencyScaleFactor( *electronPtr , SF_Trigger ) , "Failed to get SF"); - top::check(m_electronEffSFTriggerLoose -> getEfficiencyScaleFactor( *electronPtr , SF_TriggerLoose ) , "Failed to get SF"); - top::check(m_electronEffSFReco -> getEfficiencyScaleFactor( *electronPtr , SF_Reco ) , "Failed to get SF"); - top::check(m_electronEffSFID -> getEfficiencyScaleFactor( *electronPtr , SF_ID ) , "Failed to get SF"); - top::check(m_electronEffSFIDLoose -> getEfficiencyScaleFactor( *electronPtr , SF_IDLoose ) , "Failed to get SF"); - if( m_electronEffIso_exists ) - top::check(m_electronEffSFIso -> getEfficiencyScaleFactor( *electronPtr , SF_Isol ) , "Failed to get SF"); - if( m_electronEffIsoLoose_exists ) - top::check(m_electronEffSFIsoLoose -> getEfficiencyScaleFactor( *electronPtr , SF_IsolLoose ) , "Failed to get SF"); - if( m_electronEffChargeID_exists ) - top::check(m_electronEffSFChargeID -> getEfficiencyScaleFactor( *electronPtr , SF_ChargeID ) , "Failed to get SF"); - if( m_electronEffChargeIDLoose_exists ) - top::check(m_electronEffSFChargeIDLoose -> getEfficiencyScaleFactor( *electronPtr , SF_ChargeIDLoose ) , "Failed to get SF"); - if( m_electronEffChargeMisID_exists ) - top::check(m_electronEffSFChargeMisID -> getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisID ) , "Failed to get SF"); - if( m_electronEffChargeMisIDLoose_exists ) - top::check(m_electronEffSFChargeMisIDLoose -> getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisIDLoose ) , "Failed to get SF"); - + double Eff_Trigger(1.), Eff_TriggerLoose(1.); + double SF_Trigger(1.), SF_TriggerLoose(1.); + double SF_Reco(1.); + double SF_ID(1.), SF_IDLoose(1.); + double SF_Isol(1.), SF_IsolLoose(1.); + double SF_ChargeID(1.), SF_ChargeIDLoose(1.); + double SF_ChargeMisID(1.), SF_ChargeMisIDLoose(1.); + + ///-- Get Efficiencies --/// + top::check(m_electronEffTrigger->getEfficiencyScaleFactor(*electronPtr, Eff_Trigger), "Failed to get SF"); + top::check(m_electronEffTriggerLoose->getEfficiencyScaleFactor(*electronPtr, + Eff_TriggerLoose), "Failed to get SF"); + + ///-- Get Scale Factors --/// + top::check(m_electronEffSFTrigger->getEfficiencyScaleFactor(*electronPtr, SF_Trigger), "Failed to get SF"); + top::check(m_electronEffSFTriggerLoose->getEfficiencyScaleFactor(*electronPtr, + SF_TriggerLoose), "Failed to get SF"); + top::check(m_electronEffSFReco->getEfficiencyScaleFactor(*electronPtr, SF_Reco), "Failed to get SF"); + top::check(m_electronEffSFID->getEfficiencyScaleFactor(*electronPtr, SF_ID), "Failed to get SF"); + top::check(m_electronEffSFIDLoose->getEfficiencyScaleFactor(*electronPtr, SF_IDLoose), "Failed to get SF"); + if (m_electronEffIso_exists) top::check(m_electronEffSFIso->getEfficiencyScaleFactor(*electronPtr, + SF_Isol), + "Failed to get SF"); + if (m_electronEffIsoLoose_exists) top::check(m_electronEffSFIsoLoose->getEfficiencyScaleFactor(*electronPtr, + SF_IsolLoose), + "Failed to get SF"); + if (m_electronEffChargeID_exists) top::check(m_electronEffSFChargeID->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeID), + "Failed to get SF"); + if (m_electronEffChargeIDLoose_exists) top::check(m_electronEffSFChargeIDLoose->getEfficiencyScaleFactor(* + electronPtr, + SF_ChargeIDLoose), + "Failed to get SF"); + if (m_electronEffChargeMisID_exists) top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor(* + electronPtr, + SF_ChargeMisID), + "Failed to get SF"); + if (m_electronEffChargeMisIDLoose_exists) top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor( + *electronPtr, + SF_ChargeMisIDLoose), "Failed to get SF"); + + + ///-- Decorate --/// + electronPtr->auxdecor<float>(m_decor_triggerEff) = Eff_Trigger; + electronPtr->auxdecor<float>(m_decor_triggerEff_loose) = Eff_TriggerLoose; + electronPtr->auxdecor<float>(m_decor_triggerSF) = SF_Trigger; + electronPtr->auxdecor<float>(m_decor_triggerSF_loose) = SF_TriggerLoose; + electronPtr->auxdecor<float>(m_decor_recoSF) = SF_Reco; + electronPtr->auxdecor<float>(m_decor_idSF) = SF_ID; + electronPtr->auxdecor<float>(m_decor_idSF_loose) = SF_IDLoose; + electronPtr->auxdecor<float>(m_decor_isoSF) = SF_Isol; + electronPtr->auxdecor<float>(m_decor_isoSF_loose) = SF_IsolLoose; + electronPtr->auxdecor<float>(m_decor_chargeidSF) = SF_ChargeID; + electronPtr->auxdecor<float>(m_decor_chargeidSF_loose) = SF_ChargeIDLoose; + electronPtr->auxdecor<float>(m_decor_chargemisidSF) = SF_ChargeMisID; + electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose) = SF_ChargeMisIDLoose; + + ///-- For nominal calibration, vary the SF systematics --/// + if (currentSystematic.first == m_config->nominalHashValue()) { + double EFF_Trigger_UP(1.), EFF_TriggerLoose_UP(1.); + double SF_Trigger_UP(1.), SF_TriggerLoose_UP(1.); + double SF_Reco_UP(1.); + double SF_ID_UP(1.), SF_IDLoose_UP(1.); + double SF_Isol_UP(1.), SF_IsolLoose_UP(1.); + double SF_ChargeID_UP(1.), SF_ChargeIDLoose_UP(1.); + double SF_ChargeMisID_STAT_UP(1.), SF_ChargeMisIDLoose_STAT_UP(1.); + double SF_ChargeMisID_SYST_UP(1.), SF_ChargeMisIDLoose_SYST_UP(1.); + + double EFF_Trigger_DOWN(1.), EFF_TriggerLoose_DOWN(1.); + double SF_Trigger_DOWN(1.), SF_TriggerLoose_DOWN(1.); + double SF_Reco_DOWN(1.); + double SF_ID_DOWN(1.), SF_IDLoose_DOWN(1.); + double SF_Isol_DOWN(1.), SF_IsolLoose_DOWN(1.); + double SF_ChargeID_DOWN(1.), SF_ChargeIDLoose_DOWN(1.); + double SF_ChargeMisID_STAT_DOWN(1.), SF_ChargeMisIDLoose_STAT_DOWN(1.); + double SF_ChargeMisID_SYST_DOWN(1.), SF_ChargeMisIDLoose_SYST_DOWN(1.); + + ///-- Trigger --/// + ///-- Trigger UP --/// + top::check(m_electronEffSFTrigger->applySystematicVariation(m_systTrigger_UP), "Failed to set systematic"); + top::check(m_electronEffSFTriggerLoose->applySystematicVariation( + m_systTrigger_UP), "Failed to set systematic"); + top::check(m_electronEffSFTrigger->getEfficiencyScaleFactor(*electronPtr, SF_Trigger_UP), + "Failed to get SF"); + top::check(m_electronEffSFTriggerLoose->getEfficiencyScaleFactor(*electronPtr, + SF_TriggerLoose_UP), "Failed to get SF"); + top::check(m_electronEffTrigger->applySystematicVariation(m_systTrigger_UP), "Failed to set systematic"); + top::check(m_electronEffTriggerLoose->applySystematicVariation(m_systTrigger_UP), + "Failed to set systematic"); + top::check(m_electronEffTrigger->getEfficiencyScaleFactor(*electronPtr, EFF_Trigger_UP), + "Failed to get SF"); + top::check(m_electronEffTriggerLoose->getEfficiencyScaleFactor(*electronPtr, + EFF_TriggerLoose_UP), "Failed to get SF"); + + ///-- Trigger DOWN --/// + top::check(m_electronEffSFTrigger->applySystematicVariation(m_systTrigger_DOWN), + "Failed to set systematic"); + top::check(m_electronEffSFTriggerLoose->applySystematicVariation( + m_systTrigger_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFTrigger->getEfficiencyScaleFactor(*electronPtr, + SF_Trigger_DOWN), "Failed to get SF"); + top::check(m_electronEffSFTriggerLoose->getEfficiencyScaleFactor(*electronPtr, + SF_TriggerLoose_DOWN), "Failed to get SF"); + top::check(m_electronEffTrigger->applySystematicVariation(m_systTrigger_DOWN), "Failed to set systematic"); + top::check(m_electronEffTriggerLoose->applySystematicVariation( + m_systTrigger_DOWN), "Failed to set systematic"); + top::check(m_electronEffTrigger->getEfficiencyScaleFactor(*electronPtr, + EFF_Trigger_DOWN), "Failed to get SF"); + top::check(m_electronEffTriggerLoose->getEfficiencyScaleFactor(*electronPtr, + EFF_TriggerLoose_DOWN), "Failed to get SF"); + + + ///-- Trigger reset to nominal --/// + top::check(m_electronEffSFTrigger->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFTriggerLoose->applySystematicVariation(m_systNominal), + "Failed to set systematic"); + top::check(m_electronEffTrigger->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffTriggerLoose->applySystematicVariation(m_systNominal), "Failed to set systematic"); + + + ///-- Reco --/// + ///-- Reco up --/// + top::check(m_electronEffSFReco->applySystematicVariation(m_systReco_UP), "Failed to set systematic"); + top::check(m_electronEffSFReco->getEfficiencyScaleFactor(*electronPtr, SF_Reco_UP), "Failed to get SF"); + + ///-- Reco down --/// + top::check(m_electronEffSFReco->applySystematicVariation(m_systReco_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFReco->getEfficiencyScaleFactor(*electronPtr, SF_Reco_DOWN), "Failed to get SF"); + + ///-- Reco reset to nominal --/// + top::check(m_electronEffSFReco->applySystematicVariation(m_systNominal), "Failed to set systematic"); + + ///-- ID --/// + ///-- ID UP --/// + top::check(m_electronEffSFID->applySystematicVariation(m_systID_UP), "Failed to set systematic"); + top::check(m_electronEffSFIDLoose->applySystematicVariation(m_systID_UP), "Failed to set systematic"); + top::check(m_electronEffSFID->getEfficiencyScaleFactor(*electronPtr, SF_ID_UP), "Failed to get SF"); + top::check(m_electronEffSFIDLoose->getEfficiencyScaleFactor(*electronPtr, SF_IDLoose_UP), + "Failed to get SF"); + ///-- ID DOWN --/// + top::check(m_electronEffSFID->applySystematicVariation(m_systID_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFIDLoose->applySystematicVariation(m_systID_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFID->getEfficiencyScaleFactor(*electronPtr, SF_ID_DOWN), "Failed to get SF"); + top::check(m_electronEffSFIDLoose->getEfficiencyScaleFactor(*electronPtr, + SF_IDLoose_DOWN), "Failed to get SF"); + + ///-- ID reset to nominal --/// + top::check(m_electronEffSFID->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFIDLoose->applySystematicVariation(m_systNominal), "Failed to set systematic"); + + ///-- Iso --/// + ///-- Iso UP --/// + if (m_electronEffIso_exists) { + top::check(m_electronEffSFIso->applySystematicVariation(m_systIso_UP), "Failed to set systematic"); + top::check(m_electronEffSFIso->getEfficiencyScaleFactor(*electronPtr, SF_Isol_UP), "Failed to get SF"); + ///-- Iso DOWN --/// + top::check(m_electronEffSFIso->applySystematicVariation(m_systIso_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFIso->getEfficiencyScaleFactor(*electronPtr, SF_Isol_DOWN), "Failed to get SF"); + ///-- Iso reset to nominal --/// + top::check(m_electronEffSFIso->applySystematicVariation(m_systNominal), "Failed to set systematic"); + } + if (m_electronEffIsoLoose_exists) { + top::check(m_electronEffSFIsoLoose->applySystematicVariation(m_systIso_UP), "Failed to set systematic"); + top::check(m_electronEffSFIsoLoose->getEfficiencyScaleFactor(*electronPtr, + SF_IsolLoose_UP), "Failed to get SF"); + ///-- Iso DOWN --/// + top::check(m_electronEffSFIsoLoose->applySystematicVariation(m_systIso_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFIsoLoose->getEfficiencyScaleFactor(*electronPtr, + SF_IsolLoose_DOWN), "Failed to get SF"); + ///-- Iso reset to nominal --/// + top::check(m_electronEffSFIsoLoose->applySystematicVariation(m_systNominal), "Failed to set systematic"); + } + + ///-- Charge ID --/// + if (m_electronEffChargeID_exists) { + ///-- Charge ID UP --/// + top::check(m_electronEffSFChargeID->applySystematicVariation( + m_systChargeID_UP), "Failed to set systematic"); + top::check(m_electronEffSFChargeID->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeID_UP), "Failed to get SF"); + ///-- Charge ID DOWN --/// + top::check(m_electronEffSFChargeID->applySystematicVariation( + m_systChargeID_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFChargeID->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeID_DOWN), "Failed to get SF"); + ///-- Charge ID reset to nominal --/// + top::check(m_electronEffSFChargeID->applySystematicVariation(m_systNominal), "Failed to set systematic"); + } + if (m_electronEffChargeIDLoose_exists) { + ///-- Charge ID UP --/// + top::check(m_electronEffSFChargeIDLoose->applySystematicVariation( + m_systChargeID_UP), "Failed to set systematic"); + top::check(m_electronEffSFChargeIDLoose->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeIDLoose_UP), + "Failed to get SF"); + ///-- Charge ID DOWN --/// + top::check(m_electronEffSFChargeIDLoose->applySystematicVariation( + m_systChargeID_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFChargeIDLoose->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeIDLoose_DOWN), + "Failed to get SF"); + ///-- Charge ID reset to nominal --/// + top::check(m_electronEffSFChargeIDLoose->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + } + + ///-- Charge Mis ID --/// + if (m_electronEffChargeMisID_exists) { + ///-- Charge Mis ID STAT_UP --/// + top::check(m_electronEffSFChargeMisID->applySystematicVariation( + m_systChargeMisID_STAT_UP), "Failed to set systematic"); + top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeMisID_STAT_UP), + "Failed to get SF"); + ///-- Charge Mis ID STAT_DOWN --/// + top::check(m_electronEffSFChargeMisID->applySystematicVariation( + m_systChargeMisID_STAT_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeMisID_STAT_DOWN), + "Failed to get SF"); + ///-- Charge Mis ID SYS_UP --/// + top::check(m_electronEffSFChargeMisID->applySystematicVariation( + m_systChargeMisID_SYST_UP), "Failed to set systematic"); + top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeMisID_SYST_UP), + "Failed to get SF"); + ///-- Charge Mis ID SYS_DOWN --/// + top::check(m_electronEffSFChargeMisID->applySystematicVariation( + m_systChargeMisID_SYST_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeMisID_SYST_DOWN), + "Failed to get SF"); + ///-- Charge Mis ID reset to nominal --/// + top::check(m_electronEffSFChargeMisID->applySystematicVariation(m_systNominal), + "Failed to set systematic"); + } + if (m_electronEffChargeMisIDLoose_exists) { + ///-- Charge Mis ID STAT_UP --/// + top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( + m_systChargeMisID_STAT_UP), "Failed to set systematic"); + top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeMisIDLoose_STAT_UP), + "Failed to get SF"); + ///-- Charge Mis ID STAT_DOWN --/// + top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( + m_systChargeMisID_STAT_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeMisIDLoose_STAT_DOWN), + "Failed to get SF"); + ///-- Charge Mis ID SYS_UP --/// + top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( + m_systChargeMisID_SYST_UP), "Failed to set systematic"); + top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeMisIDLoose_SYST_UP), + "Failed to get SF"); + ///-- Charge Mis ID SYS_DOWN --/// + top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( + m_systChargeMisID_SYST_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor(*electronPtr, + SF_ChargeMisIDLoose_SYST_DOWN), + "Failed to get SF"); + ///-- Charge Mis ID reset to nominal --/// + top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + } ///-- Decorate --/// - electronPtr->auxdecor<float>(m_decor_triggerEff) = Eff_Trigger; - electronPtr->auxdecor<float>(m_decor_triggerEff_loose) = Eff_TriggerLoose; - electronPtr->auxdecor<float>(m_decor_triggerSF) = SF_Trigger; - electronPtr->auxdecor<float>(m_decor_triggerSF_loose) = SF_TriggerLoose; - electronPtr->auxdecor<float>(m_decor_recoSF) = SF_Reco; - electronPtr->auxdecor<float>(m_decor_idSF) = SF_ID; - electronPtr->auxdecor<float>(m_decor_idSF_loose) = SF_IDLoose; - electronPtr->auxdecor<float>(m_decor_isoSF) = SF_Isol; - electronPtr->auxdecor<float>(m_decor_isoSF_loose) = SF_IsolLoose; - electronPtr->auxdecor<float>(m_decor_chargeidSF) = SF_ChargeID; - electronPtr->auxdecor<float>(m_decor_chargeidSF_loose) = SF_ChargeIDLoose; - electronPtr->auxdecor<float>(m_decor_chargemisidSF) = SF_ChargeMisID; - electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose) = SF_ChargeMisIDLoose; - - ///-- For nominal calibration, vary the SF systematics --/// - if (currentSystematic.first == m_config->nominalHashValue()) { - - double EFF_Trigger_UP(1.),EFF_TriggerLoose_UP(1.); - double SF_Trigger_UP(1.),SF_TriggerLoose_UP(1.); - double SF_Reco_UP(1.); - double SF_ID_UP(1.),SF_IDLoose_UP(1.); - double SF_Isol_UP(1.),SF_IsolLoose_UP(1.); - double SF_ChargeID_UP(1.),SF_ChargeIDLoose_UP(1.); - double SF_ChargeMisID_STAT_UP(1.),SF_ChargeMisIDLoose_STAT_UP(1.); - double SF_ChargeMisID_SYST_UP(1.),SF_ChargeMisIDLoose_SYST_UP(1.); - - double EFF_Trigger_DOWN(1.),EFF_TriggerLoose_DOWN(1.); - double SF_Trigger_DOWN(1.),SF_TriggerLoose_DOWN(1.); - double SF_Reco_DOWN(1.); - double SF_ID_DOWN(1.),SF_IDLoose_DOWN(1.); - double SF_Isol_DOWN(1.),SF_IsolLoose_DOWN(1.); - double SF_ChargeID_DOWN(1.),SF_ChargeIDLoose_DOWN(1.); - double SF_ChargeMisID_STAT_DOWN(1.),SF_ChargeMisIDLoose_STAT_DOWN(1.); - double SF_ChargeMisID_SYST_DOWN(1.),SF_ChargeMisIDLoose_SYST_DOWN(1.); - - ///-- Trigger --/// - ///-- Trigger UP --/// - top::check(m_electronEffSFTrigger -> applySystematicVariation( m_systTrigger_UP ),"Failed to set systematic"); - top::check(m_electronEffSFTriggerLoose -> applySystematicVariation( m_systTrigger_UP ),"Failed to set systematic"); - top::check(m_electronEffSFTrigger -> getEfficiencyScaleFactor( *electronPtr , SF_Trigger_UP ) , "Failed to get SF"); - top::check(m_electronEffSFTriggerLoose -> getEfficiencyScaleFactor( *electronPtr , SF_TriggerLoose_UP ) , "Failed to get SF"); - top::check(m_electronEffTrigger -> applySystematicVariation( m_systTrigger_UP ),"Failed to set systematic"); - top::check(m_electronEffTriggerLoose -> applySystematicVariation( m_systTrigger_UP ),"Failed to set systematic"); - top::check(m_electronEffTrigger -> getEfficiencyScaleFactor( *electronPtr , EFF_Trigger_UP ) , "Failed to get SF"); - top::check(m_electronEffTriggerLoose -> getEfficiencyScaleFactor( *electronPtr , EFF_TriggerLoose_UP ) , "Failed to get SF"); - - ///-- Trigger DOWN --/// - top::check(m_electronEffSFTrigger -> applySystematicVariation( m_systTrigger_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFTriggerLoose -> applySystematicVariation( m_systTrigger_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFTrigger -> getEfficiencyScaleFactor( *electronPtr , SF_Trigger_DOWN ) , "Failed to get SF"); - top::check(m_electronEffSFTriggerLoose -> getEfficiencyScaleFactor( *electronPtr , SF_TriggerLoose_DOWN ) , "Failed to get SF"); - top::check(m_electronEffTrigger -> applySystematicVariation( m_systTrigger_DOWN ),"Failed to set systematic"); - top::check(m_electronEffTriggerLoose -> applySystematicVariation( m_systTrigger_DOWN ),"Failed to set systematic"); - top::check(m_electronEffTrigger -> getEfficiencyScaleFactor( *electronPtr , EFF_Trigger_DOWN ) , "Failed to get SF"); - top::check(m_electronEffTriggerLoose -> getEfficiencyScaleFactor( *electronPtr , EFF_TriggerLoose_DOWN ) , "Failed to get SF"); - + electronPtr->auxdecor<float>(m_decor_triggerEff + "_UP") = EFF_Trigger_UP; + electronPtr->auxdecor<float>(m_decor_triggerEff_loose + "_UP") = EFF_TriggerLoose_UP; + electronPtr->auxdecor<float>(m_decor_triggerSF + "_UP") = SF_Trigger_UP; + electronPtr->auxdecor<float>(m_decor_triggerSF_loose + "_UP") = SF_TriggerLoose_UP; + electronPtr->auxdecor<float>(m_decor_recoSF + "_UP") = SF_Reco_UP; + electronPtr->auxdecor<float>(m_decor_idSF + "_UP") = SF_ID_UP; + electronPtr->auxdecor<float>(m_decor_idSF_loose + "_UP") = SF_IDLoose_UP; + electronPtr->auxdecor<float>(m_decor_isoSF + "_UP") = SF_Isol_UP; + electronPtr->auxdecor<float>(m_decor_isoSF_loose + "_UP") = SF_IsolLoose_UP; + electronPtr->auxdecor<float>(m_decor_chargeidSF + "_UP") = SF_ChargeID_UP; + electronPtr->auxdecor<float>(m_decor_chargeidSF_loose + "_UP") = SF_ChargeIDLoose_UP; + electronPtr->auxdecor<float>(m_decor_chargemisidSF + "_STAT_UP") = SF_ChargeMisID_STAT_UP; + electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose + "_STAT_UP") = SF_ChargeMisIDLoose_STAT_UP; + electronPtr->auxdecor<float>(m_decor_chargemisidSF + "_SYST_UP") = SF_ChargeMisID_SYST_UP; + electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose + "_SYST_UP") = SF_ChargeMisIDLoose_SYST_UP; + + electronPtr->auxdecor<float>(m_decor_triggerEff + "_DOWN") = EFF_Trigger_DOWN; + electronPtr->auxdecor<float>(m_decor_triggerEff_loose + "_DOWN") = EFF_TriggerLoose_DOWN; + electronPtr->auxdecor<float>(m_decor_triggerSF + "_DOWN") = SF_Trigger_DOWN; + electronPtr->auxdecor<float>(m_decor_triggerSF_loose + "_DOWN") = SF_TriggerLoose_DOWN; + electronPtr->auxdecor<float>(m_decor_recoSF + "_DOWN") = SF_Reco_DOWN; + electronPtr->auxdecor<float>(m_decor_idSF + "_DOWN") = SF_ID_DOWN; + electronPtr->auxdecor<float>(m_decor_idSF_loose + "_DOWN") = SF_IDLoose_DOWN; + electronPtr->auxdecor<float>(m_decor_isoSF + "_DOWN") = SF_Isol_DOWN; + electronPtr->auxdecor<float>(m_decor_isoSF_loose + "_DOWN") = SF_IsolLoose_DOWN; + electronPtr->auxdecor<float>(m_decor_chargeidSF + "_DOWN") = SF_ChargeID_DOWN; + electronPtr->auxdecor<float>(m_decor_chargeidSF_loose + "_DOWN") = SF_ChargeIDLoose_DOWN; + electronPtr->auxdecor<float>(m_decor_chargemisidSF + "_STAT_DOWN") = SF_ChargeMisID_STAT_DOWN; + electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose + "_STAT_DOWN") = SF_ChargeMisIDLoose_STAT_DOWN; + electronPtr->auxdecor<float>(m_decor_chargemisidSF + "_SYST_DOWN") = SF_ChargeMisID_SYST_DOWN; + electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose + "_SYST_DOWN") = SF_ChargeMisIDLoose_SYST_DOWN; + + ///-- Debug messages --/// + + ATH_MSG_DEBUG("Electron Trigger Eff = " << electronPtr->auxdataConst<float>(m_decor_triggerEff) << " + " << + electronPtr->auxdataConst<float>(m_decor_triggerEff + "_UP") << " - " << + electronPtr->auxdataConst<float>(m_decor_triggerEff + "_DOWN") + ); + + ATH_MSG_DEBUG("Electron Trigger MediumLH SF = " << electronPtr->auxdataConst<float>( + m_decor_triggerSF) << " + " << + electronPtr->auxdataConst<float>(m_decor_triggerSF + "_UP") << " - " << + electronPtr->auxdataConst<float>(m_decor_triggerSF + "_DOWN") + ); + + ATH_MSG_DEBUG("Electron Reco SF = " << electronPtr->auxdataConst<float>(m_decor_recoSF) << " + " << + electronPtr->auxdataConst<float>(m_decor_recoSF + "_UP") << " - " << + electronPtr->auxdataConst<float>(m_decor_recoSF + "_DOWN") + ); + + ATH_MSG_DEBUG("Electron ID SF = " << electronPtr->auxdataConst<float>(m_decor_idSF) << " + " << + electronPtr->auxdataConst<float>(m_decor_idSF + "_UP") << " - " << + electronPtr->auxdataConst<float>(m_decor_idSF + "_DOWN") + ); + + ATH_MSG_DEBUG("Electron Charge ID SF = " << electronPtr->auxdataConst<float>(m_decor_chargeidSF) << " + " << + electronPtr->auxdataConst<float>(m_decor_chargeidSF + "_UP") << " - " << + electronPtr->auxdataConst<float>(m_decor_chargeidSF + "_DOWN") + ); + + ATH_MSG_DEBUG("Electron Charge Mis-ID SF = " << electronPtr->auxdataConst<float>( + m_decor_chargemisidSF) << " + " << + electronPtr->auxdataConst<float>(m_decor_chargemisidSF + "_STAT_UP") << " - " << + electronPtr->auxdataConst<float>(m_decor_chargemisidSF + "_STAT_DOWN") << " + " << + electronPtr->auxdataConst<float>(m_decor_chargemisidSF + "_SYST_UP") << " - " << + electronPtr->auxdataConst<float>(m_decor_chargemisidSF + "_SYST_DOWN") + ); + + + /////now taking care of additional systematic model if needed + if (m_config->electronEfficiencySystematicModel() != "TOTAL") { + std::vector<float> vec_Eff_Trigger_UP, vec_Eff_Trigger_DOWN, vec_Eff_TriggerLoose_UP, + vec_Eff_TriggerLoose_DOWN; + std::vector<float> vec_SF_Trigger_UP, vec_SF_Trigger_DOWN, vec_SF_TriggerLoose_UP, + vec_SF_TriggerLoose_DOWN; + std::vector<float> vec_SF_Reco_UP, vec_SF_Reco_DOWN; + std::vector<float> vec_SF_ID_UP, vec_SF_ID_DOWN, vec_SF_IDLoose_UP, vec_SF_IDLoose_DOWN; + std::vector<float> vec_SF_Isol_UP, vec_SF_Isol_DOWN, vec_SF_IsolLoose_UP, vec_SF_IsolLoose_DOWN; + std::vector<float> vec_SF_ChargeID_UP, vec_SF_ChargeID_DOWN, vec_SF_ChargeIDLoose_UP, + vec_SF_ChargeIDLoose_DOWN; + std::vector<float> vec_SF_ChargeMisID_UP, vec_SF_ChargeMisID_DOWN, vec_SF_ChargeMisIDLoose_UP, + vec_SF_ChargeMisIDLoose_DOWN; + + double EFF_Trigger(1.), EFF_TriggerLoose(1.); + double SF_Trigger(1.), SF_TriggerLoose(1.); + double SF_Reco(1.); + double SF_ID(1.), SF_IDLoose(1.); + double SF_Isol(1.), SF_IsolLoose(1.); + + /// --Trigger-- /// + int count = 0; + for (const CP::SystematicSet& isyst : m_systTriggerCorrModel) { + if (count == 0) { //0 is nominal + count++; + continue; + } + + top::check(m_electronEffSFTriggerCorrModel->applySystematicVariation(isyst), + "Failed to set systematic"); + top::check(m_electronEffSFTriggerLooseCorrModel->applySystematicVariation( + isyst), "Failed to set systematic"); + top::check(m_electronEffSFTriggerCorrModel->getEfficiencyScaleFactor(*electronPtr, + SF_Trigger), "Failed to get SF"); + top::check(m_electronEffSFTriggerLooseCorrModel->getEfficiencyScaleFactor(*electronPtr, + SF_TriggerLoose), + "Failed to get SF"); + top::check(m_electronEffTriggerCorrModel->applySystematicVariation(isyst), "Failed to set systematic"); + top::check(m_electronEffTriggerLooseCorrModel->applySystematicVariation( + isyst), "Failed to set systematic"); + top::check(m_electronEffTriggerCorrModel->getEfficiencyScaleFactor(*electronPtr, + EFF_Trigger), "Failed to get SF"); + top::check(m_electronEffTriggerLooseCorrModel->getEfficiencyScaleFactor(*electronPtr, + EFF_TriggerLoose), + "Failed to get SF"); + + // split by down and up + if (count % 2 == 1) { + vec_SF_Trigger_DOWN.emplace_back(SF_Trigger); + vec_SF_TriggerLoose_DOWN.emplace_back(SF_TriggerLoose); + vec_Eff_Trigger_DOWN.emplace_back(EFF_Trigger); + vec_Eff_TriggerLoose_DOWN.emplace_back(EFF_TriggerLoose); + } else { + vec_SF_Trigger_UP.emplace_back(SF_Trigger); + vec_SF_TriggerLoose_UP.emplace_back(SF_TriggerLoose); + vec_Eff_Trigger_UP.emplace_back(EFF_Trigger); + vec_Eff_TriggerLoose_UP.emplace_back(EFF_TriggerLoose); + } + + count++; + } + + // Do some sanity check + if (vec_SF_Trigger_DOWN.size() != vec_SF_Trigger_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of trigger SF for up and down are different" + }; + } + if (vec_SF_TriggerLoose_DOWN.size() != vec_SF_TriggerLoose_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of triggerLoose SF for up and down are different" + }; + } + if (vec_Eff_Trigger_DOWN.size() != vec_Eff_Trigger_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of trigger Eff for up and down are different" + }; + } + if (vec_Eff_TriggerLoose_DOWN.size() != vec_Eff_TriggerLoose_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of triggerLoose Eff for up and down are different" + }; + } ///-- Trigger reset to nominal --/// - top::check(m_electronEffSFTrigger -> applySystematicVariation( m_systNominal ),"Failed to set systematic"); - top::check(m_electronEffSFTriggerLoose -> applySystematicVariation( m_systNominal ),"Failed to set systematic"); - top::check(m_electronEffTrigger -> applySystematicVariation( m_systNominal ),"Failed to set systematic"); - top::check(m_electronEffTriggerLoose -> applySystematicVariation( m_systNominal ),"Failed to set systematic"); - - - ///-- Reco --/// - ///-- Reco up --/// - top::check( m_electronEffSFReco->applySystematicVariation( m_systReco_UP ) , "Failed to set systematic" ); - top::check( m_electronEffSFReco->getEfficiencyScaleFactor( *electronPtr , SF_Reco_UP ) , "Failed to get SF"); - - ///-- Reco down --/// - top::check( m_electronEffSFReco->applySystematicVariation( m_systReco_DOWN ) , "Failed to set systematic" ); - top::check( m_electronEffSFReco->getEfficiencyScaleFactor( *electronPtr , SF_Reco_DOWN ) , "Failed to get SF"); + top::check(m_electronEffSFTriggerCorrModel->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFTriggerLooseCorrModel->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + top::check(m_electronEffTriggerCorrModel->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + top::check(m_electronEffTriggerLooseCorrModel->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + + /// --Reco-- /// + count = 0; + for (const CP::SystematicSet& isyst : m_systRecoCorrModel) { + if (count == 0) { //0 is nominal + count++; + continue; + } + + top::check(m_electronEffSFRecoCorrModel->applySystematicVariation(isyst), "Failed to set systematic"); + top::check(m_electronEffSFRecoCorrModel->getEfficiencyScaleFactor(*electronPtr, + SF_Reco), "Failed to get SF"); + + if (count % 2 == 1) { + vec_SF_Reco_DOWN.emplace_back(SF_Reco); + } else { + vec_SF_Reco_UP.emplace_back(SF_Reco); + } + ++count; + } + if (vec_SF_Reco_DOWN.size() != vec_SF_Reco_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of Reco SF for up and down are different" + }; + } ///-- Reco reset to nominal --/// - top::check( m_electronEffSFReco->applySystematicVariation( m_systNominal ) , "Failed to set systematic" ); - - ///-- ID --/// - ///-- ID UP --/// - top::check(m_electronEffSFID->applySystematicVariation( m_systID_UP ),"Failed to set systematic"); - top::check(m_electronEffSFIDLoose->applySystematicVariation( m_systID_UP ),"Failed to set systematic"); - top::check(m_electronEffSFID->getEfficiencyScaleFactor( *electronPtr , SF_ID_UP ) , "Failed to get SF"); - top::check(m_electronEffSFIDLoose->getEfficiencyScaleFactor( *electronPtr , SF_IDLoose_UP ) , "Failed to get SF"); - ///-- ID DOWN --/// - top::check(m_electronEffSFID->applySystematicVariation( m_systID_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFIDLoose->applySystematicVariation( m_systID_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFID->getEfficiencyScaleFactor( *electronPtr , SF_ID_DOWN ) , "Failed to get SF"); - top::check(m_electronEffSFIDLoose->getEfficiencyScaleFactor( *electronPtr , SF_IDLoose_DOWN ) , "Failed to get SF"); + top::check(m_electronEffSFRecoCorrModel->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + + /// --ID-- /// + count = 0; + for (const CP::SystematicSet& isyst : m_systIDCorrModel) { + if (count == 0) { //0 is nominal + count++; + continue; + } + + top::check(m_electronEffSFIDCorrModel->applySystematicVariation(isyst), "Failed to set systematic"); + top::check(m_electronEffSFIDLooseCorrModel->applySystematicVariation(isyst), + "Failed to set systematic"); + top::check(m_electronEffSFIDCorrModel->getEfficiencyScaleFactor(*electronPtr, SF_ID), + "Failed to get SF"); + top::check(m_electronEffSFIDLooseCorrModel->getEfficiencyScaleFactor(*electronPtr, + SF_IDLoose), "Failed to get SF"); + + if (count % 2 == 1) { + vec_SF_ID_DOWN.emplace_back(SF_ID); + vec_SF_IDLoose_DOWN.emplace_back(SF_IDLoose); + } else { + vec_SF_ID_UP.emplace_back(SF_ID); + vec_SF_IDLoose_UP.emplace_back(SF_IDLoose); + } + ++count; + } + if (vec_SF_ID_DOWN.size() != vec_SF_ID_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of ID SF for up and down are different" + }; + } + if (vec_SF_IDLoose_DOWN.size() != vec_SF_IDLoose_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of IDLoose SF for up and down are different" + }; + } ///-- ID reset to nominal --/// - top::check(m_electronEffSFID->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - top::check(m_electronEffSFIDLoose->applySystematicVariation( m_systNominal ),"Failed to set systematic"); + top::check(m_electronEffSFIDCorrModel->applySystematicVariation(m_systNominal), + "Failed to set systematic"); + top::check(m_electronEffSFIDLooseCorrModel->applySystematicVariation( + m_systNominal), "Failed to set systematic"); ///-- Iso --/// - ///-- Iso UP --/// - if( m_electronEffIso_exists ) { - top::check(m_electronEffSFIso -> applySystematicVariation( m_systIso_UP ),"Failed to set systematic"); - top::check(m_electronEffSFIso -> getEfficiencyScaleFactor( *electronPtr , SF_Isol_UP ) , "Failed to get SF"); - ///-- Iso DOWN --/// - top::check(m_electronEffSFIso -> applySystematicVariation( m_systIso_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFIso -> getEfficiencyScaleFactor( *electronPtr , SF_Isol_DOWN ) , "Failed to get SF"); - ///-- Iso reset to nominal --/// - top::check(m_electronEffSFIso -> applySystematicVariation( m_systNominal ),"Failed to set systematic"); - } - if( m_electronEffIsoLoose_exists ) { - top::check(m_electronEffSFIsoLoose -> applySystematicVariation( m_systIso_UP ),"Failed to set systematic"); - top::check(m_electronEffSFIsoLoose -> getEfficiencyScaleFactor( *electronPtr , SF_IsolLoose_UP ) , "Failed to get SF"); - ///-- Iso DOWN --/// - top::check(m_electronEffSFIsoLoose -> applySystematicVariation( m_systIso_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFIsoLoose -> getEfficiencyScaleFactor( *electronPtr , SF_IsolLoose_DOWN ) , "Failed to get SF"); - ///-- Iso reset to nominal --/// - top::check(m_electronEffSFIsoLoose -> applySystematicVariation( m_systNominal ),"Failed to set systematic"); - } - - ///-- Charge ID --/// - if( m_electronEffChargeID_exists ) { - ///-- Charge ID UP --/// - top::check(m_electronEffSFChargeID->applySystematicVariation( m_systChargeID_UP ),"Failed to set systematic"); - top::check(m_electronEffSFChargeID->getEfficiencyScaleFactor( *electronPtr , SF_ChargeID_UP ) , "Failed to get SF"); - ///-- Charge ID DOWN --/// - top::check(m_electronEffSFChargeID->applySystematicVariation( m_systChargeID_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFChargeID->getEfficiencyScaleFactor( *electronPtr , SF_ChargeID_DOWN ) , "Failed to get SF"); - ///-- Charge ID reset to nominal --/// - top::check(m_electronEffSFChargeID->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - } - if( m_electronEffChargeIDLoose_exists ) { - ///-- Charge ID UP --/// - top::check(m_electronEffSFChargeIDLoose->applySystematicVariation( m_systChargeID_UP ),"Failed to set systematic"); - top::check(m_electronEffSFChargeIDLoose->getEfficiencyScaleFactor( *electronPtr , SF_ChargeIDLoose_UP ) , "Failed to get SF"); - ///-- Charge ID DOWN --/// - top::check(m_electronEffSFChargeIDLoose->applySystematicVariation( m_systChargeID_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFChargeIDLoose->getEfficiencyScaleFactor( *electronPtr , SF_ChargeIDLoose_DOWN ) , "Failed to get SF"); - ///-- Charge ID reset to nominal --/// - top::check(m_electronEffSFChargeIDLoose->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - } - - ///-- Charge Mis ID --/// - if( m_electronEffChargeID_exists ) { - ///-- Charge Mis ID STAT_UP --/// - top::check(m_electronEffSFChargeMisID->applySystematicVariation( m_systChargeMisID_STAT_UP ),"Failed to set systematic"); - top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisID_STAT_UP ) , "Failed to get SF"); - ///-- Charge Mis ID STAT_DOWN --/// - top::check(m_electronEffSFChargeMisID->applySystematicVariation( m_systChargeMisID_STAT_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisID_STAT_DOWN ) , "Failed to get SF"); - ///-- Charge Mis ID SYS_UP --/// - top::check(m_electronEffSFChargeMisID->applySystematicVariation( m_systChargeMisID_SYST_UP ),"Failed to set systematic"); - top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisID_SYST_UP ) , "Failed to get SF"); - ///-- Charge Mis ID SYS_DOWN --/// - top::check(m_electronEffSFChargeMisID->applySystematicVariation( m_systChargeMisID_SYST_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFChargeMisID->getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisID_SYST_DOWN ) , "Failed to get SF"); - ///-- Charge Mis ID reset to nominal --/// - top::check(m_electronEffSFChargeMisID->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - } - if( m_electronEffChargeIDLoose_exists ) { - ///-- Charge Mis ID STAT_UP --/// - top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( m_systChargeMisID_STAT_UP ),"Failed to set systematic"); - top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisIDLoose_STAT_UP ) , "Failed to get SF"); - ///-- Charge Mis ID STAT_DOWN --/// - top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( m_systChargeMisID_STAT_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisIDLoose_STAT_DOWN ) , "Failed to get SF"); - ///-- Charge Mis ID SYS_UP --/// - top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( m_systChargeMisID_SYST_UP ),"Failed to set systematic"); - top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisIDLoose_SYST_UP ) , "Failed to get SF"); - ///-- Charge Mis ID SYS_DOWN --/// - top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( m_systChargeMisID_SYST_DOWN ),"Failed to set systematic"); - top::check(m_electronEffSFChargeMisIDLoose->getEfficiencyScaleFactor( *electronPtr , SF_ChargeMisIDLoose_SYST_DOWN ) , "Failed to get SF"); - ///-- Charge Mis ID reset to nominal --/// - top::check(m_electronEffSFChargeMisIDLoose->applySystematicVariation( m_systNominal ),"Failed to set systematic"); - } + count = 0; + for (const CP::SystematicSet& isyst : m_systIsoCorrModel) { + if (count == 0) { //0 is nominal + count++; + continue; + } + + if (m_electronEffIso_exists) { + top::check(m_electronEffSFIsoCorrModel->applySystematicVariation(isyst), "Failed to set systematic"); + top::check(m_electronEffSFIsoCorrModel->getEfficiencyScaleFactor(*electronPtr, + SF_Isol), "Failed to get SF"); + ///-- Iso reset to nominal --/// + top::check(m_electronEffSFIsoCorrModel->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + } + if (m_electronEffIsoLoose_exists) { + top::check(m_electronEffSFIsoLooseCorrModel->applySystematicVariation( + isyst), "Failed to set systematic"); + top::check(m_electronEffSFIsoLooseCorrModel->getEfficiencyScaleFactor(*electronPtr, + SF_IsolLoose), + "Failed to get SF"); + ///-- Iso reset to nominal --/// + top::check(m_electronEffSFIsoLooseCorrModel->applySystematicVariation( + m_systNominal), "Failed to set systematic"); + } + if (count % 2 == 1) { + vec_SF_Isol_DOWN.emplace_back(SF_Isol); + vec_SF_IsolLoose_DOWN.emplace_back(SF_IsolLoose); + } else { + vec_SF_Isol_UP.emplace_back(SF_Isol); + vec_SF_IsolLoose_UP.emplace_back(SF_IsolLoose); + } + ++count; + } + if (vec_SF_Isol_DOWN.size() != vec_SF_Isol_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of Isol SF for up and down are different" + }; + } + if (vec_SF_IsolLoose_DOWN.size() != vec_SF_IsolLoose_UP.size()) { + throw std::runtime_error { + "ElectronScaleFactorCalculator::execute: Sizes of IsolLoose SF for up and down are different" + }; + } + ///-- Decorate --/// - electronPtr->auxdecor<float>(m_decor_triggerEff+"_UP") = EFF_Trigger_UP; - electronPtr->auxdecor<float>(m_decor_triggerEff_loose+"_UP") = EFF_TriggerLoose_UP; - electronPtr->auxdecor<float>(m_decor_triggerSF+"_UP") = SF_Trigger_UP; - electronPtr->auxdecor<float>(m_decor_triggerSF_loose+"_UP") = SF_TriggerLoose_UP; - electronPtr->auxdecor<float>(m_decor_recoSF+"_UP") = SF_Reco_UP; - electronPtr->auxdecor<float>(m_decor_idSF+"_UP") = SF_ID_UP; - electronPtr->auxdecor<float>(m_decor_idSF_loose+"_UP") = SF_IDLoose_UP; - electronPtr->auxdecor<float>(m_decor_isoSF+"_UP") = SF_Isol_UP; - electronPtr->auxdecor<float>(m_decor_isoSF_loose+"_UP") = SF_IsolLoose_UP; - electronPtr->auxdecor<float>(m_decor_chargeidSF+"_UP") = SF_ChargeID_UP; - electronPtr->auxdecor<float>(m_decor_chargeidSF_loose+"_UP") = SF_ChargeIDLoose_UP; - electronPtr->auxdecor<float>(m_decor_chargemisidSF+"_STAT_UP") = SF_ChargeMisID_STAT_UP; - electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose+"_STAT_UP") = SF_ChargeMisIDLoose_STAT_UP; - electronPtr->auxdecor<float>(m_decor_chargemisidSF+"_SYST_UP") = SF_ChargeMisID_SYST_UP; - electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose+"_SYST_UP") = SF_ChargeMisIDLoose_SYST_UP; - - electronPtr->auxdecor<float>(m_decor_triggerEff+"_DOWN") = EFF_Trigger_DOWN; - electronPtr->auxdecor<float>(m_decor_triggerEff_loose+"_DOWN") = EFF_TriggerLoose_DOWN; - electronPtr->auxdecor<float>(m_decor_triggerSF+"_DOWN") = SF_Trigger_DOWN; - electronPtr->auxdecor<float>(m_decor_triggerSF_loose+"_DOWN") = SF_TriggerLoose_DOWN; - electronPtr->auxdecor<float>(m_decor_recoSF+"_DOWN") = SF_Reco_DOWN; - electronPtr->auxdecor<float>(m_decor_idSF+"_DOWN") = SF_ID_DOWN; - electronPtr->auxdecor<float>(m_decor_idSF_loose+"_DOWN") = SF_IDLoose_DOWN; - electronPtr->auxdecor<float>(m_decor_isoSF+"_DOWN") = SF_Isol_DOWN; - electronPtr->auxdecor<float>(m_decor_isoSF_loose+"_DOWN") = SF_IsolLoose_DOWN; - electronPtr->auxdecor<float>(m_decor_chargeidSF+"_DOWN") = SF_ChargeID_DOWN; - electronPtr->auxdecor<float>(m_decor_chargeidSF_loose+"_DOWN") = SF_ChargeIDLoose_DOWN; - electronPtr->auxdecor<float>(m_decor_chargemisidSF+"_STAT_DOWN") = SF_ChargeMisID_STAT_DOWN; - electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose+"_STAT_DOWN") = SF_ChargeMisIDLoose_STAT_DOWN; - electronPtr->auxdecor<float>(m_decor_chargemisidSF+"_SYST_DOWN") = SF_ChargeMisID_SYST_DOWN; - electronPtr->auxdecor<float>(m_decor_chargemisidSF_loose+"_SYST_DOWN") = SF_ChargeMisIDLoose_SYST_DOWN; - - ///-- Debug messages --/// - - ATH_MSG_DEBUG("Electron Trigger Eff = "<<electronPtr->auxdataConst<float>(m_decor_triggerEff) << " + "<< - electronPtr->auxdataConst<float>(m_decor_triggerEff+"_UP") << " - "<< - electronPtr->auxdataConst<float>(m_decor_triggerEff+"_DOWN") - ); - - ATH_MSG_DEBUG("Electron Trigger MediumLH SF = "<<electronPtr->auxdataConst<float>(m_decor_triggerSF) << " + "<< - electronPtr->auxdataConst<float>(m_decor_triggerSF+"_UP") << " - "<< - electronPtr->auxdataConst<float>(m_decor_triggerSF+"_DOWN") - ); - - ATH_MSG_DEBUG("Electron Reco SF = "<<electronPtr->auxdataConst<float>(m_decor_recoSF) << " + "<< - electronPtr->auxdataConst<float>(m_decor_recoSF+"_UP") << " - "<< - electronPtr->auxdataConst<float>(m_decor_recoSF+"_DOWN") - ); - - ATH_MSG_DEBUG("Electron ID SF = "<<electronPtr->auxdataConst<float>(m_decor_idSF) << " + "<< - electronPtr->auxdataConst<float>(m_decor_idSF+"_UP") << " - "<< - electronPtr->auxdataConst<float>(m_decor_idSF+"_DOWN") - ); - - ATH_MSG_DEBUG("Electron Charge ID SF = "<<electronPtr->auxdataConst<float>(m_decor_chargeidSF) << " + "<< - electronPtr->auxdataConst<float>(m_decor_chargeidSF+"_UP") << " - "<< - electronPtr->auxdataConst<float>(m_decor_chargeidSF+"_DOWN") - ); - - ATH_MSG_DEBUG("Electron Charge Mis-ID SF = "<<electronPtr->auxdataConst<float>(m_decor_chargemisidSF) << " + "<< - electronPtr->auxdataConst<float>(m_decor_chargemisidSF+"_STAT_UP") << " - "<< - electronPtr->auxdataConst<float>(m_decor_chargemisidSF+"_STAT_DOWN") << " + "<< - electronPtr->auxdataConst<float>(m_decor_chargemisidSF+"_SYST_UP") << " - "<< - electronPtr->auxdataConst<float>(m_decor_chargemisidSF+"_SYST_DOWN") - ); - - } // Calibration systematic is nominal, so calculate SF systematics + electronPtr->auxdecor<std::vector<float> >(m_decor_triggerEff + "_CorrModel_UP") = vec_Eff_Trigger_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_triggerEff_loose + + "_CorrModel_UP") = vec_Eff_TriggerLoose_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_triggerSF + "_CorrModel_UP") = vec_SF_Trigger_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_triggerSF_loose + + "_CorrModel_UP") = vec_SF_TriggerLoose_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_recoSF + "_CorrModel_UP") = vec_SF_Reco_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_idSF + "_CorrModel_UP") = vec_SF_ID_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_idSF_loose + "_CorrModel_UP") = vec_SF_IDLoose_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_isoSF + "_CorrModel_UP") = vec_SF_Isol_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_isoSF_loose + "_CorrModel_UP") = vec_SF_IsolLoose_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_chargeidSF + "_CorrModel_UP") = vec_SF_ChargeID_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_chargeidSF_loose + + "_CorrModel_UP") = vec_SF_ChargeIDLoose_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_chargemisidSF + + "_CorrModel_UP") = vec_SF_ChargeMisID_UP; + electronPtr->auxdecor<std::vector<float> >(m_decor_chargemisidSF_loose + + "_CorrModel_UP") = vec_SF_ChargeMisIDLoose_UP; + + electronPtr->auxdecor<std::vector<float> >(m_decor_triggerEff + "_CorrModel_DOWN") = vec_Eff_Trigger_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_triggerEff_loose + + "_CorrModel_DOWN") = vec_Eff_TriggerLoose_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_triggerSF + "_CorrModel_DOWN") = vec_SF_Trigger_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_triggerSF_loose + + "_CorrModel_DOWN") = vec_SF_TriggerLoose_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_recoSF + "_CorrModel_DOWN") = vec_SF_Reco_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_idSF + "_CorrModel_DOWN") = vec_SF_ID_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_idSF_loose + "_CorrModel_DOWN") = vec_SF_IDLoose_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_isoSF + "_CorrModel_DOWN") = vec_SF_Isol_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_isoSF_loose + + "_CorrModel_DOWN") = vec_SF_IsolLoose_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_chargeidSF + "_CorrModel_DOWN") = vec_SF_ChargeID_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_chargeidSF_loose + + "_CorrModel_DOWN") = vec_SF_ChargeIDLoose_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_chargemisidSF + + "_CorrModel_DOWN") = vec_SF_ChargeMisID_DOWN; + electronPtr->auxdecor<std::vector<float> >(m_decor_chargemisidSF_loose + + "_CorrModel_DOWN") = vec_SF_ChargeMisIDLoose_DOWN; + }//end of saving additional systematic model + + + ///////////////////////////////////////// + } // Calibration systematic is nominal, so calculate SF systematics } } } @@ -497,5 +911,4 @@ namespace top{ return StatusCode::SUCCESS; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/FwdElectronScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/FwdElectronScaleFactorCalculator.cxx new file mode 100644 index 000000000000..54fbedf498ee --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/FwdElectronScaleFactorCalculator.cxx @@ -0,0 +1,125 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +// $Id: ElectronScaleFactorCalculator.cxx 799556 2017-03-05 19:46:03Z tpelzer $ +#include "TopCorrections/FwdElectronScaleFactorCalculator.h" +#include "TopConfiguration/TopConfig.h" +#include "TopEvent/EventTools.h" + +#include "xAODEgamma/ElectronContainer.h" + + +namespace top { + FwdElectronScaleFactorCalculator::FwdElectronScaleFactorCalculator(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), + + m_systNominal(CP::SystematicSet()), + m_systID_UP(CP::SystematicSet()), + m_systID_DOWN(CP::SystematicSet()), + m_electronEffSFID("AsgFwdElectronEfficiencyCorrectionTool_ID"), + m_electronEffSFIDLoose("AsgFwdElectronEfficiencyCorrectionTool_IDLoose"), + m_decor_idSF("SetMe"), + m_decor_idSF_loose("SetMe") { + declareProperty("config", m_config); + } + + StatusCode FwdElectronScaleFactorCalculator::initialize() { + ATH_MSG_INFO(" top::FwdElectronScaleFactorCalculator initialize"); + + top::check(m_electronEffSFID.retrieve(), "Failed to retrieve FWD electron SF Tool"); + top::check(m_electronEffSFIDLoose.retrieve(), "Failed to retrieve FWD electron Loose SF Tool"); + + m_systID_UP.insert(CP::SystematicVariation("EL_EFF_FwdID_TOTAL_1NPCOR_PLUS_UNCOR", 1)); + m_systID_DOWN.insert(CP::SystematicVariation("EL_EFF_FwdID_TOTAL_1NPCOR_PLUS_UNCOR", -1)); + + m_decor_idSF = "FWDEL_SF_ID_" + m_config->fwdElectronID(); + m_decor_idSF_loose = "FWDEL_LOOSE_SF_ID_" + m_config->fwdElectronIDLoose(); + + return StatusCode::SUCCESS; + } + + StatusCode FwdElectronScaleFactorCalculator::execute() { + ///-- Loop over all electron collections --/// + for (auto currentSystematic : *m_config->systSgKeyMapFwdElectrons()) { + const xAOD::ElectronContainer* electrons(nullptr); + top::check(evtStore()->retrieve(electrons, currentSystematic.second), "failed to retrieve electrons"); + + ///-- Tell the SF tools to use the nominal systematic --/// + top::check(m_electronEffSFID->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFIDLoose->applySystematicVariation(m_systNominal), "Failed to set systematic"); + + /// -- Loop over all electrons in each collection --/// + for (auto electronPtr : *electrons) { + /// -- Does the electron pass object selection? --/// + bool passSelection(false); + if (electronPtr->isAvailable<char>("passPreORSelection")) { + if (electronPtr->auxdataConst<char>("passPreORSelection") == 1) { + passSelection = true; + } + } + if (electronPtr->isAvailable<char>("passPreORSelectionLoose")) { + if (electronPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) { + passSelection = true; + } + } + + if (passSelection) { + double SF_ID(1.), SF_IDLoose(1.); + + ///-- Get Efficiencies --/// + + top::check(m_electronEffSFID->getEfficiencyScaleFactor(*electronPtr, SF_ID), "Failed to get SF"); + top::check(m_electronEffSFIDLoose->getEfficiencyScaleFactor(*electronPtr, SF_IDLoose), "Failed to get SF"); + + + ///-- Decorate --/// + electronPtr->auxdecor<float>(m_decor_idSF) = SF_ID; + electronPtr->auxdecor<float>(m_decor_idSF_loose) = SF_IDLoose; + + ///-- For nominal calibration, vary the SF systematics --/// + if (currentSystematic.first == m_config->nominalHashValue()) { + double SF_ID_UP(1.), SF_IDLoose_UP(1.); + double SF_ID_DOWN(1.), SF_IDLoose_DOWN(1.); + + ///-- ID --/// + ///-- ID up --/// + top::check(m_electronEffSFID->applySystematicVariation(m_systID_UP), "Failed to set systematic"); + top::check(m_electronEffSFID->getEfficiencyScaleFactor(*electronPtr, SF_ID_UP), "Failed to get SF"); + top::check(m_electronEffSFIDLoose->applySystematicVariation(m_systID_UP), "Failed to set systematic"); + top::check(m_electronEffSFIDLoose->getEfficiencyScaleFactor(*electronPtr, SF_IDLoose_UP), + "Failed to get SF"); + + ///-- ID down --/// + top::check(m_electronEffSFID->applySystematicVariation(m_systID_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFID->getEfficiencyScaleFactor(*electronPtr, SF_ID_DOWN), "Failed to get SF"); + top::check(m_electronEffSFIDLoose->applySystematicVariation(m_systID_DOWN), "Failed to set systematic"); + top::check(m_electronEffSFIDLoose->getEfficiencyScaleFactor(*electronPtr, + SF_IDLoose_DOWN), "Failed to get SF"); + + ///-- ID reset to nominal --/// + top::check(m_electronEffSFID->applySystematicVariation(m_systNominal), "Failed to set systematic"); + top::check(m_electronEffSFIDLoose->applySystematicVariation(m_systNominal), "Failed to set systematic"); + + ///-- Decorate --/// + electronPtr->auxdecor<float>(m_decor_idSF + "_UP") = SF_ID_UP; + electronPtr->auxdecor<float>(m_decor_idSF + "_DOWN") = SF_ID_DOWN; + electronPtr->auxdecor<float>(m_decor_idSF_loose + "_UP") = SF_IDLoose_UP; + electronPtr->auxdecor<float>(m_decor_idSF_loose + "_DOWN") = SF_IDLoose_DOWN; + + ///-- Debug messages --/// + + ATH_MSG_DEBUG("Fwd Electron ID SF = " << electronPtr->auxdataConst<float>(m_decor_idSF) << " + " << + electronPtr->auxdataConst<float>(m_decor_idSF + "_UP") << " - " << + electronPtr->auxdataConst<float>(m_decor_idSF + "_DOWN") + ); + } // Calibration systematic is nominal, so calculate SF systematics + } + } + } + + + return StatusCode::SUCCESS; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/GlobalLeptonTriggerCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/GlobalLeptonTriggerCalculator.cxx new file mode 100644 index 000000000000..91b061a9cb15 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/GlobalLeptonTriggerCalculator.cxx @@ -0,0 +1,201 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopCorrections/GlobalLeptonTriggerCalculator.h" +#include "TopConfiguration/TopConfig.h" +#include "TopEvent/EventTools.h" +#include "TopEvent/SystematicEvent.h" + +#include "xAODEgamma/ElectronContainer.h" +#include "xAODEgamma/Electron.h" +#include "xAODMuon/MuonContainer.h" +#include "xAODMuon/Muon.h" +#include "xAODEventInfo/EventInfo.h" +#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h" +#include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h" +#include "ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h" +#include <vector> + + +namespace top { + GlobalLeptonTriggerCalculator::GlobalLeptonTriggerCalculator(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), + + m_globalTriggerSF("TrigGlobalEfficiencyCorrectionTool::TrigGlobal"), + m_globalTriggerSFLoose("TrigGlobalEfficiencyCorrectionTool::TrigGlobalLoose"), + + m_decor_triggerSF("AnalysisTop_Trigger_SF") { + declareProperty("config", m_config); + } + + StatusCode GlobalLeptonTriggerCalculator::initialize() { + ATH_MSG_INFO(" top::GlobalLeptonTriggerCalculator initialize"); + + if (m_config->doTightEvents()) top::check(m_globalTriggerSF.retrieve(), + "Failed to retrieve global trigger SF tool"); + if (m_config->doLooseEvents()) top::check( + m_globalTriggerSFLoose.retrieve(), "Failed to retrieve global trigger SF tool (loose)"); + + // Retrieve the systematic names we stored + for (auto& s : m_config->getGlobalTriggerElectronSystematics()) ATH_MSG_DEBUG(" - Electron systematics : " << s); + for (auto& s : m_config->getGlobalTriggerMuonSystematics()) ATH_MSG_DEBUG(" - Muon systematics : " << s); + + { + std::vector<ToolHandle<IAsgElectronEfficiencyCorrectionTool> > tools; + tools.reserve(m_config->getGlobalTriggerElectronTools().size()); + for (auto const& s : m_config->getGlobalTriggerElectronTools()) { + ATH_MSG_DEBUG(" - Electron tools : " << s); + tools.emplace_back(s); + top::check(tools.back().retrieve(), "Failed to retrieve electron tool"); + } + m_electronTools.swap(tools); + } + { + std::vector<ToolHandle<CP::IMuonTriggerScaleFactors> > tools; + tools.reserve(m_config->getGlobalTriggerMuonTools().size()); + for (auto const& s : m_config->getGlobalTriggerMuonTools()) { + ATH_MSG_DEBUG(" - Muon tools : " << s); + tools.emplace_back(s); + top::check(tools.back().retrieve(), "Failed to retrieve muon tool"); + } + m_muonTools.swap(tools); + } + + return StatusCode::SUCCESS; + } + + StatusCode GlobalLeptonTriggerCalculator::execute() { + ATH_MSG_DEBUG("Entered GlobalLeptonTriggerCalculator::execute"); + + auto const& nominalHash = m_config->nominalHashValue(); + if (m_config->doTightEvents()) { + xAOD::SystematicEventContainer const* systEvents = nullptr; + top::check(evtStore()->retrieve(systEvents, + m_config->sgKeyTopSystematicEvents()), + "Failed to get xAOD::SystematicEventContainer"); + for (const xAOD::SystematicEvent* systEvent : *systEvents) { + bool withScaleFactorVariations = (systEvent->hashValue() == nominalHash); + processEvent(systEvent, withScaleFactorVariations); + } + } + if (m_config->doLooseEvents()) { + xAOD::SystematicEventContainer const* systEvents = nullptr; + top::check(evtStore()->retrieve(systEvents, + m_config->sgKeyTopSystematicEventsLoose()), + "Failed to get xAOD::SystematicEventContainer"); + for (const xAOD::SystematicEvent* systEvent : *systEvents) { + bool withScaleFactorVariations = (systEvent->hashValue() == nominalHash); + processEvent(systEvent, withScaleFactorVariations); + } + } + + ATH_MSG_DEBUG("Leaving GlobalLeptonTriggerCalculator::execute"); + return StatusCode::SUCCESS; + } + + void GlobalLeptonTriggerCalculator::processEvent(const xAOD::SystematicEvent* systEvent, bool withScaleFactorVariations) { + auto const& hash = systEvent->hashValue(); + bool isLoose = systEvent->isLooseEvent(); + + std::string const& systname = m_config->systematicName(hash); + ATH_MSG_DEBUG("Calculating trigger SF for variation " << systname << " (" << hash << ") with isLoose=" << isLoose); + + // Retrieve nominal muons, retrieve nominal electrons + const xAOD::MuonContainer* muons(nullptr); + const xAOD::ElectronContainer* electrons(nullptr); + std::vector<const xAOD::Muon*> selectedMuons; + std::vector<const xAOD::Electron*> selectedElectrons; + + if (m_config->useMuons()) top::check(evtStore()->retrieve(muons, m_config->sgKeyMuons(hash)), "Failed to retrieve muons"); + + // Put into a vector + for (size_t index : systEvent->goodMuons()) { + selectedMuons.push_back(muons->at(index)); + } + + if (m_config->useElectrons()) top::check(evtStore()->retrieve(electrons, m_config->sgKeyElectrons(hash)), "Failed to retrieve electrons"); + // Put into a vector + for (size_t index : systEvent->goodElectrons()) { + selectedElectrons.push_back(electrons->at(index)); + } + + // manage current electron trigger SF variation + CP::SystematicSet electronSystSet; + auto setCurrentElectronVariation = [this, &electronSystSet](std::string const& parameterName, int value) { + electronSystSet.clear(); + if (!parameterName.empty()) electronSystSet.insert(CP::SystematicVariation( + parameterName, value)); + for (auto&& tool : m_electronTools) { + top::check(tool->applySystematicVariation( + electronSystSet), "Failed to apply systematic"); + } + }; + + // manage current muon trigger SF variation + CP::SystematicSet muonSystSet; + auto setCurrentMuonVariation = [this, &muonSystSet](std::string const& parameterName, int value) { + muonSystSet.clear(); + if (!parameterName.empty()) muonSystSet.insert(CP::SystematicVariation( + parameterName, value)); + for (auto&& tool : m_muonTools) { + top::check(tool->applySystematicVariation( + muonSystSet), "Failed to apply systematic"); + } + }; + + // compute and store trigger SF for current variation + auto&& globalTriggerTool = (isLoose ? m_globalTriggerSFLoose : m_globalTriggerSF); + auto decorateEventForCurrentVariation = [&]() { + double sf; + + if (selectedElectrons.empty() && selectedMuons.empty()) { + sf = 1.; + } else { + sf = NAN; + top::check(globalTriggerTool->getEfficiencyScaleFactor( + selectedElectrons, + selectedMuons, + sf), "Failed to get global trigger SF"); + } + std::string auxname(m_decor_triggerSF); + auxname += "_"; + if (!(electronSystSet.empty() && muonSystSet.empty())) { + CP::SystematicSet systSet; + systSet.insert(electronSystSet); + systSet.insert(muonSystSet); + auxname += systSet.name(); + } + ATH_MSG_DEBUG("Adding decoration " << auxname << " = " << sf); + systEvent->auxdecor<float>(auxname) = sf; + }; + + ///-- Set the nominal --/// + setCurrentElectronVariation("", 0); + setCurrentMuonVariation("", 0); + decorateEventForCurrentVariation(); + + ///-- Apply and calculate variations on nominal --/// + if (withScaleFactorVariations) { + ATH_MSG_DEBUG("Calculating trigger SF variations"); + std::unordered_set<std::string> variations; + ///-- Set nominal muon for electron systematic --/// + for (auto& s : m_config->getGlobalTriggerElectronSystematics()) { + for (int val : {1, -1}) { + setCurrentElectronVariation(s, val); + decorateEventForCurrentVariation(); + } + } + ///-- Set nominal electron for muon systematic --/// + setCurrentElectronVariation("", 0); + for (auto& s : m_config->getGlobalTriggerMuonSystematics()) { + for (int val : {1, -1}) { + setCurrentMuonVariation(s, val); + decorateEventForCurrentVariation(); + } + } + setCurrentMuonVariation("", 0); + } + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/JetScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/JetScaleFactorCalculator.cxx index 837ee1ebc5d9..8e45a9fb34f5 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/JetScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/JetScaleFactorCalculator.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // $Id: JetScaleFactorCalculator.cxx 794672 2017-01-31 00:41:04Z tpelzer $ #include "TopCorrections/JetScaleFactorCalculator.h" @@ -11,7 +11,6 @@ namespace top { - JetScaleFactorCalculator::JetScaleFactorCalculator(const std::string& name) : asg::AsgTool(name), m_config(nullptr), @@ -19,8 +18,9 @@ namespace top { m_systNominal(CP::SystematicSet()), m_systUP(CP::SystematicSet()), m_systDOWN(CP::SystematicSet()), - m_jvt_tool("JetJvtEfficiencyTool") { - declareProperty("config" , m_config); + m_jvt_tool("JetJvtEfficiencyTool"), + m_fjvt_tool("JetForwardJvtEfficiencyTool") { + declareProperty("config", m_config); } StatusCode JetScaleFactorCalculator::initialize() { @@ -31,21 +31,43 @@ namespace top { m_systUP.insert(CP::SystematicVariation(CP::JvtEfficiencyUp)); m_systDOWN.insert(CP::SystematicVariation(CP::JvtEfficiencyDown)); + // fJVT Efficiency tool is only set up if user requests it + if (m_config->getfJVTWP() != "None") { + top::check(m_fjvt_tool.retrieve(), "Failed to retrieve fJVT tool"); + + m_systUP.insert(CP::SystematicVariation(CP::fJvtEfficiencyUp)); + m_systDOWN.insert(CP::SystematicVariation(CP::fJvtEfficiencyDown)); + } + + return StatusCode::SUCCESS; } - StatusCode JetScaleFactorCalculator::execute() { ///-- Loop over all jet collections --/// - ///-- Lets assume that we're not doing ElectronInJet subtraction --/// + for (auto currentSystematic : *m_config->systSgKeyMapJets(false)) { const xAOD::JetContainer* jets(nullptr); - top::check(evtStore()->retrieve(jets, currentSystematic.second), "failed to retrieve jets"); - - ///-- Tell the SF tools to use the nominal systematic --/// - - /// -- Loop over all jets in each collection --/// - for (auto jetPtr : *jets) { + top::check(evtStore()->retrieve(jets, currentSystematic.second), "failed to retrieve jets in JetScaleFactorCalculator::execute()"); + top::check(this->decorateJets(jets,currentSystematic.first == m_config->nominalHashValue()),"failed to decorate jets in JetScaleFactorCalculator::execute()"); + } + + if(m_config->doLooseEvents() && m_config->applyElectronInJetSubtraction()) + { + for (auto currentSystematic : *m_config->systSgKeyMapJets(true)) { + const xAOD::JetContainer* jets(nullptr); + top::check(evtStore()->retrieve(jets, currentSystematic.second), "failed to retrieve loose jets in JetScaleFactorCalculator::execute()"); + top::check(this->decorateJets(jets,currentSystematic.first == m_config->nominalHashValue()),"failed to decorate loose jets in JetScaleFactorCalculator::execute()"); + } + } + + return StatusCode::SUCCESS; + } + + StatusCode JetScaleFactorCalculator::decorateJets(const xAOD::JetContainer* jets, bool isNominal){ + + /// -- Loop over all jets in each collection --/// + for (const xAOD::Jet *jetPtr : *jets) { /// -- Does the jet pass object selection? --/// // WARNING: this doesn't include the JVT cut anymore bool passSelection(false); @@ -61,6 +83,7 @@ namespace top { } if (passSelection) { + ///-- JVT first --/// // Set to nominal first... top::check(m_jvt_tool->applySystematicVariation(m_systNominal), "Failed to set JVT nominal SF"); @@ -72,11 +95,11 @@ namespace top { return StatusCode::FAILURE; } - bool passes_jvt = jetPtr->auxdataConst< char >("passJVT"); + int passes_jvt = jetPtr->auxdataConst< char >("passJVT"); + if (passes_jvt < 0) continue; - if (passes_jvt) - top::check(m_jvt_tool->getEfficiencyScaleFactor(*jetPtr, jvtSF), - "Failed to getEfficiencyScaleFactor for JVT"); + if (passes_jvt) top::check(m_jvt_tool->getEfficiencyScaleFactor(*jetPtr, jvtSF), + "Failed to getEfficiencyScaleFactor for JVT"); else { top::check(m_jvt_tool->getInefficiencyScaleFactor(*jetPtr, jvtSF), "Failed to getInefficiencyScaleFactor for JVT"); @@ -85,8 +108,7 @@ namespace top { jetPtr->auxdecor<float>("JET_SF_jvt") = jvtSF; ///-- For nominal calibration, vary the SF systematics --/// - if (currentSystematic.first == m_config->nominalHashValue()) { - + if (isNominal) { float jvtSF_up(1.), jvtSF_down(1.); // made up values if (passes_jvt) { @@ -98,8 +120,7 @@ namespace top { "Failed to applySystematicVariation down for JVT"); top::check(m_jvt_tool->getEfficiencyScaleFactor(*jetPtr, jvtSF_down), "Failed to get JVT SF (systematic down)"); - } - else { + } else { top::check(m_jvt_tool->applySystematicVariation(m_systUP), "Failed to applySystematicVariation up for JVT"); top::check(m_jvt_tool->getInefficiencyScaleFactor(*jetPtr, jvtSF_up), @@ -113,14 +134,58 @@ namespace top { ///-- Decorate --/// jetPtr->auxdecor<float>("JET_SF_jvt_UP") = jvtSF_up; jetPtr->auxdecor<float>("JET_SF_jvt_DOWN") = jvtSF_down; - } // Calibration systematic is nominal, so calculate SF systematics + } // Calibration systematic is nominal, so calculate SF systematics + + ///-- Then fJVT --/// + if (m_config->getfJVTWP() != "None") { + top::check(m_fjvt_tool->applySystematicVariation(m_systNominal), + "Failed to set fJVT nominal SF"); + float fjvtSF(1.); + + if (!jetPtr->isAvailable<char>("AnalysisTop_fJVTdecision")) { + ATH_MSG_ERROR(" Can't find jet decoration \"AnalysisTop_fJVTdecision\" - we need it to calculate the jet fJVT scale-factors!"); + return StatusCode::FAILURE; + } + int passes_fjvt = jetPtr->auxdataConst< char >("AnalysisTop_fJVTdecision"); + if (passes_fjvt < 0) continue; + if (passes_fjvt) top::check(m_fjvt_tool->getEfficiencyScaleFactor(*jetPtr, fjvtSF), + "Failed to getEfficiencyScaleFactor for fJVT"); + else { + top::check(m_fjvt_tool->getInefficiencyScaleFactor(*jetPtr, fjvtSF), + "Failed to getInefficiencyScaleFactor for fJVT"); + } + jetPtr->auxdecor<float>("JET_SF_fjvt") = fjvtSF; + + if (isNominal) { + float fjvtSF_up(1.), fjvtSF_down(1.); // made up values + if (passes_fjvt) { + top::check(m_fjvt_tool->applySystematicVariation(m_systUP), + "Failed to applySystematicVariation up for fJVT"); + top::check(m_fjvt_tool->getEfficiencyScaleFactor(*jetPtr, fjvtSF_up), + "Failed to get fJVT SF (systematic up)"); + top::check(m_fjvt_tool->applySystematicVariation(m_systDOWN), + "Failed to applySystematicVariation down for fJVT"); + top::check(m_fjvt_tool->getEfficiencyScaleFactor(*jetPtr, fjvtSF_down), + "Failed to get fJVT SF (systematic down)"); + } else { + top::check(m_fjvt_tool->applySystematicVariation(m_systUP), + "Failed to applySystematicVariation up for fJVT"); + top::check(m_fjvt_tool->getInefficiencyScaleFactor(*jetPtr, fjvtSF_up), + "Failed to get fJVT SF (systematic up)"); + top::check(m_fjvt_tool->applySystematicVariation(m_systDOWN), + "Failed to applySystematicVariation down for fJVT"); + top::check(m_fjvt_tool->getInefficiencyScaleFactor(*jetPtr, fjvtSF_down), + "Failed to get fJVT SF (systematic down)"); + } + ///-- Decorate --/// + jetPtr->auxdecor<float>("JET_SF_fjvt_UP") = fjvtSF_up; + jetPtr->auxdecor<float>("JET_SF_fjvt_DOWN") = fjvtSF_down; + + } // Calibration systematic is nominal, so calculate SF systematics + } } } - } - - return StatusCode::SUCCESS; } - } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/LinkDef.h new file mode 100644 index 000000000000..a1934eb914be --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/LinkDef.h @@ -0,0 +1,18 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration. + */ + +#include "TopCorrections/ScaleFactorRetriever.h" + +#ifdef __CINT__ + +#pragma extra_include "TopCorrections/ScaleFactorRetriever.h"; + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; +#pragma link C++ nestedclass; + +#pragma link C++ class top::ScaleFactorRetriever+; + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/MsgCategory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/MsgCategory.cxx new file mode 100644 index 000000000000..cb158bc6f7e0 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/MsgCategory.cxx @@ -0,0 +1,6 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#include "TopCorrections/MsgCategory.h" + +ANA_MSG_SOURCE(TopCorrections, "TopCorrections") diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/MuonScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/MuonScaleFactorCalculator.cxx index 9ddd85ef4032..be233b338490 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/MuonScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/MuonScaleFactorCalculator.cxx @@ -1,8 +1,8 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -// $Id: MuonScaleFactorCalculator.cxx 796972 2017-02-14 03:08:26Z tpelzer $ +// $Id: MuonScaleFactorCalculator.cxx 805964 2017-06-05 19:27:16Z iconnell $ #include "TopCorrections/MuonScaleFactorCalculator.h" #include <string> @@ -16,18 +16,13 @@ #include "xAODMuon/MuonContainer.h" namespace top { - MuonScaleFactorCalculator::MuonScaleFactorCalculator(const std::string& name) : asg::AsgTool(name), m_config(nullptr), m_systNominal(CP::SystematicSet()), - m_muonTriggerScaleFactors_2015("CP::MuonTriggerScaleFactors_2015"), - m_muonTriggerScaleFactorsLoose_2015("CP::MuonTriggerScaleFactorsLoose_2015"), - m_muonTriggerScaleFactors_2016("CP::MuonTriggerScaleFactors_2016"), - m_muonTriggerScaleFactorsLoose_2016("CP::MuonTriggerScaleFactorsLoose_2016"), - m_muonEfficiencyCorrectionsTool("CP::MuonEfficiencyScaleFactorsTool"), + m_softmuonEfficiencyCorrectionsTool("CP::SoftMuonEfficiencyScaleFactorsTool"), m_muonEfficiencyCorrectionsToolLoose("CP::MuonEfficiencyScaleFactorsToolLoose"), m_muonEfficiencyCorrectionsToolIso("CP::MuonEfficiencyScaleFactorsToolIso"), m_muonEfficiencyCorrectionsToolLooseIso("CP::MuonEfficiencyScaleFactorsToolLooseIso"), @@ -39,6 +34,8 @@ namespace top { m_decor_isoSF("SetMe"), m_decor_isoSF_loose("SetMe"), m_decor_TTVA("MU_SF_TTVA"), + m_decor_softmuon_idSF("SetMe"), + m_do_muon_isolation_SFs(true), m_do_muon_isolation_SFs_loose(true), // The systematics are defined here... @@ -47,57 +44,69 @@ namespace top { m_trig_sf_syst_UP("MUON_EFF_TrigSystUncertainty__1up"), m_trig_sf_syst_DOWN("MUON_EFF_TrigSystUncertainty__1down"), - m_reco_stat_UP("MUON_EFF_STAT__1up"), - m_reco_stat_DOWN("MUON_EFF_STAT__1down"), - m_reco_syst_UP("MUON_EFF_SYS__1up"), - m_reco_syst_DOWN("MUON_EFF_SYS__1down"), - - m_reco_stat_lowpt_UP("MUON_EFF_STAT_LOWPT__1up"), - m_reco_stat_lowpt_DOWN("MUON_EFF_STAT_LOWPT__1down"), - m_reco_syst_lowpt_UP("MUON_EFF_SYS_LOWPT__1up"), - m_reco_syst_lowpt_DOWN("MUON_EFF_SYS_LOWPT__1down"), - - m_iso_stat_UP("MUON_ISO_STAT__1up"), - m_iso_stat_DOWN("MUON_ISO_STAT__1down"), - m_iso_syst_UP("MUON_ISO_SYS__1up"), - m_iso_syst_DOWN("MUON_ISO_SYS__1down"), - - m_TTVA_stat_UP("MUON_TTVA_STAT__1up"), - m_TTVA_stat_DOWN("MUON_TTVA_STAT__1down"), - m_TTVA_syst_UP("MUON_TTVA_SYS__1up"), - m_TTVA_syst_DOWN("MUON_TTVA_SYS__1down") { + m_reco_stat_UP("MUON_EFF_RECO_STAT__1up"), + m_reco_stat_DOWN("MUON_EFF_RECO_STAT__1down"), + m_reco_syst_UP("MUON_EFF_RECO_SYS__1up"), + m_reco_syst_DOWN("MUON_EFF_RECO_SYS__1down"), + + m_reco_stat_lowpt_UP("MUON_EFF_RECO_STAT_LOWPT__1up"), + m_reco_stat_lowpt_DOWN("MUON_EFF_RECO_STAT_LOWPT__1down"), + m_reco_syst_lowpt_UP("MUON_EFF_RECO_SYS_LOWPT__1up"), + m_reco_syst_lowpt_DOWN("MUON_EFF_RECO_SYS_LOWPT__1down"), + + m_iso_stat_UP("MUON_EFF_ISO_STAT__1up"), + m_iso_stat_DOWN("MUON_EFF_ISO_STAT__1down"), + m_iso_syst_UP("MUON_EFF_ISO_SYS__1up"), + m_iso_syst_DOWN("MUON_EFF_ISO_SYS__1down"), + + m_TTVA_stat_UP("MUON_EFF_TTVA_STAT__1up"), + m_TTVA_stat_DOWN("MUON_EFF_TTVA_STAT__1down"), + m_TTVA_syst_UP("MUON_EFF_TTVA_SYS__1up"), + m_TTVA_syst_DOWN("MUON_EFF_TTVA_SYS__1down") { declareProperty("config", m_config); } StatusCode MuonScaleFactorCalculator::initialize() { ATH_MSG_INFO(" top::MuonScaleFactorCalculator initialize"); - std::set<std::string> implemented_systematics = - {"MUON_EFF_TrigStatUncertainty", - "MUON_EFF_TrigSystUncertainty", - "MUON_EFF_STAT", - "MUON_EFF_SYS", - "MUON_EFF_STAT_LOWPT", - "MUON_EFF_SYS_LOWPT", - "MUON_ISO_STAT", - "MUON_ISO_SYS", - "MUON_TTVA_STAT", - "MUON_TTVA_SYS"}; + m_muonTriggerScaleFactors_R21 = ToolHandle<CP::IMuonTriggerScaleFactors>("CP::MuonTriggerScaleFactors_R21"); + m_muonTriggerScaleFactorsLoose_R21 = + ToolHandle<CP::IMuonTriggerScaleFactors>("CP::MuonTriggerScaleFactorsLoose_R21"); + + std::set<std::string> implemented_systematics; + implemented_systematics = { + "MUON_EFF_RECO_STAT", + "MUON_EFF_RECO_STAT_LOWPT", + "MUON_EFF_RECO_SYS", + "MUON_EFF_RECO_SYS_LOWPT", + "MUON_EFF_TrigStatUncertainty", + "MUON_EFF_TrigSystUncertainty", + "MUON_EFF_ISO_STAT", + "MUON_EFF_ISO_SYS", + "MUON_EFF_TTVA_STAT", + "MUON_EFF_TTVA_SYS" + }; std::set<std::string> recommended_systematics; - this->retrieveSystematicTool(m_muonTriggerScaleFactors_2015, - recommended_systematics); - this->retrieveSystematicTool(m_muonTriggerScaleFactorsLoose_2015, - recommended_systematics); - this->retrieveSystematicTool(m_muonTriggerScaleFactors_2016, + + // For R21, a single tool + this->retrieveSystematicTool(m_muonTriggerScaleFactors_R21, recommended_systematics); - this->retrieveSystematicTool(m_muonTriggerScaleFactorsLoose_2016, + this->retrieveSystematicTool(m_muonTriggerScaleFactorsLoose_R21, recommended_systematics); + this->retrieveSystematicTool(m_muonEfficiencyCorrectionsTool, recommended_systematics); + + if (m_config->useSoftMuons()) { + this->retrieveSystematicTool(m_softmuonEfficiencyCorrectionsTool, + recommended_systematics); + } + this->retrieveSystematicTool(m_muonEfficiencyCorrectionsToolLoose, recommended_systematics); + if (asg::ToolStore::contains<CP::IMuonEfficiencyScaleFactors>("CP::MuonEfficiencyScaleFactorsToolIso")) { this->retrieveSystematicTool(m_muonEfficiencyCorrectionsToolIso, recommended_systematics); @@ -112,14 +121,14 @@ namespace top { } ///-- Not a good reason for this happening at the moment --/// - if (m_config->muonIsolation() != "None" && !m_do_muon_isolation_SFs) { + if (m_config->muonIsolationSF() != "None" && !m_do_muon_isolation_SFs) { ATH_MSG_WARNING("No muon isolation SFs available." " You can run with MuonIsolation set to" " None if you don't want isolation."); return StatusCode::FAILURE; } ///-- Not a good reason for this happening at the moment --/// - if (m_config->muonIsolationLoose() != "None" && !m_do_muon_isolation_SFs_loose) { + if (m_config->muonIsolationSFLoose() != "None" && !m_do_muon_isolation_SFs_loose) { ATH_MSG_WARNING("No loose muon isolation SFs available." " You can run with MuonIsolationLoose set to" " None if you don't want isolation."); @@ -135,26 +144,27 @@ namespace top { " muon SF systematic uncertainties"); - m_decor_triggerEff = "MU_EFF_Trigger_" + m_config->muonQuality(); - m_decor_triggerEff_loose = "MU_EFF_Trigger_" + m_config->muonQualityLoose(); - m_decor_triggerSF = "MU_SF_Trigger_" + m_config->muonQuality(); - m_decor_triggerSF_loose = "MU_SF_Trigger_" + m_config->muonQualityLoose(); - m_decor_idSF = "MU_SF_ID_" + m_config->muonQuality(); - m_decor_idSF_loose = "MU_SF_ID_" + m_config->muonQualityLoose(); - m_decor_isoSF = "MU_SF_Isol_" + m_config->muonIsolation(); - m_decor_isoSF_loose = "MU_SF_Isol_" + m_config->muonIsolationLoose(); + m_decor_triggerEff = "MU_EFF_Trigger_" + m_config->muonQuality(); + m_decor_triggerEff_loose = "MU_LOOSE_EFF_Trigger_" + m_config->muonQualityLoose(); + m_decor_triggerSF = "MU_SF_Trigger_" + m_config->muonQuality(); + m_decor_triggerSF_loose = "MU_LOOSE_SF_Trigger_" + m_config->muonQualityLoose(); + m_decor_idSF = "MU_SF_ID_" + m_config->muonQuality(); + m_decor_idSF_loose = "MU_LOOSE_SF_ID_" + m_config->muonQualityLoose(); + m_decor_isoSF = "MU_SF_Isol_" + m_config->muonIsolationSF(); + m_decor_isoSF_loose = "MU_LOOSE_SF_Isol_" + m_config->muonIsolationSFLoose(); + + m_decor_softmuon_idSF = "SOFTMU_SF_ID_" + m_config->softmuonQuality(); return StatusCode::SUCCESS; } - StatusCode MuonScaleFactorCalculator::execute() { /************************************************************* - * - * The muon trigger SF tool wants a random run number, - * which we can get from the PRW tool. - * - *************************************************************/ + * + * The muon trigger SF tool wants a random run number, + * which we can get from the PRW tool. + * + *************************************************************/ if (m_config->doPileupReweighting()) { const xAOD::EventInfo* eventInfo(nullptr); @@ -163,36 +173,36 @@ namespace top { // This is the default value in the MuonTriggerScaleFactors tool unsigned int runNumber = 267639; - if (eventInfo->isAvailable<unsigned int>("RandomRunNumber")) - runNumber = eventInfo->auxdataConst<unsigned int>("RandomRunNumber"); - else - ATH_MSG_WARNING("Event has not been decorated with RandomRunNumber"); - - if (runNumber > 284484 || runNumber == 0) { - m_muonTriggerScaleFactors = m_muonTriggerScaleFactors_2016; - m_muonTriggerScaleFactorsLoose = m_muonTriggerScaleFactors_2016; + if (eventInfo->isAvailable<unsigned int>("RandomRunNumber")) runNumber = eventInfo->auxdataConst<unsigned int>( + "RandomRunNumber"); + else ATH_MSG_WARNING("Event has not been decorated with RandomRunNumber"); + + // Keep an eye here for trigger strings + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15#Supported_triggers + m_muonTriggerScaleFactors = m_muonTriggerScaleFactors_R21; + m_muonTriggerScaleFactorsLoose = m_muonTriggerScaleFactorsLoose_R21; + m_muon_trigger_sf_config = ""; + + if (runNumber == 0) { m_muon_trigger_sf_config = "HLT_mu26_ivarmedium_OR_HLT_mu50"; - } else { - m_muonTriggerScaleFactors = m_muonTriggerScaleFactors_2015; - m_muonTriggerScaleFactorsLoose = m_muonTriggerScaleFactors_2015; + } + // 2015 + else if (runNumber > 0 && runNumber <= 284484) { m_muon_trigger_sf_config = "HLT_mu20_iloose_L1MU15_OR_HLT_mu50"; } + // 2016 (set to a large value but split as we may need to have strings for 2016 -> certain 2017 run) + else if (runNumber > 284484 && runNumber < 324320) { + m_muon_trigger_sf_config = "HLT_mu26_ivarmedium_OR_HLT_mu50"; + } + // 2017+ (324320+) + else { + m_muon_trigger_sf_config = "HLT_mu26_ivarmedium_OR_HLT_mu50"; + } - // The PRW tool can give run numbers of zero for unrepresented - // mu values. If we give the muon tool a run number of zero it - // complains with the message: - // "WARNING I am using run #0 but I cannot find corresponding run period. - // Now setting to use 2016 period B. - // This might give problems! Please check which year and mc you - // have set up". - // We do this by hand to avoid the messages. - if (runNumber == 0) runNumber = 300345; - - top::check(m_muonTriggerScaleFactors->setRunNumber(runNumber), - "Failed to set run number for muon trigger SFs"); - top::check(m_muonTriggerScaleFactorsLoose->setRunNumber(runNumber), - "Failed to set run number for (loose) muon trigger SFs"); - } + ATH_MSG_DEBUG("Muon trigger scale factor config is : " + m_muon_trigger_sf_config); + ATH_MSG_DEBUG("RunNumber (0 < 2015 < 284484 < 2016 < 324320 < 2017) : "); + ATH_MSG_DEBUG(runNumber); + }//end of if (m_config->doPileupReweighting()) ///-- Loop over all muon collections --/// for (auto currentSystematic : *m_config->systSgKeyMapMuons()) { @@ -226,10 +236,9 @@ namespace top { this->applySystematicVariation(m_muonEfficiencyCorrectionsToolTTVA, m_systNominal); //-- Only do isolation if we actually get the tools --// - if (m_do_muon_isolation_SFs) - this->applySystematicVariation(m_muonEfficiencyCorrectionsToolIso, m_systNominal); - if (m_do_muon_isolation_SFs_loose) - this->applySystematicVariation(m_muonEfficiencyCorrectionsToolLooseIso, m_systNominal); + if (m_do_muon_isolation_SFs) this->applySystematicVariation(m_muonEfficiencyCorrectionsToolIso, m_systNominal); + if (m_do_muon_isolation_SFs_loose) this->applySystematicVariation(m_muonEfficiencyCorrectionsToolLooseIso, + m_systNominal); // The nominal SFs/efficiencies. // Include are:: @@ -275,19 +284,19 @@ namespace top { m_systNominal, *muonPtr, TTVA_decor); /********************************************************************** - * Muon Trigger Scale Factors - * TOM : The MCP tool takes a container of muons. The examples seem to - * suggest these should somehow be selected muons but it isn't clear - * to me what level of selection should be applied. - * - * *** To be followed up with MCP people by Jay *** - * - * TOM : We trick it by creating a view container - * with a single muon in. - * NOTE: This also happens later on for the systematics so if we ever - * get a nice function make sure we change it there too! - * - **********************************************************************/ + * Muon Trigger Scale Factors + * TOM : The MCP tool takes a container of muons. The examples seem to + * suggest these should somehow be selected muons but it isn't clear + * to me what level of selection should be applied. + * + * *** To be followed up with MCP people by Jay *** + * + * TOM : We trick it by creating a view container + * with a single muon in. + * NOTE: This also happens later on for the systematics so if we ever + * get a nice function make sure we change it there too! + * + **********************************************************************/ ConstDataVector<xAOD::MuonContainer> trigger_SF_muon(SG::VIEW_ELEMENTS); trigger_SF_muon.push_back(muonPtr); @@ -302,7 +311,7 @@ namespace top { trig_sf_decor, trig_eff_decor); this->decorateTrigSFandEff(m_muonTriggerScaleFactorsLoose, m_systNominal, trigger_SF_muon, - trig_sf_loose_decor, trig_eff_decor); + trig_sf_loose_decor, trig_eff_loose_decor); // If we are running on the nominal tree, then do the // SF systematic variations too. @@ -319,6 +328,46 @@ namespace top { this->decorateTTVASystematics(*muonPtr); } } + + ///-- Loop over all soft muon collections --/// + for (const std::pair<std::size_t, std::string>& currentSystematic : *m_config->systSgKeyMapSoftMuons()) { + const xAOD::MuonContainer* softmuons(nullptr); + top::check(evtStore()->retrieve(softmuons, currentSystematic.second), + "Failed to retrieve softmuons"); + + /// -- Loop over all soft muons in each collection --/// + for (const xAOD::Muon* muonPtr : *softmuons) { + /// -- Does the soft muon pass object selection? --/// + bool passSelection(false); + if (muonPtr->isAvailable<char>("passPreORSelection")) { + if (muonPtr->auxdataConst<char>("passPreORSelection") == 1) { + passSelection = true; + } + } + + if (!passSelection) continue; + + // Tell the SF tools to use the nominal systematic + // To be extra sure we do this when we try and get a SF too! + this->applySystematicVariation(m_softmuonEfficiencyCorrectionsTool, m_systNominal); + + // Reco efficiency and ID SF decorations + static SG::AuxElement::Decorator<float> id_sf_decor(m_decor_softmuon_idSF); + + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_systNominal, *muonPtr, + id_sf_decor); + + // If we are running on the nominal tree, then do the + // SF systematic variations too. + // Otherwise just move onto the next muon... + if (currentSystematic.first != m_config->nominalHashValue()) continue; + + // ID systematics + this->decorateIDSFandRecoEffSystematicsSoftMuon(*muonPtr); + }//end of loop on soft muons + } + return StatusCode::SUCCESS; } @@ -333,7 +382,6 @@ namespace top { recommended_systematics.insert(std::string(s)); } - template<typename T> void MuonScaleFactorCalculator::applySystematicVariation(ToolHandle<T>& tool, const CP::SystematicSet& systematic) { @@ -352,6 +400,12 @@ namespace top { implemented.end(), std::back_inserter(different_systematics)); if (different_systematics.size()) { + ATH_MSG_WARNING("WE ARE EXPECTING THE FOLLOWING SYSTEMATICS:"); + for (auto syst : recommended) + ATH_MSG_WARNING("\t" << syst); + ATH_MSG_WARNING("WE HAVE THE FOLLOWING SYSTEMATICS:"); + for (auto syst : implemented) + ATH_MSG_WARNING("\t" << syst); ATH_MSG_WARNING("WE ARE MISSING THE FOLLOWING SYSTEMATICS:"); for (auto syst : different_systematics) ATH_MSG_WARNING("\t" << syst); @@ -364,6 +418,7 @@ namespace top { const xAOD::Muon& muon, const SG::AuxElement::Decorator<float>& decor) { double trigEff = 1.0; + top::check(tool->getTriggerEfficiency(muon, trigEff, m_muon_trigger_sf_config, !m_config->isMC()), @@ -375,6 +430,7 @@ namespace top { const ConstDataVector<xAOD::MuonContainer>& muon_cont, const SG::AuxElement::Decorator<float>& decor) { double trigSF = 1.0; + top::check(tool->getTriggerScaleFactor(*muon_cont.asDataVector(), trigSF, m_muon_trigger_sf_config), "Failed to get muon trigger scale factor"); @@ -394,7 +450,8 @@ namespace top { this->decorateTriggerEfficiency(tool, *muon_cont[0], eff_decor); } - void MuonScaleFactorCalculator::decorateTriggerSystematics(const ConstDataVector<xAOD::MuonContainer>& trigger_SF_muon) { + void MuonScaleFactorCalculator::decorateTriggerSystematics(const ConstDataVector<xAOD::MuonContainer>& trigger_SF_muon) + { // Perform all trigger systematic variations, for loose and tight, // (stat/syst up/down) static SG::AuxElement::Decorator<float> trig_eff_decor_stat_up(m_decor_triggerEff + "_STAT_UP"); @@ -482,16 +539,16 @@ namespace top { void MuonScaleFactorCalculator::decorateIsolationSystematics(const xAOD::Muon& muon) { // Decorate 'tight' isolation SFs - static SG::AuxElement::Decorator<float> iso_sf_decor_stat_up(m_decor_isoSF+"_STAT_UP"); - static SG::AuxElement::Decorator<float> iso_sf_decor_stat_down(m_decor_isoSF+"_STAT_DOWN"); - static SG::AuxElement::Decorator<float> iso_sf_decor_syst_up(m_decor_isoSF+"_SYST_UP"); - static SG::AuxElement::Decorator<float> iso_sf_decor_syst_down(m_decor_isoSF+"_SYST_DOWN"); + static SG::AuxElement::Decorator<float> iso_sf_decor_stat_up(m_decor_isoSF + "_STAT_UP"); + static SG::AuxElement::Decorator<float> iso_sf_decor_stat_down(m_decor_isoSF + "_STAT_DOWN"); + static SG::AuxElement::Decorator<float> iso_sf_decor_syst_up(m_decor_isoSF + "_SYST_UP"); + static SG::AuxElement::Decorator<float> iso_sf_decor_syst_down(m_decor_isoSF + "_SYST_DOWN"); // Decorate 'loose' isolation SFs - static SG::AuxElement::Decorator<float> iso_sf_loose_decor_stat_up(m_decor_isoSF_loose+"_STAT_UP"); - static SG::AuxElement::Decorator<float> iso_sf_loose_decor_stat_down(m_decor_isoSF_loose+"_STAT_DOWN"); - static SG::AuxElement::Decorator<float> iso_sf_loose_decor_syst_up(m_decor_isoSF_loose+"_SYST_UP"); - static SG::AuxElement::Decorator<float> iso_sf_loose_decor_syst_down(m_decor_isoSF_loose+"_SYST_DOWN"); + static SG::AuxElement::Decorator<float> iso_sf_loose_decor_stat_up(m_decor_isoSF_loose + "_STAT_UP"); + static SG::AuxElement::Decorator<float> iso_sf_loose_decor_stat_down(m_decor_isoSF_loose + "_STAT_DOWN"); + static SG::AuxElement::Decorator<float> iso_sf_loose_decor_syst_up(m_decor_isoSF_loose + "_SYST_UP"); + static SG::AuxElement::Decorator<float> iso_sf_loose_decor_syst_down(m_decor_isoSF_loose + "_SYST_DOWN"); if (m_do_muon_isolation_SFs) { ///-- Stat UP --/// @@ -547,10 +604,10 @@ namespace top { } void MuonScaleFactorCalculator::decorateTTVASystematics(const xAOD::Muon& muon) { - static SG::AuxElement::Decorator<float> TTVA_decor_stat_up(m_decor_TTVA+"_STAT_UP"); - static SG::AuxElement::Decorator<float> TTVA_decor_stat_down(m_decor_TTVA+"_STAT_DOWN"); - static SG::AuxElement::Decorator<float> TTVA_decor_syst_up(m_decor_TTVA+"_SYST_UP"); - static SG::AuxElement::Decorator<float> TTVA_decor_syst_down(m_decor_TTVA+"_SYST_DOWN"); + static SG::AuxElement::Decorator<float> TTVA_decor_stat_up(m_decor_TTVA + "_STAT_UP"); + static SG::AuxElement::Decorator<float> TTVA_decor_stat_down(m_decor_TTVA + "_STAT_DOWN"); + static SG::AuxElement::Decorator<float> TTVA_decor_syst_up(m_decor_TTVA + "_SYST_UP"); + static SG::AuxElement::Decorator<float> TTVA_decor_syst_down(m_decor_TTVA + "_SYST_DOWN"); this->decorateEfficiencySF(m_muonEfficiencyCorrectionsToolTTVA, m_TTVA_stat_UP, muon, TTVA_decor_stat_up); @@ -660,4 +717,63 @@ namespace top { m_reco_syst_lowpt_DOWN, muon, id_sf_loose_decor_syst_lowpt_down); } + + void MuonScaleFactorCalculator::decorateIDSFandRecoEffSystematicsSoftMuon(const xAOD::Muon& muon) { + static SG::AuxElement::Decorator<float> id_sf_decor_stat_up(m_decor_softmuon_idSF + "_STAT_UP"); + + static SG::AuxElement::Decorator<float> id_sf_decor_stat_down(m_decor_softmuon_idSF + "_STAT_DOWN"); + + static SG::AuxElement::Decorator<float> id_sf_decor_syst_up(m_decor_softmuon_idSF + "_SYST_UP"); + + static SG::AuxElement::Decorator<float> id_sf_decor_syst_down(m_decor_softmuon_idSF + "_SYST_DOWN"); + + + ///-- Stat UP --/// + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_reco_stat_UP, muon, + id_sf_decor_stat_up); + + ///-- Stat DOWN --/// + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_reco_stat_DOWN, muon, + id_sf_decor_stat_down); + + ///-- Syst UP --/// + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_reco_syst_UP, muon, + id_sf_decor_syst_up); + + ///-- Syst DOWN --/// + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_reco_syst_DOWN, muon, + id_sf_decor_syst_down); + + static SG::AuxElement::Decorator<float> id_sf_decor_stat_lowpt_up(m_decor_softmuon_idSF + "_STAT_LOWPT_UP"); + + static SG::AuxElement::Decorator<float> id_sf_decor_stat_lowpt_down(m_decor_softmuon_idSF + "_STAT_LOWPT_DOWN"); + + static SG::AuxElement::Decorator<float> id_sf_decor_syst_lowpt_up(m_decor_softmuon_idSF + "_SYST_LOWPT_UP"); + + static SG::AuxElement::Decorator<float> id_sf_decor_syst_lowpt_down(m_decor_softmuon_idSF + "_SYST_LOWPT_DOWN"); + + ///-- Stat UP --/// + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_reco_stat_lowpt_UP, muon, + id_sf_decor_stat_lowpt_up); + + ///-- Stat DOWN --/// + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_reco_stat_lowpt_DOWN, muon, + id_sf_decor_stat_lowpt_down); + + ///-- Syst UP --/// + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_reco_syst_lowpt_UP, muon, + id_sf_decor_syst_lowpt_up); + + ///-- Syst DOWN --/// + this->decorateIDSFandRecoEff(m_softmuonEfficiencyCorrectionsTool, + m_reco_syst_lowpt_DOWN, muon, + id_sf_decor_syst_lowpt_down); + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PDFScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PDFScaleFactorCalculator.cxx index 1abf2f9743bf..b308b56fa2f1 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PDFScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PDFScaleFactorCalculator.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopCorrections/PDFScaleFactorCalculator.h" @@ -12,123 +12,110 @@ #include "xAODEventInfo/EventInfo.h" namespace top { - - PDFScaleFactorCalculator::PDFScaleFactorCalculator( const std::string& name ) : - asg::AsgTool( name ), - m_config(nullptr){ - - declareProperty( "config" , m_config ); - + PDFScaleFactorCalculator::PDFScaleFactorCalculator(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr) { + declareProperty("config", m_config); } - StatusCode PDFScaleFactorCalculator::initialize() - { - - ATH_MSG_INFO(" top::PDFScaleFactorCalculator initialize" ); + StatusCode PDFScaleFactorCalculator::initialize() { + ATH_MSG_INFO(" top::PDFScaleFactorCalculator initialize"); // This prints all the available PDFsets we can use //printAvailablePDFs(); - for( const std::string& set_name : m_config->LHAPDFSets() ) { - m_pdf_sets[ set_name ] = PDFSet( set_name ); + for (const std::string& set_name : m_config->LHAPDFSets()) { + m_pdf_sets[ set_name ] = PDFSet(set_name); } m_base_pdf_name = m_config->baseLHAPDF(); if (!m_base_pdf_name.empty()) { - ATH_MSG_INFO("Enabling " << m_base_pdf_name << " to recompute PDF weights.\n Content of sumWeight and totalSumWeight trees might be inconsistent with this recalculation.\n Use only PDFSumWeight and for PDF uncertainty estimates.\n"); + ATH_MSG_INFO( + "Enabling " << m_base_pdf_name << + " to recompute PDF weights.\n Content of sumWeight and totalSumWeight trees might be inconsistent with this recalculation.\n Use only PDFSumWeight and for PDF uncertainty estimates.\n"); m_basepdf = LHAPDF::mkPDF(m_base_pdf_name, 0); } return StatusCode::SUCCESS; - } - StatusCode PDFScaleFactorCalculator::execute() - { - + StatusCode PDFScaleFactorCalculator::execute() { // Get the event info for the MC weight const xAOD::EventInfo* event_info(nullptr); + top::check(evtStore()->retrieve(event_info, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); const xAOD::TruthEventContainer* truthEventContainer(nullptr); - top::check( evtStore()->retrieve(truthEventContainer, m_config->sgKeyTruthEvent()) , "Failed to retrieve truth PDF info" ); + top::check(evtStore()->retrieve(truthEventContainer, + m_config->sgKeyTruthEvent()), "PDFScaleFactorCalculator: Failed to retrieve TruthEvent container"); -// float mc_weight = event_info->mcEventWeight(); - float mc_weight = truthEventContainer->at(0)->weights()[0];// FIXME temporary bugfix + float mc_weight = event_info->auxdataConst<float>("AnalysisTop_eventWeight"); // try this... - top::check( ( truthEventContainer->size() == 1 ), "More than one truth event, not sure how to cope with PDF info" ); + top::check((truthEventContainer->size() == 1), "TruthEvent container size != 1, not sure how to cope with PDF info"); int PDFID1(0), PDFID2(0), PDGID1(0), PDGID2(0); - float X1(0), X2(0) ,Q(0), XF1(0), XF2(0); - - for (auto truthEvent : *truthEventContainer){ - - top::check( truthEvent->pdfInfoParameter( PDGID1, xAOD::TruthEvent::PdfParam::PDGID1 ), "Failed to get PDFInfo: PDGID1" ); - top::check( truthEvent->pdfInfoParameter( PDGID2, xAOD::TruthEvent::PdfParam::PDGID2 ), "Failed to get PDFInfo: PDGID2" ); - top::check( truthEvent->pdfInfoParameter( PDFID1, xAOD::TruthEvent::PdfParam::PDFID1 ), "Failed to get PDFInfo: PDFID1" ); - top::check( truthEvent->pdfInfoParameter( PDFID2, xAOD::TruthEvent::PdfParam::PDFID2 ), "Failed to get PDFInfo: PDFID2" ); - top::check( truthEvent->pdfInfoParameter( X1, xAOD::TruthEvent::PdfParam::X1 ), "Failed to get PDFInfo: X1" ); - top::check( truthEvent->pdfInfoParameter( X2, xAOD::TruthEvent::PdfParam::X2 ), "Failed to get PDFInfo: X2" ); - top::check( truthEvent->pdfInfoParameter( Q, xAOD::TruthEvent::PdfParam::Q ), "Failed to get PDFInfo: Q" ); - top::check( truthEvent->pdfInfoParameter( XF1, xAOD::TruthEvent::PdfParam::XF1 ), "Failed to get PDFInfo: XF1" ); - top::check( truthEvent->pdfInfoParameter( XF2, xAOD::TruthEvent::PdfParam::XF2 ), "Failed to get PDFInfo: XF2" ); - - // This isn't working ( nor the helper to get the PDF Info ) - //top::check( pdfInfo.valid(), "PDFInfo not valid" ); - - if( XF1*XF2==0 ) { - if( !m_base_pdf_name.empty()) { - XF1 = m_basepdf->xfxQ( PDGID1, X1, Q ); - XF2 = m_basepdf->xfxQ( PDGID2, X2, Q ); - } else { - ATH_MSG_FATAL("Not enough info to recompute PDF weights (empty XF1,XF2).\n Please try to set LHAPDFBaseSet to a valid PDF set.\n XF1=" << XF1 << " XF2=" << XF2 << " LHAPDFBaseSet=" << m_base_pdf_name); - return StatusCode::FAILURE; - } + float X1(0), X2(0), Q(0), XF1(0), XF2(0); + + const xAOD::TruthEvent* truthEvent = truthEventContainer->at(0); + top::check(truthEvent->pdfInfoParameter(PDGID1, + xAOD::TruthEvent::PdfParam::PDGID1), "Failed to get PDFInfo: PDGID1"); + top::check(truthEvent->pdfInfoParameter(PDGID2, + xAOD::TruthEvent::PdfParam::PDGID2), "Failed to get PDFInfo: PDGID2"); + top::check(truthEvent->pdfInfoParameter(PDFID1, + xAOD::TruthEvent::PdfParam::PDFID1), "Failed to get PDFInfo: PDFID1"); + top::check(truthEvent->pdfInfoParameter(PDFID2, + xAOD::TruthEvent::PdfParam::PDFID2), "Failed to get PDFInfo: PDFID2"); + top::check(truthEvent->pdfInfoParameter(X1, xAOD::TruthEvent::PdfParam::X1), "Failed to get PDFInfo: X1"); + top::check(truthEvent->pdfInfoParameter(X2, xAOD::TruthEvent::PdfParam::X2), "Failed to get PDFInfo: X2"); + top::check(truthEvent->pdfInfoParameter(Q, xAOD::TruthEvent::PdfParam::Q), "Failed to get PDFInfo: Q"); + top::check(truthEvent->pdfInfoParameter(XF1, xAOD::TruthEvent::PdfParam::XF1), "Failed to get PDFInfo: XF1"); + top::check(truthEvent->pdfInfoParameter(XF2, xAOD::TruthEvent::PdfParam::XF2), "Failed to get PDFInfo: XF2"); + + if (XF1 * XF2 == 0) { + if (!m_base_pdf_name.empty()) { + XF1 = m_basepdf->xfxQ(PDGID1, X1, Q); + XF2 = m_basepdf->xfxQ(PDGID2, X2, Q); + } else { + ATH_MSG_FATAL( + "Not enough info to recompute PDF weights (empty XF1,XF2).\n Please try to set LHAPDFBaseSet to a valid PDF set.\n XF1=" << XF1 << " XF2=" << XF2 << " LHAPDFBaseSet=" << + m_base_pdf_name); + return StatusCode::FAILURE; } + } - for( auto& pdf : m_pdf_sets ){ - - // Being cautious... - pdf.second.event_weights.clear(); - pdf.second.event_weights.resize(pdf.second.pdf_members.size()); - - int i = 0; - - for( const auto& pdf_member : pdf.second.pdf_members ){ - - float new_xf1 = pdf_member->xfxQ( PDGID1, X1, Q ); - float new_xf2 = pdf_member->xfxQ( PDGID2, X2, Q ); + for (auto& pdf : m_pdf_sets) { + // Being cautious... + pdf.second.event_weights.clear(); + pdf.second.event_weights.resize(pdf.second.pdf_members.size()); - float weight = (new_xf1*new_xf2)/(XF1*XF2); + int i = 0; - // This is the reweighting each event - pdf.second.event_weights[i] = weight; - // This is the sum of all event weights for a final scaling - pdf.second.sum_of_event_weights[i] += (weight*mc_weight); - i++; - } + for (const auto& pdf_member : pdf.second.pdf_members) { + float new_xf1 = pdf_member->xfxQ(PDGID1, X1, Q); + float new_xf2 = pdf_member->xfxQ(PDGID2, X2, Q); - // decorate each truth event with a vector of PDF weights - if( m_config->saveLHAPDFEvent() ) - truthEvent->auxdecor< std::vector< float > >( "AnalysisTop_"+pdf.first+"_Weights" ) = pdf.second.event_weights; + float weight = (new_xf1 * new_xf2) / (XF1 * XF2); + // This is the reweighting each event + pdf.second.event_weights[i] = weight; + // This is the sum of all event weights for a final scaling + pdf.second.sum_of_event_weights[i] += (weight * mc_weight); + i++; } + // decorate each truth event with a vector of PDF weights + if (m_config->saveLHAPDFEvent()) truthEvent->auxdecor< std::vector< float > >( + "AnalysisTop_" + pdf.first + "_Weights") = pdf.second.event_weights; } return StatusCode::SUCCESS; - } - StatusCode PDFScaleFactorCalculator::finalize() - { - - for( auto& pdf : m_pdf_sets ) - m_config->addLHAPDFResult( pdf.first, pdf.second.sum_of_event_weights ); + StatusCode PDFScaleFactorCalculator::finalize() { + for (auto& pdf : m_pdf_sets) + m_config->addLHAPDFResult(pdf.first, pdf.second.sum_of_event_weights); if (m_basepdf) delete m_basepdf; return StatusCode::SUCCESS; - } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PhotonScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PhotonScaleFactorCalculator.cxx index 658c5ebfc1a2..fd8355f5cb05 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PhotonScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PhotonScaleFactorCalculator.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // $Id: PhotonScaleFactorCalculator.cxx 802226 2017-04-04 16:13:10Z grancagn $ #include "TopCorrections/PhotonScaleFactorCalculator.h" @@ -13,226 +13,183 @@ #include "xAODEgamma/PhotonContainer.h" namespace top { -PhotonScaleFactorCalculator::PhotonScaleFactorCalculator(const std::string& name) : - asg::AsgTool(name), - m_config(nullptr), - m_systNominal(CP::SystematicSet()), - m_systEffIDUp("PH_EFF_ID_Uncertainty__1up"), - m_systEffIDDown("PH_EFF_ID_Uncertainty__1down"), - m_systEffLowPtIsoUp("PH_EFF_LOWPTISO_Uncertainty__1up"), - m_systEffLowPtIsoDown("PH_EFF_LOWPTISO_Uncertainty__1down"), - m_systEffTrkIsoUp("PH_EFF_TRKISO_Uncertainty__1up"), - m_systEffTrkIsoDown("PH_EFF_TRKISO_Uncertainty__1down"), - m_photonEffSF("AsgPhotonEfficiencyCorrectionTool"), - m_photonIsoSF(), - m_photonLooseIsoSF(), - m_photonIsoSF_exists(false), - m_photonLooseIsoSF_exists(false), - m_decor_isoSF("SetMe"), - m_decor_isoSF_loose("SetMe") - { - declareProperty("config" , m_config); -} + PhotonScaleFactorCalculator::PhotonScaleFactorCalculator(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), + m_systNominal(CP::SystematicSet()), + m_systEffIDUp("PH_EFF_ID_Uncertainty__1up"), + m_systEffIDDown("PH_EFF_ID_Uncertainty__1down"), + m_systEffIsoUp("PH_EFF_ISO_Uncertainty__1up"), + m_systEffIsoDown("PH_EFF_ISO_Uncertainty__1down"), + m_photonEffSF("AsgPhotonEfficiencyCorrectionTool"), + m_photonIsoSF(), + m_photonLooseIsoSF(), + m_photonIsoSF_exists(false), + m_photonLooseIsoSF_exists(false), + m_decor_isoSF("SetMe"), + m_decor_isoSF_loose("SetMe") { + declareProperty("config", m_config); + } StatusCode PhotonScaleFactorCalculator::initialize() { ATH_MSG_INFO(" top::PhotonScaleFactorCalculator initialize"); top::check(m_photonEffSF.retrieve(), "Failed to retrieve photon efficiency SF calculator"); - std::cout<<"------>Systematics:"<<std::endl; + std::ostream& msgInfo = msg(MSG::Level::INFO); + msgInfo << "------>Systematics:\n"; for (auto sys:m_photonEffSF->recommendedSystematics()) - std::cout<<"---> "<<sys<<std::endl; + msgInfo << "---> " << sys << "\n"; // remove "FixedCut" if present std::string s = "FixedCut"; std::string isoName = m_config->photonIsolation(); m_decor_isoSF = "PH_SF_Iso_" + isoName; std::string::size_type i = isoName.find(s); - if (i != std::string::npos) - isoName.erase(i, s.length()); + if (i != std::string::npos) isoName.erase(i, s.length()); std::string photonIsoSFName = "AsgPhotonEfficiencyCorrectionTool_IsoSF" + isoName; m_photonIsoSF.setName(photonIsoSFName); if (asg::ToolStore::contains<IAsgPhotonEfficiencyCorrectionTool>(photonIsoSFName)) { m_photonIsoSF_exists = true; top::check(m_photonIsoSF.retrieve(), - "Failed to retrieve photon isolation efficiency SF calculator"); - std::cout<<"------>Systematics:"<<std::endl; + "Failed to retrieve photon isolation efficiency SF calculator"); + msgInfo << "------>Systematics:\n"; for (auto sys:m_photonIsoSF->recommendedSystematics()) - std::cout<<"---> "<<sys<<std::endl; + msgInfo << "---> " << sys << "\n"; } std::string isoNameLoose = m_config->photonIsolationLoose(); - m_decor_isoSF_loose = "PH_SF_Iso_" + isoNameLoose; + m_decor_isoSF_loose = "PH_LOOSE_SF_Iso_" + isoNameLoose; i = isoNameLoose.find(s); - if (i != std::string::npos) - isoNameLoose.erase(i, s.length()); + if (i != std::string::npos) isoNameLoose.erase(i, s.length()); std::string photonLooseIsoSFName = "AsgPhotonEfficiencyCorrectionTool_IsoSF" + isoNameLoose; m_photonLooseIsoSF.setName(photonLooseIsoSFName); if (asg::ToolStore::contains<IAsgPhotonEfficiencyCorrectionTool>(photonLooseIsoSFName)) { m_photonLooseIsoSF_exists = true; top::check(m_photonLooseIsoSF.retrieve(), - "Failed to retrieve loose photon isolation efficiency SF calculator"); - //std::cout<<"------>Systematics:"<<std::endl; - //for (auto sys:m_photonIsoSF->recommendedSystematics()) - //std::cout<<"---> "<<sys<<std::endl; + "Failed to retrieve loose photon isolation efficiency SF calculator"); } return StatusCode::SUCCESS; } - -StatusCode PhotonScaleFactorCalculator::execute() { - // Loop over all photon collections - for (auto currentSystematic : *m_config->systSgKeyMapPhotons()) { - const xAOD::PhotonContainer* photons(nullptr); - top::check(evtStore()->retrieve(photons, currentSystematic.second), - "Failed to retrieve photons"); - - // Loop over all photons in each collection - for (auto photonPtr : *photons) { - // Does the photon pass object selection? - bool passSelection(false); - if (photonPtr->isAvailable<char>("passPreORSelection")) { - if (photonPtr->auxdataConst<char>("passPreORSelection") == 1) { - passSelection = true; + StatusCode PhotonScaleFactorCalculator::execute() { + // Loop over all photon collections + for (auto currentSystematic : *m_config->systSgKeyMapPhotons()) { + const xAOD::PhotonContainer* photons(nullptr); + + top::check(evtStore()->retrieve(photons, currentSystematic.second), + "Failed to retrieve photons"); + + // Loop over all photons in each collection + for (auto photonPtr : *photons) { + // Does the photon pass object selection? + bool passSelection(false); + if (photonPtr->isAvailable<char>("passPreORSelection")) { + if (photonPtr->auxdataConst<char>("passPreORSelection") == 1) { + passSelection = true; + } } - } - if (photonPtr->isAvailable<char>("passPreORSelectionLoose")) { - if (photonPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) { - passSelection = true; + if (photonPtr->isAvailable<char>("passPreORSelectionLoose")) { + if (photonPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) { + passSelection = true; + } } - } - if (!passSelection) continue; + if (!passSelection) continue; - top::check(m_photonEffSF->applySystematicVariation(m_systNominal), - "Failed to set photon efficiency SF tool to nominal"); + top::check(m_photonEffSF->applySystematicVariation(m_systNominal), + "Failed to set photon efficiency SF tool to nominal"); - double effSF(1.); - top::check(m_photonEffSF->getEfficiencyScaleFactor(*photonPtr, effSF), + double effSF(1.); + top::check(m_photonEffSF->getEfficiencyScaleFactor(*photonPtr, effSF), "Failed to get nominal photon SF"); - static SG::AuxElement::Decorator<float> ph_effID_dec("EFF_ID_SF"); - ph_effID_dec(*photonPtr) = effSF; + static SG::AuxElement::Decorator<float> ph_effID_dec("EFF_ID_SF"); + ph_effID_dec(*photonPtr) = effSF; + + double isoSF(1.), isoLooseSF(1.); + if (m_photonIsoSF_exists) { + top::check(m_photonIsoSF->applySystematicVariation(m_systNominal), + "Failed to set photon efficiency SF tool to nominal"); + top::check(m_photonIsoSF->getEfficiencyScaleFactor(*photonPtr, isoSF), + "Failed to get nominal photon SF"); + static SG::AuxElement::Decorator<float> ph_isoID_dec(m_decor_isoSF); + ph_isoID_dec(*photonPtr) = isoSF; + } + if (m_photonLooseIsoSF_exists) { + top::check(m_photonLooseIsoSF->applySystematicVariation(m_systNominal), + "Failed to set photon efficiency SF tool to nominal"); + top::check(m_photonLooseIsoSF->getEfficiencyScaleFactor(*photonPtr, isoLooseSF), + "Failed to get nominal photon SF"); + static SG::AuxElement::Decorator<float> ph_isoID_dec(m_decor_isoSF_loose); + ph_isoID_dec(*photonPtr) = isoLooseSF; + } - double isoSF(1.), isoLooseSF(1.); - if (m_photonIsoSF_exists) { - top::check(m_photonIsoSF->applySystematicVariation(m_systNominal), - "Failed to set photon efficiency SF tool to nominal"); - top::check(m_photonIsoSF->getEfficiencyScaleFactor(*photonPtr, isoSF), - "Failed to get nominal photon SF"); - static SG::AuxElement::Decorator<float> ph_isoID_dec(m_decor_isoSF); - ph_isoID_dec(*photonPtr) = isoSF; - } - if (m_photonLooseIsoSF_exists) { - top::check(m_photonLooseIsoSF->applySystematicVariation(m_systNominal), - "Failed to set photon efficiency SF tool to nominal"); - top::check(m_photonLooseIsoSF->getEfficiencyScaleFactor(*photonPtr, isoLooseSF), - "Failed to get nominal photon SF"); - static SG::AuxElement::Decorator<float> ph_isoID_dec(m_decor_isoSF_loose); - ph_isoID_dec(*photonPtr) = isoLooseSF; - } + // For nominal calibration, vary the SF systematics + if (currentSystematic.first != m_config->nominalHashValue()) continue; + + double effSF_up(1.), effSF_down(1.); + top::check(m_photonEffSF->applySystematicVariation(m_systEffIDUp), + "Failed to set photon efficiency SF tool to" + " ID up systematic"); + top::check(m_photonEffSF->getEfficiencyScaleFactor(*photonPtr, effSF_up), + "Failed to get photon efficiency SF:" + " systematic up ID SF"); + + top::check(m_photonEffSF->applySystematicVariation(m_systEffIDDown), + "Failed to set photon efficiency SF tool to" + " ID up systematic"); + top::check(m_photonEffSF->getEfficiencyScaleFactor(*photonPtr, effSF_down), + "Failed to get photon efficiency SF:" + " systematic down ID SF"); + + static SG::AuxElement::Decorator<float> ph_effIDUp_dec("EFF_ID_SF_UP"); + static SG::AuxElement::Decorator<float> ph_effIDDown_dec("EFF_ID_SF_DOWN"); + ph_effIDUp_dec(*photonPtr) = effSF_up; + ph_effIDDown_dec(*photonPtr) = effSF_down; + + // isolation systematic uncertainties + double effIsoSF_up(1.), effIsoSF_down(1.); + double effLooseIsoSF_up(1.), effLooseIsoSF_down(1.); + if (m_photonIsoSF_exists) { + top::check(m_photonIsoSF->applySystematicVariation(m_systEffIsoUp), + "Failed to set photon efficiency SF tool to" + " isolation up systematic"); + top::check(m_photonIsoSF->getEfficiencyScaleFactor(*photonPtr, effIsoSF_up), + "Failed to get photon efficiency SF:" + " up systematic isolation"); + top::check(m_photonIsoSF->applySystematicVariation(m_systEffIsoDown), + "Failed to set photon efficiency SF tool to" + " isolation down systematic"); + top::check(m_photonIsoSF->getEfficiencyScaleFactor(*photonPtr, effIsoSF_down), + "Failed to get photon efficiency SF:" + " down systematic isolation"); + } + if (m_photonLooseIsoSF_exists) { + top::check(m_photonLooseIsoSF->applySystematicVariation(m_systEffIsoUp), + "Failed to set photon efficiency SF tool to" + " isolation up systematic"); + top::check(m_photonLooseIsoSF->getEfficiencyScaleFactor(*photonPtr, effLooseIsoSF_up), + "Failed to get photon efficiency SF:" + " up systematic isolation"); + top::check(m_photonLooseIsoSF->applySystematicVariation(m_systEffIsoDown), + "Failed to set photon efficiency SF tool to" + " isolation down systematic"); + top::check(m_photonLooseIsoSF->getEfficiencyScaleFactor(*photonPtr, effLooseIsoSF_down), + "Failed to get photon efficiency SF:" + " down systematic isolation"); + } - // For nominal calibration, vary the SF systematics - if (currentSystematic.first != m_config->nominalHashValue()) - continue; - - double effSF_up(1.), effSF_down(1.); - top::check(m_photonEffSF->applySystematicVariation(m_systEffIDUp), - "Failed to set photon efficiency SF tool to" - " ID up systematic"); - top::check(m_photonEffSF->getEfficiencyScaleFactor(*photonPtr, effSF_up), - "Failed to get photon efficiency SF:" - " systematic up ID SF"); - - top::check(m_photonEffSF->applySystematicVariation(m_systEffIDDown), - "Failed to set photon efficiency SF tool to" - " ID up systematic"); - top::check(m_photonEffSF->getEfficiencyScaleFactor(*photonPtr, effSF_down), - "Failed to get photon efficiency SF:" - " systematic down ID SF"); - - static SG::AuxElement::Decorator<float> ph_effIDUp_dec("EFF_ID_SF_UP"); - static SG::AuxElement::Decorator<float> ph_effIDDown_dec("EFF_ID_SF_DOWN"); - ph_effIDUp_dec(*photonPtr) = effSF_up; - ph_effIDDown_dec(*photonPtr) = effSF_down; - - // isolation systematic uncertainties - double effLowPtIsoSF_up(1.), effTrkIsoSF_up(1.); - double effLowPtIsoSF_down(1.), effTrkIsoSF_down(1.); - double effLowPtLooseIsoSF_up(1.), effTrkLooseIsoSF_up(1.); - double effLowPtLooseIsoSF_down(1.), effTrkLooseIsoSF_down(1.); - if (m_photonIsoSF_exists) { - top::check(m_photonIsoSF->applySystematicVariation(m_systEffLowPtIsoUp), - "Failed to set photon efficiency SF tool to" - " Radiative Z (low ET) up systematic "); - top::check(m_photonIsoSF->getEfficiencyScaleFactor(*photonPtr, effLowPtIsoSF_up), - "Failed to get photon efficiency SF:" - " up systematic Radiative Z (low ET)"); - top::check(m_photonIsoSF->applySystematicVariation(m_systEffLowPtIsoDown), - "Failed to set photon efficiency SF tool to" - " Radiative Z (low ET) down systematic"); - top::check(m_photonIsoSF->getEfficiencyScaleFactor(*photonPtr, effLowPtIsoSF_down), - "Failed to get photon efficiency SF:" - " down systematic Radiative Z (low ET)"); - - top::check(m_photonIsoSF->applySystematicVariation(m_systEffTrkIsoUp), - "Failed to set photon efficiency SF tool to" - " Track isolation (ptcone, intermediate and high ET) up systematic"); - top::check(m_photonIsoSF->getEfficiencyScaleFactor(*photonPtr, effTrkIsoSF_up), - "Failed to get photon efficiency SF:" - " up systematic Track isolation (ptcone, intermediate and high ET)"); - top::check(m_photonIsoSF->applySystematicVariation(m_systEffTrkIsoDown), - "Failed to set photon efficiency SF tool to" - " Track isolation (ptcone, intermediate and high ET) down systematic"); - top::check(m_photonIsoSF->getEfficiencyScaleFactor(*photonPtr, effTrkIsoSF_down), - "Failed to get photon efficiency SF:" - " down systematic Track isolation (ptcone, intermediate and high ET)"); - } - if (m_photonLooseIsoSF_exists) { - top::check(m_photonLooseIsoSF->applySystematicVariation(m_systEffLowPtIsoUp), - "Failed to set photon efficiency SF tool to" - " Radiative Z (low ET) up systematic "); - top::check(m_photonLooseIsoSF->getEfficiencyScaleFactor(*photonPtr, effLowPtLooseIsoSF_up), - "Failed to get photon efficiency SF:" - " up systematic Radiative Z (low ET)"); - top::check(m_photonLooseIsoSF->applySystematicVariation(m_systEffLowPtIsoDown), - "Failed to set photon efficiency SF tool to" - " Radiative Z (low ET) down systematic"); - top::check(m_photonLooseIsoSF->getEfficiencyScaleFactor(*photonPtr, effLowPtLooseIsoSF_down), - "Failed to get photon efficiency SF:" - " down systematic Radiative Z (low ET)"); - - top::check(m_photonLooseIsoSF->applySystematicVariation(m_systEffTrkIsoUp), - "Failed to set photon efficiency SF tool to" - " Track isolation (ptcone, intermediate and high ET) up systematic"); - top::check(m_photonLooseIsoSF->getEfficiencyScaleFactor(*photonPtr, effTrkLooseIsoSF_up), - "Failed to get photon efficiency SF:" - " up systematic Track isolation (ptcone, intermediate and high ET)"); - top::check(m_photonLooseIsoSF->applySystematicVariation(m_systEffTrkIsoDown), - "Failed to set photon efficiency SF tool to" - " Track isolation (ptcone, intermediate and high ET) down systematic"); - top::check(m_photonLooseIsoSF->getEfficiencyScaleFactor(*photonPtr, effTrkLooseIsoSF_down), - "Failed to get photon efficiency SF:" - " down systematic Track isolation (ptcone, intermediate and high ET)"); - } + static SG::AuxElement::Decorator<float> ph_effIsoUp_dec(m_decor_isoSF + "_UP"); + static SG::AuxElement::Decorator<float> ph_effIsoDown_dec(m_decor_isoSF + "_DOWN"); + static SG::AuxElement::Decorator<float> ph_effLooseIsoUp_dec(m_decor_isoSF_loose + "_UP"); + static SG::AuxElement::Decorator<float> ph_effLooseIsoDown_dec(m_decor_isoSF_loose + "_DOWN"); - static SG::AuxElement::Decorator<float> ph_effLowPtIsoUp_dec(m_decor_isoSF+"_LOWPT_UP"); - static SG::AuxElement::Decorator<float> ph_effLowPtIsoDown_dec(m_decor_isoSF+"_LOWPT_DOWN"); - static SG::AuxElement::Decorator<float> ph_effTrkIsoUp_dec(m_decor_isoSF+"_TRK_UP"); - static SG::AuxElement::Decorator<float> ph_effTrkIsoDown_dec(m_decor_isoSF+"_TRK_DOWN"); - static SG::AuxElement::Decorator<float> ph_effLowPtLooseIsoUp_dec(m_decor_isoSF_loose+"_LOWPT_UP"); - static SG::AuxElement::Decorator<float> ph_effLowPtLooseIsoDown_dec(m_decor_isoSF_loose+"_LOWPT_DOWN"); - static SG::AuxElement::Decorator<float> ph_effTrkLooseIsoUp_dec(m_decor_isoSF_loose+"_TRK_UP"); - static SG::AuxElement::Decorator<float> ph_effTrkLooseIsoDown_dec(m_decor_isoSF_loose+"_TRK_DOWN"); - ph_effLowPtIsoUp_dec(*photonPtr) = effLowPtIsoSF_up; - ph_effLowPtIsoDown_dec(*photonPtr) = effLowPtIsoSF_down; - ph_effTrkIsoUp_dec(*photonPtr) = effTrkIsoSF_up; - ph_effTrkIsoDown_dec(*photonPtr) = effTrkIsoSF_down; - ph_effLowPtLooseIsoUp_dec(*photonPtr) = effLowPtLooseIsoSF_up; - ph_effLowPtLooseIsoDown_dec(*photonPtr) = effLowPtLooseIsoSF_down; - ph_effTrkLooseIsoUp_dec(*photonPtr) = effTrkLooseIsoSF_up; - ph_effTrkLooseIsoDown_dec(*photonPtr) = effTrkLooseIsoSF_down; + ph_effIsoUp_dec(*photonPtr) = effIsoSF_up; + ph_effIsoDown_dec(*photonPtr) = effIsoSF_down; + ph_effLooseIsoUp_dec(*photonPtr) = effLooseIsoSF_up; + ph_effLooseIsoDown_dec(*photonPtr) = effLooseIsoSF_down; + } } + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PileupScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PileupScaleFactorCalculator.cxx index 918b6e72ce6c..82bf77123b1f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PileupScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/PileupScaleFactorCalculator.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ #include "TopCorrections/PileupScaleFactorCalculator.h" #include "TopConfiguration/TopConfig.h" @@ -8,91 +8,107 @@ #include "xAODEventInfo/EventInfo.h" -namespace top{ - - PileupScaleFactorCalculator::PileupScaleFactorCalculator( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + PileupScaleFactorCalculator::PileupScaleFactorCalculator(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), m_pileupReweightingTool("CP::PileupReweightingTool"), - m_systNominal( CP::SystematicSet() ), - m_systDataSFUp( CP::SystematicSet() ), - m_systDataSFDown( CP::SystematicSet() ) - { - declareProperty( "config" , m_config ); + m_systNominal(CP::SystematicSet()), + m_systDataSFUp(CP::SystematicSet()), + m_systDataSFDown(CP::SystematicSet()) { + declareProperty("config", m_config); } - StatusCode PileupScaleFactorCalculator::initialize() - { - ATH_MSG_INFO(" top::PileupScaleFactorCalculator initialize" ); + StatusCode PileupScaleFactorCalculator::initialize() { + ATH_MSG_INFO(" top::PileupScaleFactorCalculator initialize"); - top::check( m_pileupReweightingTool.retrieve(), "Failed to retireve pileup reweighting tool" ); + top::check(m_pileupReweightingTool.retrieve(), "Failed to retireve pileup reweighting tool"); - m_systDataSFUp.insert( CP::SystematicVariation("PRW_DATASF", 1) ); - m_systDataSFDown.insert( CP::SystematicVariation("PRW_DATASF", -1) ); + m_systDataSFUp.insert(CP::SystematicVariation("PRW_DATASF", 1)); + m_systDataSFDown.insert(CP::SystematicVariation("PRW_DATASF", -1)); m_mu_dependent_PRW = m_config->PileupMuDependent(); return StatusCode::SUCCESS; } - - StatusCode PileupScaleFactorCalculator::execute() - { - + StatusCode PileupScaleFactorCalculator::execute() { // get the event info const xAOD::EventInfo* eventInfo(nullptr); + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), - "Failed to retrieve EventInfo"); + "Failed to retrieve EventInfo"); - top::check( m_pileupReweightingTool->applySystematicVariation( m_systNominal ), - "Failed to set pileup reweighting to nominal value" ); + top::check(m_pileupReweightingTool->applySystematicVariation(m_systNominal), + "Failed to set pileup reweighting to nominal value"); top::check(m_pileupReweightingTool->apply(*eventInfo, m_mu_dependent_PRW), - "Failed to apply pileup weight"); + "Failed to apply pileup weight"); + + // Apply correction to actual mu for data + if (!m_config->isMC()) { + float actualMu = m_pileupReweightingTool->getCorrectedActualInteractionsPerCrossing(*eventInfo); + eventInfo->auxdecor<float>("corrected_actualInteractionsPerCrossing") = actualMu; + } // Get hash value which can be used later for reweighting if (m_config->isMC()) { unsigned long long prw_hash = m_pileupReweightingTool->getPRWHash(*eventInfo); eventInfo->auxdecor<unsigned long long>("PileupWeight_Hash") = prw_hash; } - + // Now get the up and down pileup variations // We want the SF for MC and the mu value for data // Switch tool to DataSFUp - top::check( m_pileupReweightingTool->applySystematicVariation( m_systDataSFUp ), - "Failed to switch pileup reweighting tool to data SF up" ); - - if( m_config->isMC() ){ + top::check(m_pileupReweightingTool->applySystematicVariation(m_systDataSFUp), + "Failed to switch pileup reweighting tool to data SF up"); + + if (m_config->isMC()) { // The apply method above has pileupWeight as // a double (although the function returns a float) // so here we do the same for consistency - float pileupWeight = m_pileupReweightingTool->getCombinedWeight( *eventInfo ); + float pileupWeight = m_pileupReweightingTool->getCombinedWeight(*eventInfo); eventInfo->auxdecor<float>("PileupWeight_UP") = pileupWeight; - } - else { - float lumiBlockMu = m_pileupReweightingTool->getCorrectedMu( *eventInfo ); + } else { + float lumiBlockMu { + 1 + }; + if (m_config->isAFII() && m_config->PileupActualMu_AF().size() > 0) { + lumiBlockMu = m_pileupReweightingTool->getCorrectedActualInteractionsPerCrossing(*eventInfo); + } else if (!m_config->isAFII() && m_config->PileupActualMu_FS().size() > 0) { + lumiBlockMu = m_pileupReweightingTool->getCorrectedActualInteractionsPerCrossing(*eventInfo); + } else { + lumiBlockMu = m_pileupReweightingTool->getCorrectedAverageInteractionsPerCrossing(*eventInfo); + } eventInfo->auxdecor<float>("corrected_averageInteractionsPerCrossing_UP") = lumiBlockMu; } - + // Switch tool to DataSFDown - top::check( m_pileupReweightingTool->applySystematicVariation( m_systDataSFDown ), - "Failed to switch pileup reweighting tool to data SF down" ); + top::check(m_pileupReweightingTool->applySystematicVariation(m_systDataSFDown), + "Failed to switch pileup reweighting tool to data SF down"); - if( m_config->isMC() ){ - float pileupWeight = m_pileupReweightingTool->getCombinedWeight( *eventInfo ); + if (m_config->isMC()) { + float pileupWeight = m_pileupReweightingTool->getCombinedWeight(*eventInfo); eventInfo->auxdecor<float>("PileupWeight_DOWN") = pileupWeight; - } - else { - float lumiBlockMu = m_pileupReweightingTool->getCorrectedMu( *eventInfo ); + } else { + float lumiBlockMu { + 1 + }; + if (m_config->isAFII() && m_config->PileupActualMu_AF().size() > 0) { + lumiBlockMu = m_pileupReweightingTool->getCorrectedActualInteractionsPerCrossing(*eventInfo); + } else if (!m_config->isAFII() && m_config->PileupActualMu_FS().size() > 0) { + lumiBlockMu = m_pileupReweightingTool->getCorrectedActualInteractionsPerCrossing(*eventInfo); + } else { + lumiBlockMu = m_pileupReweightingTool->getCorrectedAverageInteractionsPerCrossing(*eventInfo); + } eventInfo->auxdecor<float>("corrected_averageInteractionsPerCrossing_DOWN") = lumiBlockMu; } - + // Switch tool to back to nominal to be extra careful... - top::check( m_pileupReweightingTool->applySystematicVariation( m_systNominal ), - "Failed to switch pileup reweighting tool back to nominal" ); + top::check(m_pileupReweightingTool->applySystematicVariation(m_systNominal), + "Failed to switch pileup reweighting tool back to nominal"); return StatusCode::SUCCESS; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ScaleFactorCalculator.cxx index 733581f8f832..315b8013e317 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ScaleFactorCalculator.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopCorrections/ScaleFactorCalculator.h" @@ -10,146 +10,273 @@ #include "TopEvent/EventTools.h" #include "xAODEventInfo/EventInfo.h" -#include "xAODTruth/TruthEventContainer.h" + +#include <sstream> namespace top { + ScaleFactorCalculator::ScaleFactorCalculator(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), -ScaleFactorCalculator::ScaleFactorCalculator(const std::string& name) : - asg::AsgTool(name), - m_config(nullptr), - - m_photonSF(nullptr), - m_electronSF(nullptr), - m_muonSF(nullptr), - m_tauSF(nullptr), - m_jetSF(nullptr), - m_btagSF(nullptr), - m_pileupSF(nullptr), - m_sherpa_22_reweight_tool("PMGSherpa22VJetsWeightTool") { - declareProperty("config", m_config); -} - -StatusCode ScaleFactorCalculator::initialize() { - ATH_MSG_INFO(" top::ScaleFactorCalculator initialize"); - - m_photonSF = std::make_unique<top::PhotonScaleFactorCalculator>("top::PhotonScaleFactorCalculator"); - m_electronSF = std::make_unique<top::ElectronScaleFactorCalculator>("top::ElectronScaleFactorCalculator"); - m_muonSF = std::make_unique<top::MuonScaleFactorCalculator>("top::MuonScaleFactorCalculator"); - m_tauSF = std::make_unique<top::TauScaleFactorCalculator>("top::TauScaleFactorCalculator"); - m_jetSF = std::make_unique<top::JetScaleFactorCalculator>("top::JetScaleFactorCalculator"); - m_btagSF = std::make_unique<top::BTagScaleFactorCalculator>("top::BTagScaleFactorCalculator"); - m_pileupSF = std::make_unique<top::PileupScaleFactorCalculator>("top::PileupScaleFactorCalculator"); - - if (m_config->isMC()) { - if (m_config->usePhotons()) { - top::check(m_photonSF->setProperty("config", m_config), "Failed to setProperty"); - top::check(m_photonSF->initialize(), "Failed to initialize"); - } + m_photonSF(nullptr), + m_electronSF(nullptr), + m_fwdElectronSF(nullptr), + m_muonSF(nullptr), + m_tauSF(nullptr), + m_jetSF(nullptr), + m_btagSF(nullptr), + m_pileupSF(nullptr), + m_sherpa_22_reweight_tool("PMGSherpa22VJetsWeightTool"), + m_globalLeptonTriggerSF(nullptr), + m_pmg_truth_weight_tool("PMGTruthWeightTool"), + m_sample_multiple_MCweights(false), + m_nominal_weight_name("") { + declareProperty("config", m_config); + } - if (m_config->useElectrons()) { - top::check(m_electronSF->setProperty("config", m_config), "Failed to setProperty"); - // m_electronSF->msg().setLevel(MSG::DEBUG); - top::check(m_electronSF->initialize(), "Failed to initialize"); - } + StatusCode ScaleFactorCalculator::initialize() { + ATH_MSG_INFO(" top::ScaleFactorCalculator initialize"); - if (m_config->useMuons() && !m_config->isTruthDxAOD()) { - top::check(m_muonSF->setProperty("config", m_config), "Failed to setProperty"); - // m_muonSF->msg().setLevel(MSG::DEBUG); - top::check(m_muonSF->initialize(), "Failed to initialize"); - } + m_photonSF = std::make_unique<top::PhotonScaleFactorCalculator>("top::PhotonScaleFactorCalculator"); + m_electronSF = std::make_unique<top::ElectronScaleFactorCalculator>("top::ElectronScaleFactorCalculator"); + m_fwdElectronSF = std::make_unique<top::FwdElectronScaleFactorCalculator>("top::FwdElectronScaleFactorCalculator"); + m_muonSF = std::make_unique<top::MuonScaleFactorCalculator>("top::MuonScaleFactorCalculator"); + m_tauSF = std::make_unique<top::TauScaleFactorCalculator>("top::TauScaleFactorCalculator"); + m_jetSF = std::make_unique<top::JetScaleFactorCalculator>("top::JetScaleFactorCalculator"); + m_btagSF = std::make_unique<top::BTagScaleFactorCalculator>("top::BTagScaleFactorCalculator"); + m_pileupSF = std::make_unique<top::PileupScaleFactorCalculator>("top::PileupScaleFactorCalculator"); + m_globalLeptonTriggerSF = + std::make_unique<top::GlobalLeptonTriggerCalculator>("top::GlobalLeptonTriggerCalculator"); - if (m_config->useTaus()) { - top::check(m_tauSF->setProperty("config", m_config), "Failed to setProperty"); - top::check(m_tauSF->initialize(), "Failed to initialize"); - } + if (m_config->isMC()) { + if (m_config->usePhotons()) { + top::check(m_photonSF->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_photonSF->initialize(), "Failed to initialize"); + } + + if (m_config->useElectrons()) { + top::check(m_electronSF->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_electronSF->initialize(), "Failed to initialize"); + } + + if (m_config->useFwdElectrons()) { + top::check(m_fwdElectronSF->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_fwdElectronSF->initialize(), "Failed to initialize"); + } - if (m_config->useJets()) { - top::check(m_jetSF->setProperty("config", m_config), "Failed to setProperty"); - top::check(m_jetSF->initialize(), "Failed to initialize"); + if (m_config->useMuons() && !m_config->isTruthDxAOD()) { + top::check(m_muonSF->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_muonSF->initialize(), "Failed to initialize"); + } - top::check(m_btagSF->setProperty("config", m_config), "Failed to setProperty"); - top::check(m_btagSF->initialize(), "Failed to initialize"); + if (m_config->useTaus()) { + top::check(m_tauSF->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_tauSF->initialize(), "Failed to initialize"); + } + + if (m_config->useJets()) { + top::check(m_jetSF->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_jetSF->initialize(), "Failed to initialize"); + + top::check(m_btagSF->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_btagSF->initialize(), "Failed to initialize"); + } + + if (m_config->isSherpa22Vjets()) top::check(m_sherpa_22_reweight_tool.retrieve(), + "Failed to retrieve PMGSherpa22VJetsWeightTool"); + + if ((m_config->useElectrons() || m_config->useMuons()) && m_config->useGlobalTrigger()) { + top::check(m_globalLeptonTriggerSF->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_globalLeptonTriggerSF->initialize(), "Failed to initalize"); + } + + top::check(initialize_nominal_MC_weight(), "Failed to initialize nominal MC weight in SF calculator"); } - if (m_config->isSherpa22Vjets()) - top::check(m_sherpa_22_reweight_tool.retrieve(), - "Failed to retrieve PMGSherpa22VJetsWeightTool"); - } + if (m_config->doPileupReweighting()) { + top::check(m_pileupSF->setProperty("config", m_config), "Failed to add config to pileup SF calculator"); + top::check(m_pileupSF->initialize(), "Failed to initialize pileup SF calculator"); + } - if (m_config->doPileupReweighting()) { - top::check(m_pileupSF->setProperty("config", m_config), "Failed to add config to pileup SF calculator"); - top::check(m_pileupSF->initialize(), "Failed to initialize pileup SF calculator"); + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} - -StatusCode ScaleFactorCalculator::execute() { - if (m_config->isMC()) { - if (m_config->usePhotons()) - top::check(m_photonSF->execute(), "Failed to execute photon SF"); - if (m_config->useElectrons()) - top::check(m_electronSF->execute(), "Failed to execute electron SF"); - if (m_config->useMuons() && !m_config->isTruthDxAOD()) - top::check(m_muonSF->execute(), "Failed to execute muon SF"); - if (m_config->useTaus()) - top::check(m_tauSF->execute(), "Failed to execute tau SF"); - if (m_config->useJets()) - top::check(m_jetSF->execute(), "Failed to execute jet SF"); - if (m_config->useJets()) { - top::check(m_btagSF->execute(), "Failed to execute btag SF"); + StatusCode ScaleFactorCalculator::initialize_nominal_MC_weight() { + // check if user force-requested to use plain MC weights vector index + // in that case ignore all the additional checks if metadata broken + // as well as the method to determine nominal weight by name + if (m_config->forceNominalWeightFallbackIndex()) { + ATH_MSG_WARNING("ForceNominalWeightFallbackIndex option was set to true." + << "\nWill use weight with index: " << m_config->nominalWeightIndex() + << " instead of determining it from metadata!"); + return StatusCode::SUCCESS; + } + ///-- Start using the PMG tool to get the nominal event weights --/// + // in case PMGTruthWeightTool init fails, e.g. due to broken metadata + if (!m_pmg_truth_weight_tool.retrieve()) { + // we don't know how many MC weights there are and user didn't specify nominal index + if (m_config->MCweightsVectorSize() == size_t(-1) + && m_config->nominalWeightIndex() == size_t(-1)) { + ATH_MSG_ERROR("\nPMGTruthWeightTool instance could not be retrieved." + << "We could not determine the number of MC generator weights in this sample.\n" + << "We cannot determine the nominal MC weight. Please specify the index of " + << "nominal MC weight via config option NominalWeightFallbackIndex."); + return StatusCode::FAILURE; + } + // we know there are multiple MC weights and user didn't specify nominal index + if (m_config->MCweightsVectorSize() > 1 + && m_config->nominalWeightIndex() == size_t(-1)) { + ATH_MSG_ERROR("\nPMGTruthWeightTool instance could not be retrieved." + << "We detect multiple MC generator weights in the sample.\n " + << "We cannot determine which one is nominal. Please specify the index of " + << "nominal MC weight via config option NominalWeightFallbackIndex."); + return StatusCode::FAILURE; + } + // only one MC weight in the sample, this is sovable unambiguously + if (m_config->MCweightsVectorSize() == 1) { + m_config->setNominalWeightIndex(0); + ATH_MSG_WARNING("PMGTruthWeightTool instance could not be retrieved." + << "This sample has only one MC weight, will use that one."); + return StatusCode::SUCCESS; + } + // possibly multiple weights, but the user already gave us fallback option + ATH_MSG_WARNING("PMGTruthWeightTool instance could not be retrieved." + << "Falling back to specified NominalWeightFallbackIndex " + << m_config->nominalWeightIndex()); + return StatusCode::SUCCESS; } - // Add Sherpa 22 weights directly here, if we get more - // PMG tools for reweighting then we should consider making - // a m_PMG_SF class, as with other corrections - if (m_config->isSherpa22Vjets()) { - const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), - "Failed to retrieve EventInfo"); - double sherpa_weight = m_sherpa_22_reweight_tool->getWeight(); - eventInfo->auxdecor<double>("Sherpa22VJetsWeight") = sherpa_weight; + // PMGTruthWeightTool was initialized succesfully, let's see if we have weights + const std::vector<std::string>& pmg_weight_names = m_pmg_truth_weight_tool->getWeightNames(); + m_sample_multiple_MCweights = (pmg_weight_names.size() > 1); + if (!m_sample_multiple_MCweights) { + ATH_MSG_WARNING("PMGTruthWeightTool did not find multiple MC generator weights in metadata for this sample." + << "\nThis most likely means that the sample has only one weight." + << "\nCheck the top-xaod output for PMGTruthWeightTool-related errors just to be sure."); + if (m_config->nominalWeightIndex() != size_t(-1)) { + ATH_MSG_WARNING("Using MC weight index " << m_config->nominalWeightIndex() + << " as specified in config."); + } else { + ATH_MSG_WARNING("Will use 0th weight index. " + << "If you want a different weight, specify it via config option NominalWeightFallbackIndex"); + m_config->setNominalWeightIndex(0); + } + return StatusCode::SUCCESS; } + // here we try to find the first weight name from the NominalWeightNames config option, that matches any MC weight in the sample + const std::vector<std::string> &nominal_weight_names = m_config->nominalWeightNames(); + bool found_match = false; + std::vector<std::string> multiple_matches; + for (const std::string& weight_name : nominal_weight_names) { + // Check whether this weight name does exist + if (m_pmg_truth_weight_tool->hasWeight(weight_name)) { + // pick only the first match, but check if there are multiple matches -- that is a problem + if (!found_match) + m_nominal_weight_name = weight_name; + found_match = true; + multiple_matches.push_back(weight_name); + } + } + // we have to find the index, because PMGTruthWeightTool has no method to give us the index + auto weight_index = std::find(pmg_weight_names.begin(), pmg_weight_names.end(), m_nominal_weight_name); + m_config->setNominalWeightName(m_nominal_weight_name); + m_config->setNominalWeightIndex(weight_index - pmg_weight_names.begin()); + if (multiple_matches.size() > 1) { + std::stringstream s_multiple_matches; + for (const std::string &wname : multiple_matches) + s_multiple_matches << "\"" << wname << "\"\n"; + ATH_MSG_WARNING("Multiple NominalWeightNames match for this MC sample!\n" + s_multiple_matches.str() + + "\nThe one we will use is \"" + m_nominal_weight_name + "\". Check whether this is really correct!"); + } + if (!found_match) { + // if we get here, it means we are missing the correct name of the nominal weight + // user has to find it in the sample meta-data and add it to AT config file + ATH_MSG_ERROR("No MC weight matches any of the names specified by NominalWeightNames " + "option\nThis may indicate a sample with non-standard nominal MC weight name!"); + std::stringstream weights_log; + for (size_t w_indx=0; w_indx < pmg_weight_names.size(); ++w_indx) { + weights_log << "Weight " << w_indx << ": \"" << pmg_weight_names.at(w_indx) << "\"\n"; + } + ATH_MSG_ERROR("The following weight names are available based on sample metadata:\n" + weights_log.str() + + "\nAdd the correct nominal weight name from this list into the NominalWeightNames option in your config file."); + return StatusCode::FAILURE; + } + + ATH_MSG_INFO("Using the following MC weight as nominal: \"" + m_config->nominalWeightName() + << "\", index: " << m_config->nominalWeightIndex()); + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} - -StatusCode ScaleFactorCalculator::executePileup() { - if (m_config->doPileupReweighting()) - top::check(m_pileupSF->execute(), "Failed to execute pileup SF"); - return StatusCode::SUCCESS; -} - -float ScaleFactorCalculator::pileupWeight() const { - float sf(1.); - if (!m_config->isMC()) { - return sf; + + StatusCode ScaleFactorCalculator::execute() { + if (m_config->isMC()) { + if (m_config->usePhotons()) top::check(m_photonSF->execute(), "Failed to execute photon SF"); + if (m_config->useElectrons()) top::check(m_electronSF->execute(), "Failed to execute electron SF"); + if (m_config->useFwdElectrons()) top::check(m_fwdElectronSF->execute(), "Failed to execute fwd electron SF"); + if (m_config->useMuons() && + !m_config->isTruthDxAOD()) top::check(m_muonSF->execute(), "Failed to execute muon SF"); + if (m_config->useTaus()) top::check(m_tauSF->execute(), "Failed to execute tau SF"); + if (m_config->useJets()) top::check(m_jetSF->execute(), "Failed to execute jet SF"); + if (m_config->useJets()) { + top::check(m_btagSF->execute(), "Failed to execute btag SF"); + } + // Add Sherpa 22 weights directly here, if we get more + // PMG tools for reweighting then we should consider making + // a m_PMG_SF class, as with other corrections + if (m_config->isSherpa22Vjets()) { + const xAOD::EventInfo* eventInfo(nullptr); + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); + double sherpa_weight = m_sherpa_22_reweight_tool->getWeight(); + eventInfo->auxdecor<double>("Sherpa22VJetsWeight") = sherpa_weight; + } + if ((m_config->useElectrons() || m_config->useMuons()) && m_config->useGlobalTrigger()) { + top::check(m_globalLeptonTriggerSF->execute(), "Failed to exectute global trigger SF"); + } + } + return StatusCode::SUCCESS; + } + + StatusCode ScaleFactorCalculator::executePileup() { + if (m_config->doPileupReweighting()) top::check(m_pileupSF->execute(), "Failed to execute pileup SF"); + return StatusCode::SUCCESS; } - const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), - "Failed to retrieve EventInfo"); + float ScaleFactorCalculator::pileupWeight() const { + float sf(1.); + + if (!m_config->isMC()) { + return sf; + } - if (eventInfo->isAvailable<float>("PileupWeight")) - sf = eventInfo->auxdataConst<float>("PileupWeight"); + const xAOD::EventInfo* eventInfo(nullptr); + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), + "Failed to retrieve EventInfo"); - return sf; -} + if (eventInfo->isAvailable<float>("PileupWeight")) sf = eventInfo->auxdataConst<float>("PileupWeight"); -float ScaleFactorCalculator::mcEventWeight() const { - float sf(1.); - if (!m_config->isMC()) { return sf; } - const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), - "Failed to retrieve EventInfo"); - const xAOD::TruthEventContainer* truthEventContainer(nullptr); - top::check( evtStore()->retrieve(truthEventContainer, m_config->sgKeyTruthEvent()) , "Failed to retrieve truth PDF info" ); + float ScaleFactorCalculator::mcEventWeight() const { + float sf(1.); + + if (!m_config->isMC()) { + return sf; + } + // Decorate the updated nominal weight if appropriate - note this is called early in top-xaod + const xAOD::EventInfo* eventInfo(nullptr); + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); -// sf = eventInfo->mcEventWeight(); - sf = truthEventContainer->at(0)->weights()[0];// FIXME temporary bugfix + // Check if the decoration is already present, and return it if so + if (eventInfo->isAvailable<float>("AnalysisTop_eventWeight")) return eventInfo->auxdataConst<float>( + "AnalysisTop_eventWeight"); - return sf; -} + try { + sf = eventInfo->mcEventWeights().at(m_config->nominalWeightIndex()); + eventInfo->auxdecor<float>("AnalysisTop_eventWeight") = sf; + } catch (std::out_of_range &e) { + ATH_MSG_ERROR("MC weight specified by index " << m_config->nominalWeightIndex() + << " does not exist: "); + throw; + } + return sf; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ScaleFactorRetriever.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ScaleFactorRetriever.cxx index b777c655d890..65cdd47b26d7 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ScaleFactorRetriever.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/ScaleFactorRetriever.cxx @@ -1,33 +1,53 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopCorrections/ScaleFactorRetriever.h" +#include "TopCorrections/TopCorrectionsTools.h" #include <vector> #include <string> #include "TopEvent/Event.h" #include "TopEvent/EventTools.h" +#include "TopEvent/SystematicEvent.h" +#include "TopConfiguration/ConfigurationSettings.h" #include "TopConfiguration/TopConfig.h" #include "AthContainers/AuxElement.h" +#include "xAODRootAccess/TStore.h" +#include "xAODEventInfo/EventInfo.h" namespace top { + ScaleFactorRetriever::ScaleFactorRetriever(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), + m_preferGlobalTriggerSF(ConfigurationSettings::get()->feature("PreferGlobalTriggerSF")) { + declareProperty("config", m_config); + } + + StatusCode ScaleFactorRetriever::initialize() { + ATH_MSG_INFO("Initialising " << this->name()); - ScaleFactorRetriever::ScaleFactorRetriever(std::shared_ptr<top::TopConfig> config) : - m_config(config) { - std::shared_ptr<std::vector<std::string>> selectors = config -> allSelectionNames(); + std::shared_ptr<std::vector<std::string> > selectors = m_config->allSelectionNames(); for (std::string selPtr : *selectors) { - std::vector<std::string> muonTrig = config -> muonTriggers(selPtr); - std::vector<std::string> electronTrig = config -> electronTriggers(selPtr); + std::vector<std::string> muonTrig_Tight = m_config->muonTriggers_Tight(selPtr); + std::vector<std::string> electronTrig_Tight = m_config->electronTriggers_Tight(selPtr); + std::vector<std::string> muonTrig_Loose = m_config->muonTriggers_Loose(selPtr); + std::vector<std::string> electronTrig_Loose = m_config->electronTriggers_Loose(selPtr); - for (auto trig : muonTrig) - m_muonTriggers.push_back(trig); + for (auto trig : muonTrig_Tight) + m_muonTriggers_Tight.push_back(trig); + for (auto trig : muonTrig_Loose) + m_muonTriggers_Loose.push_back(trig); - for (auto trig : electronTrig) - m_electronTriggers.push_back(trig); + for (auto trig : electronTrig_Tight) + m_electronTriggers_Tight.push_back(trig); + for (auto trig : electronTrig_Loose) + m_electronTriggers_Loose.push_back(trig); } + + return StatusCode::SUCCESS; } // Pile up SF @@ -40,14 +60,13 @@ namespace top { float sf(1.); if (var == 0) { // nominal - if (event.m_info->isAvailable<float>("PileupWeight")) - sf = event.m_info->auxdataConst<float>("PileupWeight"); + if (event.m_info->isAvailable<float>("PileupWeight")) sf = event.m_info->auxdataConst<float>("PileupWeight"); } else if (var == 1) { // dataSF up - if (event.m_info->isAvailable<float>("PileupWeight_UP")) - sf = event.m_info->auxdataConst<float>("PileupWeight_UP"); + if (event.m_info->isAvailable<float>("PileupWeight_UP")) sf = + event.m_info->auxdataConst<float>("PileupWeight_UP"); } else if (var == -1) { // dataSF down - if (event.m_info->isAvailable<float>("PileupWeight_DOWN")) - sf = event.m_info->auxdataConst<float>("PileupWeight_DOWN"); + if (event.m_info->isAvailable<float>("PileupWeight_DOWN")) sf = event.m_info->auxdataConst<float>( + "PileupWeight_DOWN"); } return sf; @@ -61,8 +80,82 @@ namespace top { * triggerSF(event, SFSyst); } + float ScaleFactorRetriever::globalTriggerSF(const top::Event& event, const top::topSFSyst SFSyst) const { + float sf(1.0); + + static const std::string prefix = "AnalysisTop_Trigger_SF_"; + + xAOD::SystematicEvent const* eventInfo = event.m_systematicEvent; + top::check(eventInfo, "Failed to retrieve SystematicEvent"); + const bool electronTriggerIsEmpty = event.m_isLoose ? m_electronTriggers_Loose.empty() : m_electronTriggers_Tight.empty(); + const bool muonTriggerIsEmpty = event.m_isLoose ? m_muonTriggers_Loose.empty() : m_muonTriggers_Tight.empty(); + + // Create a hard-coded map linking top::topSFSyst <-> EventInfo decoration + switch (SFSyst) { + case top::topSFSyst::EL_SF_Trigger_UP: + if (electronTriggerIsEmpty) { + sf = 1; + } else { + sf = eventInfo->auxdataConst<float>(prefix + "EL_EFF_Trigger_TOTAL_1NPCOR_PLUS_UNCOR__1up"); + } + break; + + case top::topSFSyst::EL_SF_Trigger_DOWN: + if (electronTriggerIsEmpty) { + sf = 1; + } else { + sf = eventInfo->auxdataConst<float>(prefix + "EL_EFF_Trigger_TOTAL_1NPCOR_PLUS_UNCOR__1down"); + } + break; + + case top::topSFSyst::MU_SF_Trigger_STAT_UP: + if (muonTriggerIsEmpty) { + sf = 1; + } else { + sf = eventInfo->auxdataConst<float>(prefix + "MUON_EFF_TrigStatUncertainty__1up"); + } + break; + + case top::topSFSyst::MU_SF_Trigger_STAT_DOWN: + if (muonTriggerIsEmpty) { + sf = 1; + } else { + sf = eventInfo->auxdataConst<float>(prefix + "MUON_EFF_TrigStatUncertainty__1down"); + } + break; + + case top::topSFSyst::MU_SF_Trigger_SYST_UP: + if (muonTriggerIsEmpty) { + sf = 1; + } else { + sf = eventInfo->auxdataConst<float>(prefix + "MUON_EFF_TrigSystUncertainty__1up"); + } + break; + + case top::topSFSyst::MU_SF_Trigger_SYST_DOWN: + if (muonTriggerIsEmpty) { + sf = 1; + } else { + sf = eventInfo->auxdataConst<float>(prefix + "MUON_EFF_TrigSystUncertainty__1down"); + } + break; + + default: + // Nominal weight + sf = eventInfo->auxdataConst<float>(prefix); + break; + } + return sf; + } + float ScaleFactorRetriever::triggerSF(const top::Event& event, const top::topSFSyst SFSyst) const { + return(m_preferGlobalTriggerSF && + m_config->useGlobalTrigger() ? globalTriggerSF(event, SFSyst) : oldTriggerSF(event, SFSyst)); + } + + float ScaleFactorRetriever::oldTriggerSF(const top::Event& event, + const top::topSFSyst SFSyst) const { std::string electronID = m_config->electronID(); if (event.m_isLoose) { electronID = m_config->electronIDLoose(); @@ -79,43 +172,104 @@ namespace top { for (auto elPtr : event.m_electrons) { bool trigMatch = false; - for (const auto& trigger : m_electronTriggers) { + for (const auto& trigger : event.m_isLoose ? m_electronTriggers_Loose : m_electronTriggers_Tight) { std::string trig = "TRIGMATCH_" + trigger; if (elPtr->isAvailable<char>(trig)) { - if (elPtr->auxdataConst<char>(trig) == 1) - trigMatch = true; + if (elPtr->auxdataConst<char>(trig) == 1) trigMatch = true; } } - if (trigMatch) - triggerSFvec.push_back(electronSF_Trigger(*elPtr , electronID , SFSyst)); + if (trigMatch) triggerSFvec.push_back(electronSF_Trigger(*elPtr, electronID, SFSyst, event.m_isLoose)); } // Loop over muons for (auto muPtr : event.m_muons) { bool trigMatch = false; - for (const auto& trigger : m_muonTriggers) { + for (const auto& trigger : event.m_isLoose ? m_muonTriggers_Loose : m_muonTriggers_Tight) { std::string trig = "TRIGMATCH_" + trigger; if (muPtr->isAvailable<char>(trig)) { - if (muPtr->auxdataConst<char>(trig) == 1) - trigMatch = true; + if (muPtr->auxdataConst<char>(trig) == 1) trigMatch = true; } } - if (trigMatch) - triggerSFvec.push_back(muonSF_Trigger(*muPtr , muonID , SFSyst)); + if (trigMatch) triggerSFvec.push_back(muonSF_Trigger(*muPtr, muonID, SFSyst, event.m_isLoose)); } // for the cutflow histograms, in case the lepton triggers have not been checked yet - if (triggerSFvec.empty()) - return 1.0; + if (triggerSFvec.empty()) return 1.0; float trigSF = 1.0; for (float SF : triggerSFvec) trigSF *= (1.0 - SF); - return 1.0-trigSF; + return 1.0 - trigSF; + } + + std::vector<float> ScaleFactorRetriever::electronSFSystVariationVector(const top::Event& event, + const top::topSFComp SFComp, int var) const { + std::vector<float> sf; + if (abs(var) != 1) { + ATH_MSG_ERROR("ScaleFactorRetriever::electronSFSystVariationVector must be called with var=+1 (up) or -1 (down)"); + return sf; + } + if (SFComp != top::topSFComp::RECO && SFComp != top::topSFComp::ID && SFComp != top::topSFComp::ISOLATION) { + ATH_MSG_ERROR( + "ScaleFactorRetriever::electronSFSystVariationVector is currently implemented only for SFComp=RECO, ID, ISOLATION"); + return sf; + } + + std::string decorationName = "EL_SF_"; + if(event.m_isLoose && !m_config->applyTightSFsInLooseTree() && SFComp != top::topSFComp::RECO) decorationName = "EL_LOOSE_SF_"; + std::string electronID = ""; + std::string electronIso = ""; + + if (SFComp == top::topSFComp::RECO) decorationName += "Reco_"; + if (SFComp == top::topSFComp::ID) { + decorationName += "ID_"; + electronID = m_config->electronID(); + if (event.m_isLoose && !m_config->applyTightSFsInLooseTree()) { + electronID = m_config->electronIDLoose(); + } + decorationName += electronID; + decorationName += "_"; + } + if (SFComp == top::topSFComp::ISOLATION) { + decorationName += "Iso_"; + electronIso = m_config->electronIsolationSF(); + if (event.m_isLoose && !m_config->applyTightSFsInLooseTree()) { + electronIso = m_config->electronIsolationSFLoose(); + } + decorationName += electronIso; + decorationName += "_"; + } + + if (var == 1) decorationName += "CorrModel_UP"; + else decorationName += "CorrModel_DOWN"; + + for (auto elPtr : event.m_electrons) { + std::vector<float> sf_aux; + if (elPtr->isAvailable<std::vector<float> >(decorationName)) { + sf_aux = elPtr->auxdataConst<std::vector<float> >(decorationName); + } else { + ATH_MSG_ERROR( + "ScaleFactorRetriever::electronSFSystVariationVector error in accessing decoration " << decorationName); + } + + if (sf.size() == 0) sf = std::vector<float>(sf_aux.size(), leptonSF(event, top::topSFSyst::nominal)); + if (sf.size() != sf_aux.size()) ATH_MSG_ERROR( + "ScaleFactorRetriever::electronSFSystVariationVector error in size of vector of electron SFs"); + double oldSF = 1.; + if (SFComp == top::topSFComp::RECO) oldSF = electronSF_Reco(*elPtr, top::topSFSyst::nominal,event.m_isLoose); + if (SFComp == top::topSFComp::ID) oldSF = electronSF_ID(*elPtr, electronID, top::topSFSyst::nominal,event.m_isLoose); + if (SFComp == top::topSFComp::ISOLATION) oldSF = electronSF_Isol(*elPtr, electronIso, top::topSFSyst::nominal,event.m_isLoose); + + for (unsigned int i = 0; i < sf.size(); i++) { + sf[i] *= (sf_aux[i] / oldSF); + } + }//end of loop on electrons + + return sf; } // Obtain the electron SF @@ -128,12 +282,11 @@ namespace top { if (event.m_isLoose && !m_config->applyTightSFsInLooseTree()) { electronID = m_config->electronIDLoose(); } - std::string electronIso = m_config->electronIsolation(); + std::string electronIso = m_config->electronIsolationSF(); if (event.m_isLoose && !m_config->applyTightSFsInLooseTree()) { - electronIso = m_config->electronIsolationLoose(); + electronIso = m_config->electronIsolationSFLoose(); } - float trigger(1.); float reco(1.); float id(1.); float isol(1.); @@ -142,74 +295,99 @@ namespace top { // Loop over electrons for (auto elPtr : event.m_electrons) { - if (event.m_isLoose && m_config->applyTightSFsInLooseTree() && !elPtr->auxdataConst<char>("passPreORSelection")) - continue;// in case one want the tight SFs in the loose tree, need to only take the tight leptons - - // trigger *= electronSF_Trigger(*elPtr , electronID , SFSyst); - reco *= electronSF_Reco(*elPtr , SFSyst); - id *= electronSF_ID(*elPtr , electronID , SFSyst); - isol *= electronSF_Isol(*elPtr , electronIso , SFSyst); - chargeid *= electronSF_ChargeID(*elPtr, electronID , electronIso, SFSyst); - chargemisid *= electronSF_ChargeMisID(*elPtr, electronID , electronIso, SFSyst); - - } - - sf = trigger*reco*id*isol; // *chargeid*chargemisid; // let the charge id scale factors out until further tested by users - - // if (SFComp == top::topSFComp::TRIGGER) - // return trigger; - if (SFComp == top::topSFComp::RECO) - return reco; - else if (SFComp == top::topSFComp::ID) - return id; - else if (SFComp == top::topSFComp::ISOLATION) - return isol; - else if (SFComp == top::topSFComp::CHARGEID) - return chargeid; - else if (SFComp == top::topSFComp::CHARGEMISID) - return chargemisid; - else if (SFComp == top::topSFComp::ALL) - return sf; + if (event.m_isLoose && m_config->applyTightSFsInLooseTree() && + !elPtr->auxdataConst<char>("passPreORSelection")) continue; // in case one want the tight SFs in the loose + // tree, need to only take the tight leptons + + reco *= electronSF_Reco(*elPtr, SFSyst,event.m_isLoose); + id *= electronSF_ID(*elPtr, electronID, SFSyst,event.m_isLoose); + isol *= electronSF_Isol(*elPtr, electronIso, SFSyst,event.m_isLoose); + chargeid *= electronSF_ChargeID(*elPtr, electronID, electronIso, SFSyst,event.m_isLoose); + chargemisid *= electronSF_ChargeMisID(*elPtr, electronID, electronIso, SFSyst,event.m_isLoose); + } + + sf = reco * id * isol; // *chargeid*chargemisid; // let the charge id scale factors out until further tested by + // users + + if (SFComp == top::topSFComp::RECO) return reco; + else if (SFComp == top::topSFComp::ID) return id; + else if (SFComp == top::topSFComp::ISOLATION) return isol; + else if (SFComp == top::topSFComp::CHARGEID) return chargeid; + else if (SFComp == top::topSFComp::CHARGEMISID) return chargemisid; + else if (SFComp == top::topSFComp::ALL) return sf; return sf; } +// Obtain the electron SF + float ScaleFactorRetriever::fwdElectronSF(const top::Event& event, + const top::topSFSyst SFSyst, + const top::topSFComp SFComp) const { + float sf(1.); + std::string fwdElectronID = m_config->fwdElectronID(); + if (event.m_isLoose) { + fwdElectronID = m_config->fwdElectronIDLoose(); + } - float ScaleFactorRetriever::electronSF_Trigger(const xAOD::Electron& x, - const top::topSFSyst SFSyst, - bool isLoose) const { - - return electronSF_Trigger(x, (isLoose ? m_config->electronIDLoose() : m_config->electronID()), SFSyst); + float reco(1.); + float id(1.); + float isol(1.); + float chargeid(1.); + float chargemisid(1.); + // Loop over electrons + for (auto elPtr : event.m_fwdElectrons) { + //currently on ID SFs are supported for fwd electrons + id *= fwdElectronSF_ID(*elPtr, fwdElectronID, SFSyst, event.m_isLoose); } - float ScaleFactorRetriever::electronEff_Trigger(const xAOD::Electron& x, - const top::topSFSyst SFSyst, - bool isLoose) const { + sf = reco * id * isol; - return electronEff_Trigger(x, (isLoose ? m_config->electronIDLoose() : m_config->electronID()), SFSyst); + if (SFComp == top::topSFComp::RECO) return reco; + else if (SFComp == top::topSFComp::ID) return id; + else if (SFComp == top::topSFComp::ISOLATION) return isol; + else if (SFComp == top::topSFComp::CHARGEID) return chargeid; + else if (SFComp == top::topSFComp::CHARGEMISID) return chargemisid; + else if (SFComp == top::topSFComp::ALL) return sf; + return sf; } + float ScaleFactorRetriever::electronSF_Trigger(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const { + return electronSF_Trigger(x, (isLoose ? m_config->electronIDLoose() : m_config->electronID()), SFSyst, isLoose); + } + + float ScaleFactorRetriever::electronEff_Trigger(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const { + return electronEff_Trigger(x, (isLoose ? m_config->electronIDLoose() : m_config->electronID()), SFSyst, isLoose); + } float ScaleFactorRetriever::electronSF_Trigger(const xAOD::Electron& x, const std::string& id, - const top::topSFSyst SFSyst) const { + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("EL_SF_Trigger_"+id)) { - sf = x.auxdataConst<float>("EL_SF_Trigger_"+id); + + std::string prefix="EL"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_Trigger_" + id)) { + sf = x.auxdataConst<float>(prefix+"_SF_Trigger_" + id); } if (SFSyst == top::topSFSyst::EL_SF_Trigger_UP) { - if (x.isAvailable<float>("EL_SF_Trigger_"+id+"_UP")) { - sf = x.auxdataConst<float>("EL_SF_Trigger_"+id+"_UP"); + if (x.isAvailable<float>(prefix+"_SF_Trigger_" + id + "_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_Trigger_" + id + "_UP"); } } if (SFSyst == top::topSFSyst::EL_SF_Trigger_DOWN) { - if (x.isAvailable<float>("EL_SF_Trigger_"+id+"_DOWN")) { - sf = x.auxdataConst<float>("EL_SF_Trigger_"+id+"_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_Trigger_" + id + "_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_Trigger_" + id + "_DOWN"); } } @@ -217,114 +395,158 @@ namespace top { } float ScaleFactorRetriever::electronEff_Trigger(const xAOD::Electron& x, - const std::string& id, - const top::topSFSyst SFSyst) const { + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const { float eff(1.); - if (x.isAvailable<float>("EL_EFF_Trigger_"+id)) { - eff = x.auxdataConst<float>("EL_EFF_Trigger_"+id); + + std::string prefix="EL"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_EFF_Trigger_" + id)) { + eff = x.auxdataConst<float>(prefix+"_EFF_Trigger_" + id); } if (SFSyst == top::topSFSyst::EL_SF_Trigger_UP) { - if (x.isAvailable<float>("EL_EFF_Trigger_"+id+"_UP")) { - eff = x.auxdataConst<float>("EL_EFF_Trigger_"+id+"_UP"); + if (x.isAvailable<float>(prefix+"_EFF_Trigger_" + id + "_UP")) { + eff = x.auxdataConst<float>(prefix+"_EFF_Trigger_" + id + "_UP"); } } if (SFSyst == top::topSFSyst::EL_SF_Trigger_DOWN) { - if (x.isAvailable<float>("EL_EFF_Trigger_"+id+"_DOWN")) { - eff = x.auxdataConst<float>("EL_EFF_Trigger_"+id+"_DOWN"); + if (x.isAvailable<float>(prefix+"_EFF_Trigger_" + id + "_DOWN")) { + eff = x.auxdataConst<float>(prefix+"_EFF_Trigger_" + id + "_DOWN"); } } return eff; } - float ScaleFactorRetriever::electronSF_Reco(const xAOD::Electron& x, - const top::topSFSyst SFSyst) const { + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("EL_SF_Reco")) { - sf = x.auxdataConst<float>("EL_SF_Reco"); + + std::string prefix="EL"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_Reco")) { + sf = x.auxdataConst<float>(prefix+"_SF_Reco"); } if (SFSyst == top::topSFSyst::EL_SF_Reco_UP) { - if (x.isAvailable<float>("EL_SF_Reco_UP")) { - sf = x.auxdataConst<float>("EL_SF_Reco_UP"); + if (x.isAvailable<float>(prefix+"_SF_Reco_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_Reco_UP"); } } if (SFSyst == top::topSFSyst::EL_SF_Reco_DOWN) { - if (x.isAvailable<float>("EL_SF_Reco_DOWN")) { - sf = x.auxdataConst<float>("EL_SF_Reco_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_Reco_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_Reco_DOWN"); } } return sf; } - float ScaleFactorRetriever::electronSF_ID(const xAOD::Electron& x, const top::topSFSyst SFSyst, bool isLoose) const { - - return electronSF_ID(x, (isLoose ? m_config->electronIDLoose() : m_config->electronID()), SFSyst); - + return electronSF_ID(x, (isLoose ? m_config->electronIDLoose() : m_config->electronID()), SFSyst, isLoose); } + float ScaleFactorRetriever::fwdElectronSF_ID(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const { + return fwdElectronSF_ID(x, (isLoose ? m_config->fwdElectronIDLoose() : m_config->fwdElectronID()), SFSyst, isLoose); + } float ScaleFactorRetriever::electronSF_ID(const xAOD::Electron& x, const std::string& id, - const top::topSFSyst SFSyst) const { + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("EL_SF_ID_"+id)) { - sf = x.auxdataConst<float>("EL_SF_ID_"+id); + + std::string prefix="EL"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_ID_" + id)) { + sf = x.auxdataConst<float>(prefix+"_SF_ID_" + id); } if (SFSyst == top::topSFSyst::EL_SF_ID_UP) { - if (x.isAvailable<float>("EL_SF_ID_"+id+"_UP")) { - sf = x.auxdataConst<float>("EL_SF_ID_"+id+"_UP"); + if (x.isAvailable<float>(prefix+"_SF_ID_" + id + "_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_ID_" + id + "_UP"); } } if (SFSyst == top::topSFSyst::EL_SF_ID_DOWN) { - if (x.isAvailable<float>("EL_SF_ID_"+id+"_DOWN")) { - sf = x.auxdataConst<float>("EL_SF_ID_"+id+"_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_ID_" + id + "_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_ID_" + id + "_DOWN"); } } return sf; } + float ScaleFactorRetriever::fwdElectronSF_ID(const xAOD::Electron& x, + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const { + float sf(1.); + + std::string prefix="FWDEL"; + if(isLoose) prefix+="_LOOSE"; - float ScaleFactorRetriever::electronSF_Isol(const xAOD::Electron& x, - const top::topSFSyst SFSyst, - bool isLoose) const { + if (x.isAvailable<float>(prefix+"_SF_ID_" + id)) { + sf = x.auxdataConst<float>(prefix+"_SF_ID_" + id); + } - return electronSF_Isol(x, (isLoose ? m_config->electronIsolationLoose() : m_config->electronIsolation()), SFSyst); + if (SFSyst == top::topSFSyst::FWDEL_SF_ID_UP) { + if (x.isAvailable<float>(prefix+"_SF_ID_" + id + "_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_ID_" + id + "_UP"); + } + } + if (SFSyst == top::topSFSyst::FWDEL_SF_ID_DOWN) { + if (x.isAvailable<float>(prefix+"_SF_ID_" + id + "_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_ID_" + id + "_DOWN"); + } } + return sf; + } + + float ScaleFactorRetriever::electronSF_Isol(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const { + return electronSF_Isol(x, (isLoose ? m_config->electronIsolationSFLoose() : m_config->electronIsolationSF()), + SFSyst, isLoose); + } + float ScaleFactorRetriever::electronSF_Isol(const xAOD::Electron& x, const std::string& iso, - const top::topSFSyst SFSyst) const { + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("EL_SF_Iso_"+iso)) { - sf = x.auxdataConst<float>("EL_SF_Iso_"+iso); + + std::string prefix="EL"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_Iso_" + iso)) { + sf = x.auxdataConst<float>(prefix+"_SF_Iso_" + iso); } if (SFSyst == top::topSFSyst::EL_SF_Isol_UP) { - - if (x.isAvailable<float>("EL_SF_Iso_"+iso+"_UP")) { - - sf = x.auxdataConst<float>("EL_SF_Iso_"+iso+"_UP"); - + if (x.isAvailable<float>(prefix+"_SF_Iso_" + iso + "_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_Iso_" + iso + "_UP"); } } if (SFSyst == top::topSFSyst::EL_SF_Isol_DOWN) { - if (x.isAvailable<float>("EL_SF_Iso_"+iso+"_DOWN")) { - sf = x.auxdataConst<float>("EL_SF_Iso_"+iso+"_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_Iso_" + iso + "_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_Iso_" + iso + "_DOWN"); } } @@ -334,29 +556,32 @@ namespace top { float ScaleFactorRetriever::electronSF_ChargeID(const xAOD::Electron& x, const top::topSFSyst SFSyst, bool isLoose) const { - return electronSF_ChargeID(x, (isLoose ? m_config->electronIDLoose() : m_config->electronID()), - (isLoose ? m_config->electronIsolationLoose() : m_config->electronIsolation()), SFSyst); - + (isLoose ? m_config->electronIsolationLoose() : m_config->electronIsolation()), SFSyst, isLoose); } float ScaleFactorRetriever::electronSF_ChargeID(const xAOD::Electron& x, const std::string& id, const std::string& iso, - const top::topSFSyst SFSyst) const { + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("EL_SF_ChargeID_"+id+"_"+iso)) { - sf = x.auxdataConst<float>("EL_SF_ChargeID_"+id+"_"+iso); + + std::string prefix="EL"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_ChargeID_" + id + "_" + iso)) { + sf = x.auxdataConst<float>(prefix+"_SF_ChargeID_" + id + "_" + iso); } if (SFSyst == top::topSFSyst::EL_SF_ChargeID_UP) { - if (x.isAvailable<float>("EL_SF_ChargeID_"+id+"_"+iso+"_UP")) { - sf = x.auxdataConst<float>("EL_SF_ChargeID_"+id+"_"+iso+"_UP"); + if (x.isAvailable<float>(prefix+"_SF_ChargeID_" + id + "_" + iso + "_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_ChargeID_" + id + "_" + iso + "_UP"); } } if (SFSyst == top::topSFSyst::EL_SF_ChargeID_DOWN) { - if (x.isAvailable<float>("EL_SF_ChargeID_"+id+"_"+iso+"_DOWN")) { - sf = x.auxdataConst<float>("EL_SF_ChargeID_"+id+"_"+iso+"_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_ChargeID_" + id + "_" + iso + "_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_ChargeID_" + id + "_" + iso + "_DOWN"); } } return sf; @@ -365,41 +590,45 @@ namespace top { float ScaleFactorRetriever::electronSF_ChargeMisID(const xAOD::Electron& x, const top::topSFSyst SFSyst, bool isLoose) const { - return electronSF_ChargeMisID(x, (isLoose ? m_config->electronIDLoose() : m_config->electronID()), - (isLoose ? m_config->electronIsolationLoose() : m_config->electronIsolation()), SFSyst); - + (isLoose ? m_config->electronIsolationLoose() : m_config->electronIsolation()), + SFSyst, isLoose); } float ScaleFactorRetriever::electronSF_ChargeMisID(const xAOD::Electron& x, const std::string& id, const std::string& iso, - const top::topSFSyst SFSyst) const { + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("EL_SF_ChargeMisID_"+id+"_"+iso)) { - sf = x.auxdataConst<float>("EL_SF_ChargeMisID_"+id+"_"+iso); + + std::string prefix="EL"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso)) { + sf = x.auxdataConst<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso); } if (SFSyst == top::topSFSyst::EL_SF_ChargeMisID_STAT_UP) { - if (x.isAvailable<float>("EL_SF_ChargeMisID_"+id+"_"+iso+"_STAT_UP")) { - sf = x.auxdataConst<float>("EL_SF_ChargeMisID_"+id+"_"+iso+"_STAT_UP"); + if (x.isAvailable<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso + "_STAT_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso + "_STAT_UP"); } } if (SFSyst == top::topSFSyst::EL_SF_ChargeMisID_STAT_DOWN) { - if (x.isAvailable<float>("EL_SF_ChargeMisID_"+id+"_"+iso+"_STAT_DOWN")) { - sf = x.auxdataConst<float>("EL_SF_ChargeMisID_"+id+"_"+iso+"_STAT_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso + "_STAT_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso + "_STAT_DOWN"); } } if (SFSyst == top::topSFSyst::EL_SF_ChargeMisID_SYST_UP) { - if (x.isAvailable<float>("EL_SF_ChargeMisID_"+id+"_"+iso+"_SYST_UP")) { - sf = x.auxdataConst<float>("EL_SF_ChargeMisID_"+id+"_"+iso+"_SYST_UP"); + if (x.isAvailable<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso + "_SYST_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso + "_SYST_UP"); } } if (SFSyst == top::topSFSyst::EL_SF_ChargeMisID_SYST_DOWN) { - if (x.isAvailable<float>("EL_SF_ChargeMisID_"+id+"_"+iso+"_SYST_DOWN")) { - sf = x.auxdataConst<float>("EL_SF_ChargeMisID_"+id+"_"+iso+"_SYST_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso + "_SYST_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_ChargeMisID_" + id + "_" + iso + "_SYST_DOWN"); } } @@ -413,14 +642,13 @@ namespace top { float sf(1.); std::string muonID = m_config->muonQuality(); - std::string muonIso = m_config->muonIsolation(); + std::string muonIso = m_config->muonIsolationSF(); if (event.m_isLoose && !m_config->applyTightSFsInLooseTree()) { muonID = m_config->muonQualityLoose(); - muonIso = m_config->muonIsolationLoose(); + muonIso = m_config->muonIsolationSFLoose(); } - float trigger(1.); float reco(1.); float id(1.); float isol(1.); @@ -428,72 +656,68 @@ namespace top { // Loop over muons for (auto muPtr : event.m_muons) { - if (event.m_isLoose && m_config->applyTightSFsInLooseTree() && !muPtr->auxdataConst<char>("passPreORSelection")) - continue;// in case one want the tight SFs in the loose tree, need to only take the tight leptons - - id *= muonSF_ID(*muPtr , muonID , SFSyst); - isol *= muonSF_Isol(*muPtr , muonIso , SFSyst); + if (event.m_isLoose && m_config->applyTightSFsInLooseTree() && + !muPtr->auxdataConst<char>("passPreORSelection")) continue; // in case one want the tight SFs in the loose + // tree, need to only take the tight leptons - if(m_config -> applyTTVACut()) // if not using TTVA cut, leave SF set to 1.0 - TTVA *= muonSF_TTVA(*muPtr , SFSyst); + id *= muonSF_ID(*muPtr, muonID, SFSyst, event.m_isLoose); + isol *= muonSF_Isol(*muPtr, muonIso, SFSyst, event.m_isLoose); + if (m_config->applyTTVACut()) // if not using TTVA cut, leave SF set to 1.0 + TTVA *= muonSF_TTVA(*muPtr, SFSyst); } - sf = trigger * id * isol * TTVA; + sf = id * isol * TTVA; - // if (SFComp == top::topSFComp::TRIGGER) - // return trigger; - if (SFComp == top::topSFComp::RECO) - return reco; - else if (SFComp == top::topSFComp::ID) - return id; - else if (SFComp == top::topSFComp::ISOLATION) - return isol; - else if (SFComp == top::topSFComp::TTVA) - return TTVA; - else if (SFComp == top::topSFComp::ALL) - return sf; + if (SFComp == top::topSFComp::RECO) return reco; + else if (SFComp == top::topSFComp::ID) return id; + else if (SFComp == top::topSFComp::ISOLATION) return isol; + else if (SFComp == top::topSFComp::TTVA) return TTVA; + else if (SFComp == top::topSFComp::ALL) return sf; return sf; - } float ScaleFactorRetriever::muonSF_Trigger(const xAOD::Muon& x, const top::topSFSyst SFSyst, bool isLoose) const { - return muonSF_Trigger(x, (isLoose ? m_config->muonQualityLoose() : m_config->muonQuality()), SFSyst); + return muonSF_Trigger(x, (isLoose ? m_config->muonQualityLoose() : m_config->muonQuality()), SFSyst, isLoose); } - float ScaleFactorRetriever::muonSF_Trigger(const xAOD::Muon& x, const std::string& id, - const top::topSFSyst SFSyst) const { + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("MU_SF_Trigger_"+id)) { - sf = x.auxdataConst<float>("MU_SF_Trigger_"+id); + + std::string prefix="MU"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_Trigger_" + id)) { + sf = x.auxdataConst<float>(prefix+"_SF_Trigger_" + id); } if (SFSyst == top::topSFSyst::MU_SF_Trigger_STAT_UP) { - if (x.isAvailable<float>("MU_SF_Trigger_"+id+"_STAT_UP")) { - sf = x.auxdataConst<float>("MU_SF_Trigger_"+id+"_STAT_UP"); + if (x.isAvailable<float>(prefix+"_SF_Trigger_" + id + "_STAT_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_Trigger_" + id + "_STAT_UP"); } } if (SFSyst == top::topSFSyst::MU_SF_Trigger_STAT_DOWN) { - if (x.isAvailable<float>("MU_SF_Trigger_"+id+"_STAT_DOWN")) { - sf = x.auxdataConst<float>("MU_SF_Trigger_"+id+"_STAT_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_Trigger_" + id + "_STAT_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_Trigger_" + id + "_STAT_DOWN"); } } if (SFSyst == top::topSFSyst::MU_SF_Trigger_SYST_UP) { - if (x.isAvailable<float>("MU_SF_Trigger_"+id+"_SYST_UP")) { - sf = x.auxdataConst<float>("MU_SF_Trigger_"+id+"_SYST_UP"); + if (x.isAvailable<float>(prefix+"_SF_Trigger_" + id + "_SYST_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_Trigger_" + id + "_SYST_UP"); } } if (SFSyst == top::topSFSyst::MU_SF_Trigger_SYST_DOWN) { - if (x.isAvailable<float>("MU_SF_Trigger_"+id+"_SYST_DOWN")) { - sf = x.auxdataConst<float>("MU_SF_Trigger_"+id+"_SYST_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_Trigger_" + id + "_SYST_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_Trigger_" + id + "_SYST_DOWN"); } } @@ -502,44 +726,46 @@ namespace top { return sf; } - - float ScaleFactorRetriever::muonEff_Trigger(const xAOD::Muon& x, - const top::topSFSyst SFSyst, - bool isLoose) const { - return muonEff_Trigger(x, (isLoose ? m_config->muonQualityLoose() : m_config->muonQuality()), SFSyst); + const top::topSFSyst SFSyst, + bool isLoose) const { + return muonEff_Trigger(x, (isLoose ? m_config->muonQualityLoose() : m_config->muonQuality()), SFSyst, isLoose); } - float ScaleFactorRetriever::muonEff_Trigger(const xAOD::Muon& x, - const std::string& id, - const top::topSFSyst SFSyst) const { + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const { float eff(1.); - if (x.isAvailable<float>("MU_EFF_Trigger_"+id)) { - eff = x.auxdataConst<float>("MU_EFF_Trigger_"+id); + + std::string prefix="MU"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_EFF_Trigger_" + id)) { + eff = x.auxdataConst<float>(prefix+"_EFF_Trigger_" + id); } if (SFSyst == top::topSFSyst::MU_SF_Trigger_STAT_UP) { - if (x.isAvailable<float>("MU_EFF_Trigger_"+id+"_STAT_UP")) { - eff = x.auxdataConst<float>("MU_EFF_Trigger_"+id+"_STAT_UP"); + if (x.isAvailable<float>(prefix+"_EFF_Trigger_" + id + "_STAT_UP")) { + eff = x.auxdataConst<float>(prefix+"_EFF_Trigger_" + id + "_STAT_UP"); } } if (SFSyst == top::topSFSyst::MU_SF_Trigger_STAT_DOWN) { - if (x.isAvailable<float>("MU_EFF_Trigger_"+id+"_STAT_DOWN")) { - eff = x.auxdataConst<float>("MU_EFF_Trigger_"+id+"_STAT_DOWN"); + if (x.isAvailable<float>(prefix+"_EFF_Trigger_" + id + "_STAT_DOWN")) { + eff = x.auxdataConst<float>(prefix+"_EFF_Trigger_" + id + "_STAT_DOWN"); } } if (SFSyst == top::topSFSyst::MU_SF_Trigger_SYST_UP) { - if (x.isAvailable<float>("MU_EFF_Trigger_"+id+"_SYST_UP")) { - eff = x.auxdataConst<float>("MU_EFF_Trigger_"+id+"_SYST_UP"); + if (x.isAvailable<float>(prefix+"_EFF_Trigger_" + id + "_SYST_UP")) { + eff = x.auxdataConst<float>(prefix+"_EFF_Trigger_" + id + "_SYST_UP"); } } if (SFSyst == top::topSFSyst::MU_SF_Trigger_SYST_DOWN) { - if (x.isAvailable<float>("MU_EFF_Trigger_"+id+"_SYST_DOWN")) { - eff = x.auxdataConst<float>("MU_EFF_Trigger_"+id+"_SYST_DOWN"); + if (x.isAvailable<float>(prefix+"_EFF_Trigger_" + id + "_SYST_DOWN")) { + eff = x.auxdataConst<float>(prefix+"_EFF_Trigger_" + id + "_SYST_DOWN"); } } @@ -548,43 +774,53 @@ namespace top { return eff; } - float ScaleFactorRetriever::muonSF_ID(const xAOD::Muon& x, - const top::topSFSyst SFSyst, - bool isLoose) const { - return muonSF_ID(x, (isLoose ? m_config->muonQualityLoose() : m_config->muonQuality()), SFSyst); + const top::topSFSyst SFSyst, + bool isLoose) const { + return muonSF_ID(x, (isLoose ? m_config->muonQualityLoose() : m_config->muonQuality()), SFSyst, isLoose); } float ScaleFactorRetriever::muonSF_ID(const xAOD::Muon& x, const std::string& id, - const top::topSFSyst SFSyst) const { + const top::topSFSyst SFSyst, + bool isLoose) const { + std::string decoration = "MU_SF_ID_"; + if(isLoose) decoration = "MU_LOOSE_SF_ID_"; + decoration+=id; - std::string decoration = "MU_SF_ID_"+id; switch (SFSyst) { case top::topSFSyst::MU_SF_ID_STAT_UP: decoration += "_STAT_UP"; break; + case top::topSFSyst::MU_SF_ID_STAT_DOWN: decoration += "_STAT_DOWN"; break; + case top::topSFSyst::MU_SF_ID_SYST_UP: decoration += "_SYST_UP"; break; + case top::topSFSyst::MU_SF_ID_SYST_DOWN: decoration += "_SYST_DOWN"; break; + case top::topSFSyst::MU_SF_ID_STAT_LOWPT_UP: decoration += "_STAT_LOWPT_UP"; break; + case top::topSFSyst::MU_SF_ID_STAT_LOWPT_DOWN: decoration += "_STAT_LOWPT_DOWN"; break; + case top::topSFSyst::MU_SF_ID_SYST_LOWPT_UP: decoration += "_SYST_LOWPT_UP"; break; + case top::topSFSyst::MU_SF_ID_SYST_LOWPT_DOWN: decoration += "_SYST_LOWPT_DOWN"; break; + default: // Do nothing, we have the decoration already break; @@ -599,51 +835,103 @@ namespace top { // This should never happen throw std::runtime_error("Something has gone wrong in mu ID SF retrieval"); } - + + float ScaleFactorRetriever::softmuonSF_ID(const xAOD::Muon& x, + const top::topSFSyst SFSyst) const { + return softmuonSF_ID(x, m_config->softmuonQuality(), SFSyst); + } + + float ScaleFactorRetriever::softmuonSF_ID(const xAOD::Muon& x, + const std::string& id, + const top::topSFSyst SFSyst) const { + std::string decoration = "SOFTMU_SF_ID_" + id; + switch (SFSyst) { + case top::topSFSyst::MU_SF_ID_STAT_UP: + decoration += "_STAT_UP"; + break; + + case top::topSFSyst::MU_SF_ID_STAT_DOWN: + decoration += "_STAT_DOWN"; + break; + + case top::topSFSyst::MU_SF_ID_SYST_UP: + decoration += "_SYST_UP"; + break; + + case top::topSFSyst::MU_SF_ID_SYST_DOWN: + decoration += "_SYST_DOWN"; + break; + + case top::topSFSyst::MU_SF_ID_STAT_LOWPT_UP: + decoration += "_STAT_LOWPT_UP"; + break; + + case top::topSFSyst::MU_SF_ID_STAT_LOWPT_DOWN: + decoration += "_STAT_LOWPT_DOWN"; + break; + + case top::topSFSyst::MU_SF_ID_SYST_LOWPT_UP: + decoration += "_SYST_LOWPT_UP"; + break; + + case top::topSFSyst::MU_SF_ID_SYST_LOWPT_DOWN: + decoration += "_SYST_LOWPT_DOWN"; + break; + + default: + // Do nothing, we have the decoration already + break; + } + + return x.auxdataConst<float>(decoration); + + // This should never happen + throw std::runtime_error("Something has gone wrong in mu ID SF retrieval"); + } + float ScaleFactorRetriever::muonSF_Isol(const xAOD::Muon& x, const top::topSFSyst SFSyst, bool isLoose) const { - - return muonSF_Isol(x, (isLoose ? m_config->muonIsolationLoose() : m_config->muonIsolation()), SFSyst); + return muonSF_Isol(x, (isLoose ? m_config->muonIsolationSFLoose() : m_config->muonIsolationSF()), SFSyst, isLoose); } - float ScaleFactorRetriever::muonSF_Isol(const xAOD::Muon& x, const std::string& iso, - const top::topSFSyst SFSyst) const { - + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("MU_SF_Isol_"+iso)) { - sf = x.auxdataConst<float>("MU_SF_Isol_"+iso); + + std::string prefix="MU"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_Isol_" + iso)) { + sf = x.auxdataConst<float>(prefix+"_SF_Isol_" + iso); } if (SFSyst == top::topSFSyst::MU_SF_Isol_SYST_UP) { - - if (x.isAvailable<float>("MU_SF_Isol_"+iso+"_SYST_UP")) { - sf = x.auxdataConst<float>("MU_SF_Isol_"+iso+"_SYST_UP"); + if (x.isAvailable<float>(prefix+"_SF_Isol_" + iso + "_SYST_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_Isol_" + iso + "_SYST_UP"); } - } if (SFSyst == top::topSFSyst::MU_SF_Isol_SYST_DOWN) { - if (x.isAvailable<float>("MU_SF_Isol_"+iso+"_SYST_DOWN")) { - sf = x.auxdataConst<float>("MU_SF_Isol_"+iso+"_SYST_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_Isol_" + iso + "_SYST_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_Isol_" + iso + "_SYST_DOWN"); } } if (SFSyst == top::topSFSyst::MU_SF_Isol_STAT_UP) { - if (x.isAvailable<float>("MU_SF_Isol_"+iso+"_STAT_UP")) { - sf = x.auxdataConst<float>("MU_SF_Isol_"+iso+"_STAT_UP"); + if (x.isAvailable<float>(prefix+"_SF_Isol_" + iso + "_STAT_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_Isol_" + iso + "_STAT_UP"); } } if (SFSyst == top::topSFSyst::MU_SF_Isol_STAT_DOWN) { - if (x.isAvailable<float>("MU_SF_Isol_"+iso+"_STAT_DOWN")) { - sf = x.auxdataConst<float>("MU_SF_Isol_"+iso+"_STAT_DOWN"); + if (x.isAvailable<float>(prefix+"_SF_Isol_" + iso + "_STAT_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_Isol_" + iso + "_STAT_DOWN"); } } - return sf; } @@ -657,41 +945,46 @@ namespace top { **/ float ScaleFactorRetriever::muonSF_TTVA(const xAOD::Muon& x, const top::topSFSyst SFSyst) const { - // Nominal decoration: if not a TTVA // systematic then return the nominal std::string decoration = "MU_SF_TTVA"; + switch (SFSyst) { case top::topSFSyst::MU_SF_TTVA_STAT_UP: decoration += "_STAT_UP"; break; + case top::topSFSyst::MU_SF_TTVA_STAT_DOWN: decoration += "_STAT_DOWN"; break; + case top::topSFSyst::MU_SF_TTVA_SYST_UP: decoration += "_SYST_UP"; break; + case top::topSFSyst::MU_SF_TTVA_SYST_DOWN: decoration += "_SYST_DOWN"; break; + default: // Do nothing, we have the decoration already break; } if (!(x.isAvailable<float>(decoration))) { - std::cout << "Muon is not decorated with requested " - << "TTVA SF. 1.0 will be returned." << std::endl; + ATH_MSG_INFO("Muon is not decorated with requested TTVA SF. 1.0 will be returned."); return 1.0; } return x.auxdataConst<float>(decoration); + ; } float ScaleFactorRetriever::tauSF(const top::Event& event, const top::topSFSyst SFSyst) const { float sf(1.0); + for (auto tau : event.m_tauJets) sf *= tauSF(*tau, SFSyst, event.m_isLoose); return sf; @@ -701,97 +994,74 @@ namespace top { const top::topSFSyst SFSyst, bool isLoose) const { // See TauScaleFactorCalculator.cxx for uncertainties - static SG::AuxElement::ConstAccessor<float> acc_tauSF("tauSF"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_eleolr_total_up("tauSF_eleolr_total_up"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_eleolr_total_down("tauSF_eleolr_total_down"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_jetid_total_up("tauSF_jetid_total_up"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_jetid_total_down("tauSF_jetid_total_down"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_reco_total_up("tauSF_reco_total_up"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_reco_total_down("tauSF_reco_total_down"); - - static SG::AuxElement::ConstAccessor<float> acc_tauSF_loose("tauSF_loose"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_eleolr_total_up_loose("tauSF_eleolr_total_up_loose"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_eleolr_total_down_loose("tauSF_eleolr_total_down_loose"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_jetid_total_up_loose("tauSF_jetid_total_up_loose"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_jetid_total_down_loose("tauSF_jetid_total_down_loose"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_reco_total_up_loose("tauSF_reco_total_up_loose"); - static SG::AuxElement::ConstAccessor<float> acc_tauSF_reco_total_down_loose("tauSF_reco_total_down_loose"); + + static std::map<TString, const SG::AuxElement::ConstAccessor<float> > acc_tauSFs; + static std::map<TString, const SG::AuxElement::ConstAccessor<float> > acc_tauSFs_loose; if (!isLoose) { - switch (SFSyst) { - case top::topSFSyst::TAU_SF_ELEOLR_TOTAL_UP : - return acc_tauSF_eleolr_total_up(x); - case top::topSFSyst::TAU_SF_ELEOLR_TOTAL_DOWN : - return acc_tauSF_eleolr_total_down(x); - case top::topSFSyst::TAU_SF_JETID_TOTAL_UP : - return acc_tauSF_jetid_total_up(x); - case top::topSFSyst::TAU_SF_JETID_TOTAL_DOWN : - return acc_tauSF_jetid_total_down(x); - case top::topSFSyst::TAU_SF_RECO_TOTAL_UP : - return acc_tauSF_reco_total_up(x); - case top::topSFSyst::TAU_SF_RECO_TOTAL_DOWN : - return acc_tauSF_reco_total_down(x); - default : - // If not a tau systematic then return nominal SF - return acc_tauSF(x); - break; + if (tauSF_name.find(SFSyst) == tauSF_name.end()) { + if (acc_tauSFs.find(tauSF_name.at(top::topSFSyst::TAU_SF_NOMINAL)) == acc_tauSFs.end()) { + acc_tauSFs.insert(std::pair<TString, + const SG::AuxElement::ConstAccessor<float> > (tauSF_name.at(top::topSFSyst:: + TAU_SF_NOMINAL), + tauSF_name.at(top::topSFSyst:: + TAU_SF_NOMINAL).Data())); + } + return acc_tauSFs.at(tauSF_name.at(top::topSFSyst::TAU_SF_NOMINAL))(x); } + if (acc_tauSFs.find(tauSF_name.at(SFSyst)) == acc_tauSFs.end()) { + acc_tauSFs.insert(std::pair<TString, const SG::AuxElement::ConstAccessor<float> > (tauSF_name.at(SFSyst), + tauSF_name.at(SFSyst).Data())); + } + return acc_tauSFs.at(tauSF_name.at(SFSyst))(x); } else { - switch (SFSyst) { - case top::topSFSyst::TAU_SF_ELEOLR_TOTAL_UP : - return acc_tauSF_eleolr_total_up_loose(x); - case top::topSFSyst::TAU_SF_ELEOLR_TOTAL_DOWN : - return acc_tauSF_eleolr_total_down_loose(x); - case top::topSFSyst::TAU_SF_JETID_TOTAL_UP : - return acc_tauSF_jetid_total_up_loose(x); - case top::topSFSyst::TAU_SF_JETID_TOTAL_DOWN : - return acc_tauSF_jetid_total_down_loose(x); - case top::topSFSyst::TAU_SF_RECO_TOTAL_UP : - return acc_tauSF_reco_total_up_loose(x); - case top::topSFSyst::TAU_SF_RECO_TOTAL_DOWN : - return acc_tauSF_reco_total_down_loose(x); - default : - // If not a tau systematic then return nominal SF - return acc_tauSF_loose(x); - break; + if (tauSF_name.find(SFSyst) == tauSF_name.end()) { + if (acc_tauSFs_loose.find(tauSF_name.at(top::topSFSyst::TAU_SF_NOMINAL)) == acc_tauSFs_loose.end()) { + acc_tauSFs_loose.insert(std::pair<TString, + const SG::AuxElement::ConstAccessor<float> > (tauSF_name.at(top::topSFSyst:: + TAU_SF_NOMINAL) + + "_loose", + tauSF_name.at(top::topSFSyst:: + TAU_SF_NOMINAL).Data())); } + return acc_tauSFs_loose.at(tauSF_name.at(top::topSFSyst::TAU_SF_NOMINAL) + "_loose")(x); + } + if (acc_tauSFs_loose.find((tauSF_name.at(SFSyst) + "_loose")) == acc_tauSFs_loose.end()) { + acc_tauSFs_loose.insert(std::pair<TString, + const SG::AuxElement::ConstAccessor<float> > (tauSF_name.at(SFSyst) + "_loose", + (tauSF_name.at(SFSyst) + + "_loose").Data())); } + return acc_tauSFs_loose.at((tauSF_name.at(SFSyst) + "_loose"))(x); } + } float ScaleFactorRetriever::photonSF_Isol(const xAOD::Photon& x, - const top::topSFSyst SFSyst, - bool isLoose) const { - - return photonSF_Isol(x, (isLoose ? m_config->photonIsolationLoose() : m_config->photonIsolation()), SFSyst); - + const top::topSFSyst SFSyst, + bool isLoose) const { + return photonSF_Isol(x, (isLoose ? m_config->photonIsolationLoose() : m_config->photonIsolation()), SFSyst, isLoose); } float ScaleFactorRetriever::photonSF_Isol(const xAOD::Photon& x, - const std::string& iso, - const top::topSFSyst SFSyst) const { - + const std::string& iso, + const top::topSFSyst SFSyst, + bool isLoose) const { float sf(1.); - if (x.isAvailable<float>("PH_SF_Iso_" + iso)) { - sf = x.auxdataConst<float>("PH_SF_Iso_"+iso); - } - if (SFSyst == top::topSFSyst::PHOTON_EFF_LOWPTISO_UP) { - if (x.isAvailable<float>("PH_SF_Iso_"+iso+"_LOWPT_UP")) { - sf = x.auxdataConst<float>("PH_SF_Iso_"+iso+"_LOWPT_UP"); - } - } - if (SFSyst == top::topSFSyst::PHOTON_EFF_LOWPTISO_DOWN) { - if (x.isAvailable<float>("PH_SF_Iso_"+iso+"_LOWPT_DOWN")) { - sf = x.auxdataConst<float>("PH_SF_Iso_"+iso+"_LOWPT_DOWN"); - } + + std::string prefix="PH"; + if(isLoose) prefix+="_LOOSE"; + + if (x.isAvailable<float>(prefix+"_SF_Iso_" + iso)) { + sf = x.auxdataConst<float>(prefix+"_SF_Iso_" + iso); } - if (SFSyst == top::topSFSyst::PHOTON_EFF_LOWPTISO_UP) { - if (x.isAvailable<float>("PH_SF_Iso_"+iso+"_TRK_UP")) { - sf = x.auxdataConst<float>("PH_SF_Iso_"+iso+"_TRK_UP"); + if (SFSyst == top::topSFSyst::PHOTON_EFF_ISO_UP) { + if (x.isAvailable<float>(prefix+"_SF_Iso_" + iso + "_UP")) { + sf = x.auxdataConst<float>(prefix+"_SF_Iso_" + iso + "_UP"); } } - if (SFSyst == top::topSFSyst::PHOTON_EFF_LOWPTISO_DOWN) { - if (x.isAvailable<float>("PH_SF_Iso_"+iso+"_TRK_DOWN")) { - sf = x.auxdataConst<float>("PH_SF_Iso_"+iso+"_TRK_DOWN"); + if (SFSyst == top::topSFSyst::PHOTON_EFF_ISO_DOWN) { + if (x.isAvailable<float>(prefix+"_SF_Iso_" + iso + "_DOWN")) { + sf = x.auxdataConst<float>(prefix+"_SF_Iso_" + iso + "_DOWN"); } } return sf; @@ -799,68 +1069,90 @@ namespace top { float ScaleFactorRetriever::photonSF(const top::Event& event, const top::topSFSyst SFSyst) const { - float sf(1.0); - for (auto photon : event.m_photons) - sf *= photonSF(*photon, SFSyst, event.m_isLoose); + float sf(1.); + float reco(1.); + float isol(1.); + + for (auto photon : event.m_photons) { + reco *= photonSF_Reco(*photon, SFSyst); + isol *= photonSF_Isol(*photon, SFSyst, event.m_isLoose); + } + + sf = reco * isol; + return sf; } - float ScaleFactorRetriever::photonSF(const xAOD::Photon& photon, - const top::topSFSyst SFSyst, - bool isLoose) const { - - static SG::AuxElement::ConstAccessor<float> acc_ph_IDSF("EFF_ID_SF"); - static SG::AuxElement::ConstAccessor<float> acc_ph_IDSFUp("EFF_ID_SF_UP"); - static SG::AuxElement::ConstAccessor<float> acc_ph_IDSFDown("EFF_ID_SF_DOWN"); + float ScaleFactorRetriever::photonSF_Reco(const xAOD::Photon& photon, + const top::topSFSyst SFSyst) const { + static const SG::AuxElement::ConstAccessor<float> acc_ph_IDSF("EFF_ID_SF"); + static const SG::AuxElement::ConstAccessor<float> acc_ph_IDSFUp("EFF_ID_SF_UP"); + static const SG::AuxElement::ConstAccessor<float> acc_ph_IDSFDown("EFF_ID_SF_DOWN"); switch (SFSyst) { case top::topSFSyst::nominal: return acc_ph_IDSF(photon); + case top::topSFSyst::PHOTON_IDSF_UP: return acc_ph_IDSFUp(photon); + case top::topSFSyst::PHOTON_IDSF_DOWN: return acc_ph_IDSFDown(photon); + default: - return photonSF_Isol(photon, SFSyst, isLoose); + return acc_ph_IDSF(photon); } } - + /** - * @brief nominal SF or named systematics - */ + * @brief nominal SF or named systematics + */ float ScaleFactorRetriever::btagSF(const top::Event& event, const top::topSFSyst SFSyst, std::string WP, bool do_trackjets, std::string uncert_name) const { float sf(1.); - std::string decoration = "btag_SF_"+WP+"_nom"; + std::string decoration = "btag_SF_" + WP + "_nom"; + std::string systematicName, bTagSystName; switch (SFSyst) { - case top::topSFSyst::nominal : - break; // is btag_SF_nom by default - case top::topSFSyst::BTAG_SF_NAMED_UP : - if (uncert_name=="") { - std::cout << "Named b-tagging systematics should have a name. Please provide one." << std::endl; + case top::topSFSyst::nominal: + // If this is the nominal tree, we proceed as normal + // If not nominal tree, we need to know which systematic this event corresponds to, + // in case the systematic is removed from EV decomposition (will enter as a nominal retrieval) + systematicName = m_config->systematicName(event.m_hashValue); + bTagSystName = top::bTagNamedSystCheck(m_config, systematicName, WP, do_trackjets, false); + if (bTagSystName != "") decoration = "btag_SF_" + WP + "_" + bTagSystName; // Only change decoration if found, + // otherwise we will use the nominal + break; + + case top::topSFSyst::BTAG_SF_NAMED_UP: + if (uncert_name == "") { + ATH_MSG_INFO("Named b-tagging systematics should have a name. Please provide one."); return 0; } - decoration = "btag_SF_"+WP+"_"+uncert_name+"__1up"; + decoration = "btag_SF_" + WP + "_" + uncert_name + "__1up"; break; - case top::topSFSyst::BTAG_SF_NAMED_DOWN : - if (uncert_name=="") { - std::cout << "Named b-tagging systematics should have a name. Please provide one." << std::endl; + + case top::topSFSyst::BTAG_SF_NAMED_DOWN: + if (uncert_name == "") { + ATH_MSG_INFO("Named b-tagging systematics should have a name. Please provide one."); return 0; } - decoration = "btag_SF_"+WP+"_"+uncert_name+"__1down"; + decoration = "btag_SF_" + WP + "_" + uncert_name + "__1down"; break; - case top::topSFSyst::BTAG_SF_EIGEN_B : - case top::topSFSyst::BTAG_SF_EIGEN_C : - case top::topSFSyst::BTAG_SF_EIGEN_LIGHT : - std::cout << "For Eigenvectors please use ScaleFactorRetriever::btagSF_eigen_vars" << std::endl; + + case top::topSFSyst::BTAG_SF_EIGEN_B: + case top::topSFSyst::BTAG_SF_EIGEN_C: + case top::topSFSyst::BTAG_SF_EIGEN_LIGHT: + ATH_MSG_INFO("For Eigenvectors please use ScaleFactorRetriever::btagSF_eigen_vars"); return 0; + break; - default : - std::cout << "Not the right function: " - << __PRETTY_FUNCTION__ << std::endl; + + default: + ATH_MSG_INFO("Not the right function: " << __PRETTY_FUNCTION__); return 0; + break; } @@ -868,13 +1160,10 @@ namespace top { xAOD::JetContainer jets = event.m_jets; if (do_trackjets) jets = event.m_trackJets; for (auto jetPtr : jets) { - double weight = 1.0; - if (jetPtr -> isAvailable<float>(decoration)) - weight = jetPtr -> auxdataConst<float>(decoration); + if (jetPtr->isAvailable<float>(decoration)) weight = jetPtr->auxdataConst<float>(decoration); sf *= weight; - } // for now @@ -886,31 +1175,33 @@ namespace top { std::vector<float>& vec_btagSF_up, std::vector<float>& vec_btagSF_down, std::string WP, bool do_trackjets) const { - // just in case vec_btagSF_up.clear(); vec_btagSF_down.clear(); unsigned int n_eigen = 0; - std::string prefix = "btag_SF_"+WP+"_FT_EFF_Eigen_"; + std::string prefix = "btag_SF_" + WP + "_FT_EFF_Eigen_"; std::string flav = ""; switch (SFSyst) { - case top::topSFSyst::BTAG_SF_EIGEN_B : - n_eigen = do_trackjets ? m_config-> trkjet_btagging_num_B_eigenvars(WP) : m_config->btagging_num_B_eigenvars(WP); + case top::topSFSyst::BTAG_SF_EIGEN_B: + n_eigen = do_trackjets ? m_config->trkjet_btagging_num_B_eigenvars(WP) : m_config->btagging_num_B_eigenvars(WP); flav = "B_"; break; - case top::topSFSyst::BTAG_SF_EIGEN_C : - n_eigen = do_trackjets ? m_config-> trkjet_btagging_num_C_eigenvars(WP) : m_config->btagging_num_C_eigenvars(WP); + + case top::topSFSyst::BTAG_SF_EIGEN_C: + n_eigen = do_trackjets ? m_config->trkjet_btagging_num_C_eigenvars(WP) : m_config->btagging_num_C_eigenvars(WP); flav = "C_"; break; - case top::topSFSyst::BTAG_SF_EIGEN_LIGHT : - n_eigen = do_trackjets ? m_config-> trkjet_btagging_num_Light_eigenvars(WP) : m_config->btagging_num_Light_eigenvars(WP); + + case top::topSFSyst::BTAG_SF_EIGEN_LIGHT: + n_eigen = + do_trackjets ? m_config->trkjet_btagging_num_Light_eigenvars(WP) : m_config->btagging_num_Light_eigenvars(WP); flav = "Light_"; break; - default : - std::cout << "Not the right function: " - << __PRETTY_FUNCTION__ << std::endl; + + default: + ATH_MSG_INFO("Not the right function: " << __PRETTY_FUNCTION__); return; } vec_btagSF_up.resize(n_eigen); @@ -919,49 +1210,60 @@ namespace top { for (unsigned int i = 0; i < n_eigen; ++i) { float SF_up(1.0), SF_down(1.0); std::string num = std::to_string(i); - std::string SF_dec_up = prefix+flav+num+"__1up"; - std::string SF_dec_down = prefix+flav+num+"__1down"; + std::string SF_dec_up = prefix + flav + num + "__1up"; + std::string SF_dec_down = prefix + flav + num + "__1down"; xAOD::JetContainer jets = event.m_jets; if (do_trackjets) jets = event.m_trackJets; for (auto jetPtr : jets) { - if (jetPtr->isAvailable<float>(SF_dec_up)) - SF_up *= jetPtr->auxdataConst<float>(SF_dec_up); - if (jetPtr->isAvailable<float>(SF_dec_down)) - SF_down *= jetPtr->auxdataConst<float>(SF_dec_down); + if (jetPtr->isAvailable<float>(SF_dec_up)) SF_up *= jetPtr->auxdataConst<float>(SF_dec_up); + if (jetPtr->isAvailable<float>(SF_dec_down)) SF_down *= jetPtr->auxdataConst<float>(SF_dec_down); } vec_btagSF_up[i] = SF_up; vec_btagSF_down[i] = SF_down; - } return; } float ScaleFactorRetriever::jvtSF(const top::Event& event, const top::topSFSyst SFSyst) const { - xAOD::JetContainer jets = event.m_jets; switch (SFSyst) { case top::topSFSyst::JVT_UP: return event.m_jvtSF_UP; + case top::topSFSyst::JVT_DOWN: return event.m_jvtSF_DOWN; + default: return event.m_jvtSF; } + } + float ScaleFactorRetriever::fjvtSF(const top::Event& event, + const top::topSFSyst SFSyst) const { + xAOD::JetContainer jets = event.m_jets; + switch (SFSyst) { + case top::topSFSyst::FJVT_UP: + return event.m_fjvtSF_UP; + + case top::topSFSyst::FJVT_DOWN: + return event.m_fjvtSF_DOWN; + + default: + return event.m_fjvtSF; + } } /** - * @brief Print all the SF values to cout - */ + * @brief Print all the SF values to msg stream + */ void ScaleFactorRetriever::print(const top::Event& event) { - std::cout << "ScaleFactors" << "\n"; - std::cout << " MCEventWeight : " << event.m_info->mcEventWeight() << "\n"; - std::cout << " Pileup : " << pileupSF(event) << "\n"; - std::cout << " LeptonEventWeight : " << leptonSF(event, top::topSFSyst::nominal) << "\n"; - std::cout << " B-TagEventWeight : " << btagSF(event, top::topSFSyst::nominal) << "\n"; + ATH_MSG_INFO("ScaleFactors"); + ATH_MSG_INFO(" MCEventWeight : " << + std::to_string(event.m_info->auxdataConst<float>("AnalysisTop_eventWeight"))); + ATH_MSG_INFO(" Pileup : " << std::to_string(pileupSF(event))); + ATH_MSG_INFO(" LeptonEventWeight : " << std::to_string(leptonSF(event, top::topSFSyst::nominal))); + ATH_MSG_INFO(" B-TagEventWeight : " << std::to_string(btagSF(event, top::topSFSyst::nominal))); } - - } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/TauScaleFactorCalculator.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/TauScaleFactorCalculator.cxx index 03ce54848f66..3484f4d583a9 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/TauScaleFactorCalculator.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/TauScaleFactorCalculator.cxx @@ -1,8 +1,8 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ -// $Id: TauScaleFactorCalculator.cxx 712396 2015-12-03 16:25:25Z tneep $ +// $Id: TauScaleFactorCalculator.cxx 805414 2017-05-24 12:21:29Z yili $ #include <string> #include "TopCorrections/TauScaleFactorCalculator.h" @@ -10,132 +10,118 @@ #include "TopEvent/EventTools.h" #include "xAODTau/TauJetContainer.h" +#include "TopCorrections/ScaleFactorRetriever.h" namespace top { + TauScaleFactorCalculator::TauScaleFactorCalculator(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), + m_tauEffCorrTool("TauAnalysisTools::TauEfficiencyCorrectionsTool"), + m_tauEffCorrToolLoose("TauAnalysisTools::TauEfficiencyCorrectionsToolLoose"), + + m_systNominal(CP::SystematicSet()) { + declareProperty("config", m_config); + } -TauScaleFactorCalculator::TauScaleFactorCalculator(const std::string& name) : - asg::AsgTool(name), - m_config(nullptr), - m_tauEffCorrTool("TauAnalysisTools::TauEfficiencyCorrectionsTool"), - m_tauEffCorrToolLoose("TauAnalysisTools::TauEfficiencyCorrectionsToolLoose"), - - m_systNominal(CP::SystematicSet()) { - declareProperty("config" , m_config); -} - -StatusCode TauScaleFactorCalculator::initialize() { - ATH_MSG_INFO(" top::TauScaleFactorCalculator initialize"); - - top::check(m_tauEffCorrTool.retrieve(), - "Failed to retrieve tau efficiency corrections tool"); - - // How to get the recommended/affecting systematics... - // CP::SystematicSet m_syst_rec = m_tauEffCorrTool->recommendedSystematics(); - // CP::SystematicSet m_syst_aff = m_tauEffCorrTool->affectingSystematics(); - - const std::string tauSysPrefix = "TAUS_TRUEHADTAU_EFF_"; - // Should be empty- but lets be sure - m_syst_map.clear(); - // Add all recommended systematics to be clear - // Tau-electron overlap removal up/down - m_syst_map["tauSF_eleolr_total_down"] - = CP::SystematicSet(tauSysPrefix+"ELEOLR_TOTAL__1down"); - m_syst_map["tauSF_eleolr_total_up"] - = CP::SystematicSet(tauSysPrefix+"ELEOLR_TOTAL__1up"); - // Tau Jet ID WP up/down - m_syst_map["tauSF_jetid_total_down"] - = CP::SystematicSet(tauSysPrefix+"JETID_TOTAL__1down"); - m_syst_map["tauSF_jetid_total_up"] - = CP::SystematicSet(tauSysPrefix+"JETID_TOTAL__1up"); - // Tau reconstruction up/down - m_syst_map["tauSF_reco_total_down"] - = CP::SystematicSet(tauSysPrefix+"RECO_TOTAL__1down"); - m_syst_map["tauSF_reco_total_up"] - = CP::SystematicSet(tauSysPrefix+"RECO_TOTAL__1up"); - - return StatusCode::SUCCESS; -} - - -StatusCode TauScaleFactorCalculator::execute() { - ///-- Loop over all muon collections --/// - for (auto currentSystematic : *m_config->systSgKeyMapTaus()) { - const xAOD::TauJetContainer* taus(nullptr); - top::check(evtStore()->retrieve(taus, currentSystematic.second), - "failed to retrieve taus"); - - ///-- Tell the SF tools to use the nominal systematic --/// - - /// -- Loop over all taus in each collection --/// - for (auto tauPtr : *taus) { - /// -- Does the tau pass object selection? --/// - bool passSelection(false); - if (tauPtr->isAvailable<char>("passPreORSelection")) { - if (tauPtr->auxdataConst<char>("passPreORSelection") == 1) { - passSelection = true; - } - } - if (tauPtr->isAvailable<char>("passPreORSelectionLoose")) { - if (tauPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) { - passSelection = true; - } - } + StatusCode TauScaleFactorCalculator::initialize() { + ATH_MSG_INFO(" top::TauScaleFactorCalculator initialize"); - ///-- If we aren't selecting the tau, then don't bother --/// - if (!passSelection) continue; - - //============================================================ - // Find the nominal SF for the tight/loose tau IDs for every - // systematic uncertainty. - // - // Make sure we set both tools to nominal for each tau - //============================================================ - - top::check(m_tauEffCorrTool->applySystematicVariation(m_systNominal), - "Failed to set tau efficiency correction" - " tool to nominal value"); - top::check(m_tauEffCorrToolLoose->applySystematicVariation(m_systNominal), - "Failed to set (loose) tau efficiency correction" - " tool to nominal value"); - - double nominalSF(0.0), nominalSFLoose(0.0); - - top::check(m_tauEffCorrTool->getEfficiencyScaleFactor(*tauPtr, nominalSF), - "Failed to get nominal tau SF"); - top::check(m_tauEffCorrToolLoose->getEfficiencyScaleFactor(*tauPtr, - nominalSFLoose), - "Failed to get nominal (loose) tau SF"); - - ///-- Decorate the tau with the tight/loose SFs --/// - tauPtr->auxdecor<float>("tauSF") = nominalSF; - tauPtr->auxdecor<float>("tauSF_loose") = nominalSFLoose; - - ///-- For nominal calibration, vary the SF systematics --/// - if (currentSystematic.first == m_config->nominalHashValue()) { - for (const auto& i : m_syst_map) { - double SF(0.0), SF_loose(0.0); - const std::string decoration_name = i.first; - const std::string decoration_name_loose = i.first+"_loose"; - top::check(m_tauEffCorrTool->applySystematicVariation(i.second), - "Failed to set tau efficiency correction" - " tool to nominal value"); - top::check(m_tauEffCorrToolLoose->applySystematicVariation(i.second), - "Failed to set (loose) tau efficiency correction" - " tool to nominal value"); - top::check(m_tauEffCorrTool->getEfficiencyScaleFactor(*tauPtr, SF), - "Failed to get nominal tau SF"); - top::check(m_tauEffCorrToolLoose->getEfficiencyScaleFactor(*tauPtr, - SF_loose), - "Failed to get nominal (loose) tau SF"); - tauPtr->auxdecor<float>(decoration_name) = SF; - tauPtr->auxdecor<float>(decoration_name_loose) = SF_loose; - } - } // Calibration systematic is nominal, so calculate SF systematics + top::check(m_tauEffCorrTool.retrieve(), + "Failed to retrieve tau efficiency corrections tool"); + + // How to get the recommended/affecting systematics... + // Should be empty- but lets be sure + m_syst_map.clear(); + // Add all recommended systematics to be clear + // Tau-electron overlap removal up/down, true hadtau + + for (auto tauSFpair : top::tauSF_name) { + if (m_config->tauSFDoRNNID() == false && tauSFpair.second.Contains("RNN")) continue; + if (m_config->tauSFDoBDTID() == false && tauSFpair.second.Contains("JETID")) continue; + m_syst_map[tauSFpair.second.Data()] = CP::SystematicSet(tauSFpair.second.Data()); } + + return StatusCode::SUCCESS; } + StatusCode TauScaleFactorCalculator::execute() { + ///-- Loop over all muon collections --/// + for (auto currentSystematic : *m_config->systSgKeyMapTaus()) { + const xAOD::TauJetContainer* taus(nullptr); + top::check(evtStore()->retrieve(taus, currentSystematic.second), + "failed to retrieve taus"); + + ///-- Tell the SF tools to use the nominal systematic --/// + + /// -- Loop over all taus in each collection --/// + for (auto tauPtr : *taus) { + /// -- Does the tau pass object selection? --/// + bool passSelection(false); + if (tauPtr->isAvailable<char>("passPreORSelection")) { + if (tauPtr->auxdataConst<char>("passPreORSelection") == 1) { + passSelection = true; + } + } + if (tauPtr->isAvailable<char>("passPreORSelectionLoose")) { + if (tauPtr->auxdataConst<char>("passPreORSelectionLoose") == 1) { + passSelection = true; + } + } + + ///-- If we aren't selecting the tau, then don't bother --/// + if (!passSelection) continue; + + //============================================================ + // Find the nominal SF for the tight/loose tau IDs for every + // systematic uncertainty. + // + // Make sure we set both tools to nominal for each tau + //============================================================ + + top::check(m_tauEffCorrTool->applySystematicVariation(m_systNominal), + "Failed to set tau efficiency correction" + " tool to nominal value"); + top::check(m_tauEffCorrToolLoose->applySystematicVariation(m_systNominal), + "Failed to set (loose) tau efficiency correction" + " tool to nominal value"); + + double nominalSF(0.0), nominalSFLoose(0.0); + + top::check(m_tauEffCorrTool->getEfficiencyScaleFactor(*tauPtr, nominalSF), + "Failed to get nominal tau SF"); + top::check(m_tauEffCorrToolLoose->getEfficiencyScaleFactor(*tauPtr, + nominalSFLoose), + "Failed to get nominal (loose) tau SF"); + + ///-- Decorate the tau with the tight/loose SFs --/// + tauPtr->auxdecor<float>("TAU_SF_NOMINAL") = nominalSF; + tauPtr->auxdecor<float>("TAU_SF_NOMINAL_loose") = nominalSFLoose; + + ///-- For nominal calibration, vary the SF systematics --/// + if (currentSystematic.first == m_config->nominalHashValue()) { + for (const auto& i : m_syst_map) { + double SF(0.0), SF_loose(0.0); + const std::string decoration_name = i.first; + const std::string decoration_name_loose = i.first + "_loose"; + top::check(m_tauEffCorrTool->applySystematicVariation(i.second), + "Failed to set tau efficiency correction" + " tool to nominal value"); + top::check(m_tauEffCorrToolLoose->applySystematicVariation(i.second), + "Failed to set (loose) tau efficiency correction" + " tool to nominal value"); + top::check(m_tauEffCorrTool->getEfficiencyScaleFactor(*tauPtr, SF), + "Failed to get nominal tau SF"); + top::check(m_tauEffCorrToolLoose->getEfficiencyScaleFactor(*tauPtr, + SF_loose), + "Failed to get nominal (loose) tau SF"); + tauPtr->auxdecor<float>(decoration_name) = SF; + tauPtr->auxdecor<float>(decoration_name_loose) = SF_loose; + } + } // Calibration systematic is nominal, so calculate SF systematics + } + } - return StatusCode::SUCCESS; -} + return StatusCode::SUCCESS; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/TopCorrectionsTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/TopCorrectionsTools.cxx new file mode 100644 index 000000000000..6044afeb2ea8 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/Root/TopCorrectionsTools.cxx @@ -0,0 +1,62 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopCorrections/TopCorrectionsTools.h" +#include <iostream> + +#include "TopCorrections/MsgCategory.h" +using namespace TopCorrections; + +namespace top { + // B-tagging naming tool + std::string bTagNamedSystCheck(std::shared_ptr<top::TopConfig> config, + const std::string& systCollection, + const std::string& tagWP, + const bool isTrackJet, + const bool verbose = false) { + // TODO -- to be reworked to use new message level settings to be implemented + if (verbose) ATH_MSG_INFO("Searching for " << systCollection << " for WP " << tagWP); + if (isTrackJet) { + for (const std::string& name : config->trkjet_btagging_namedSysts(tagWP)) { + if (verbose) ATH_MSG_INFO("...Possible matches : "); + if (systCollection.find(betterBtagNamedSyst(name)) != std::string::npos) { + if (verbose) ATH_MSG_INFO("......Matched!"); + if (systCollection.find("up") != std::string::npos) return name + "__1up"; + else if (systCollection.find("down") != std::string::npos) return name + "__1down"; + else return name; + } + } + } else { + for (const std::string& name : config->btagging_namedSysts(tagWP)) { + if (verbose) ATH_MSG_INFO("...Possible matches : "); + if (systCollection.find(betterBtagNamedSyst(name)) != std::string::npos) { + if (verbose) ATH_MSG_INFO("......Matched!"); + if (systCollection.find("up") != std::string::npos) return name + "__1up"; + else if (systCollection.find("down") != std::string::npos) return name + "__1down"; + else return name; + } + } + } + return ""; + } + + // B-tagging naming tool + std::string betterBtagNamedSyst(const std::string& name) { + // remove "FT_EFF_", spaces, and "-" in named systematics + std::string str = "FT_EFF_"; + std::string out = name; + if (out.find(str) != std::string::npos) { + out.replace(out.find(str), str.length(), ""); + } + str = " "; + while (out.find(str) != std::string::npos) { + out.replace(out.find(str), str.length(), "_"); + } + str = "-"; + while (out.find(str) != std::string::npos) { + out.replace(out.find(str), str.length(), "_"); + } + return out; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/BTagScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/BTagScaleFactorCalculator.h index 41fc0f4ae4c3..a16c8ead2ce4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/BTagScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/BTagScaleFactorCalculator.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -// $Id: BTagScaleFactorCalculator.h 754162 2016-06-10 15:01:10Z tpelzer $ +// $Id: BTagScaleFactorCalculator.h 807496 2017-06-28 14:52:29Z iconnell $ #ifndef ANALYSISTOP_TOPCORRECTIONS_BTAGSCALEFACTORCALCULATOR_H #define ANALYSISTOP_TOPCORRECTIONS_BTAGSCALEFACTORCALCULATOR_H /** - * @author Andrea Knue <aknue@cern.ch>, John Morris <john.morris@cern.ch> - * - * @brief BTagScaleFactorCalculator - * Calculate all jet scale factors and decorate - * - * $Revision: - * $Date: 2016-06-10 17:01:10 +0200 (Fri, 10 Jun 2016) $ - * - **/ + * @author Andrea Knue <aknue@cern.ch>, John Morris <john.morris@cern.ch> + * + * @brief BTagScaleFactorCalculator + * Calculate all jet scale factors and decorate + * + * $Revision: + * $Date: 2017-06-28 15:52:29 +0100 (Wed, 28 Jun 2017) $ + * + **/ // system include(s): #include <memory> @@ -27,48 +27,45 @@ // Systematic include(s): #include "PATInterfaces/SystematicSet.h" -#include "xAODBTaggingEfficiency/IBTaggingEfficiencyTool.h" -#include "xAODBTaggingEfficiency/IBTaggingSelectionTool.h" +#include "FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h" +#include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class BTagScaleFactorCalculator final : public asg::AsgTool { - public: - explicit BTagScaleFactorCalculator( const std::string& name ); - virtual ~BTagScaleFactorCalculator(){} - - // Delete Standard constructors - BTagScaleFactorCalculator(const BTagScaleFactorCalculator& rhs) = delete; - BTagScaleFactorCalculator(BTagScaleFactorCalculator&& rhs) = delete; - BTagScaleFactorCalculator& operator=(const BTagScaleFactorCalculator& rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - StatusCode apply( const std::shared_ptr<std::unordered_map<std::size_t,std::string>>& jet_syst_collections, - bool use_trackjets = false); - - private: - - std::shared_ptr<top::TopConfig> m_config; - - CP::SystematicSet m_nominal; - std::unordered_map<std::string, CP::SystematicSet> m_systs; - std::unordered_map<std::string, CP::SystematicSet> m_trkjet_systs; - - ///B-tagging efficiency tools - std::unordered_map<std::string, ToolHandle<IBTaggingEfficiencyTool>> m_btagEffTools; - std::unordered_map<std::string, ToolHandle<IBTaggingEfficiencyTool>> m_trkjet_btagEffTools; - ///B-tagging selection tools - std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool>> m_btagSelTools; - std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool>> m_trkjet_btagSelTools; - - int m_release_series = 24; // Default to 2.4 - +namespace top { + class BTagScaleFactorCalculator final: public asg::AsgTool { + public: + explicit BTagScaleFactorCalculator(const std::string& name); + virtual ~BTagScaleFactorCalculator() {} + + // Delete Standard constructors + BTagScaleFactorCalculator(const BTagScaleFactorCalculator& rhs) = delete; + BTagScaleFactorCalculator(BTagScaleFactorCalculator&& rhs) = delete; + BTagScaleFactorCalculator& operator = (const BTagScaleFactorCalculator& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(); + StatusCode apply(const std::shared_ptr<std::unordered_map<std::size_t, std::string> >& jet_syst_collections, + bool use_trackjets = false); + + // Function to print out information about internal tools + StatusCode debug(); + private: + std::shared_ptr<top::TopConfig> m_config; + + CP::SystematicSet m_nominal; + std::unordered_map<std::string, CP::SystematicSet> m_systs; + std::unordered_map<std::string, CP::SystematicSet> m_trkjet_systs; + + ///B-tagging efficiency tools + std::unordered_map<std::string, ToolHandle<IBTaggingEfficiencyTool> > m_btagEffTools; + std::unordered_map<std::string, ToolHandle<IBTaggingEfficiencyTool> > m_trkjet_btagEffTools; + ///B-tagging selection tools + std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool> > m_btagSelTools; + std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool> > m_trkjet_btagSelTools; }; } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ElectronScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ElectronScaleFactorCalculator.h index 79984a325cf3..eba7b226cb6e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ElectronScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ElectronScaleFactorCalculator.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: ElectronScaleFactorCalculator.h 799556 2017-03-05 19:46:03Z tpelzer $ #ifndef ANALYSISTOP_TOPCORRECTIONS_ELECTRONSCALEFACTORCALCULATOR_H #define ANALYSISTOP_TOPCORRECTIONS_ELECTRONSCALEFACTORCALCULATOR_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief ElectronScaleFactorCalculator - * Calculate all electron scale factors and decorate - * - * $Revision: 799556 $ - * $Date: 2017-03-05 20:46:03 +0100 (Sun, 05 Mar 2017) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief ElectronScaleFactorCalculator + * Calculate all electron scale factors and decorate + * + * $Revision: 799556 $ + * $Date: 2017-03-05 19:46:03 +0000 (Sun, 05 Mar 2017) $ + * + **/ // system include(s): #include <memory> @@ -27,85 +27,100 @@ // Systematic include(s): #include "PATInterfaces/SystematicSet.h" +#include "PATInterfaces/SystematicsUtil.h" // CP Tool include(s): -#include "ElectronEfficiencyCorrection/IAsgElectronEfficiencyCorrectionTool.h" +#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h" #include "ElectronEfficiencyCorrection/ElectronChargeEfficiencyCorrectionTool.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class ElectronScaleFactorCalculator final : public asg::AsgTool { - public: - explicit ElectronScaleFactorCalculator( const std::string& name ); - virtual ~ElectronScaleFactorCalculator(){} - - // Delete Standard constructors - ElectronScaleFactorCalculator(const ElectronScaleFactorCalculator& rhs) = delete; - ElectronScaleFactorCalculator(ElectronScaleFactorCalculator&& rhs) = delete; - ElectronScaleFactorCalculator& operator=(const ElectronScaleFactorCalculator& rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - CP::SystematicSet m_systNominal; - CP::SystematicSet m_systTrigger_UP; - CP::SystematicSet m_systTrigger_DOWN; - CP::SystematicSet m_systReco_UP; - CP::SystematicSet m_systReco_DOWN; - CP::SystematicSet m_systID_UP; - CP::SystematicSet m_systID_DOWN; - CP::SystematicSet m_systIso_UP; - CP::SystematicSet m_systIso_DOWN; - CP::SystematicSet m_systChargeID_UP; - CP::SystematicSet m_systChargeID_DOWN; - CP::SystematicSet m_systChargeMisID_STAT_UP; - CP::SystematicSet m_systChargeMisID_STAT_DOWN; - CP::SystematicSet m_systChargeMisID_SYST_UP; - CP::SystematicSet m_systChargeMisID_SYST_DOWN; - - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTrigger; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTriggerLoose; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTrigger; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTriggerLoose; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFReco; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFID; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDLoose; - - bool m_electronEffIso_exists; - bool m_electronEffIsoLoose_exists; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIso; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIsoLoose; - bool m_electronEffChargeID_exists; - bool m_electronEffChargeIDLoose_exists; - bool m_electronEffChargeMisID_exists; - bool m_electronEffChargeMisIDLoose_exists; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFChargeID; - ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFChargeIDLoose; - ToolHandle<CP::ElectronChargeEfficiencyCorrectionTool> m_electronEffSFChargeMisID; - ToolHandle<CP::ElectronChargeEfficiencyCorrectionTool> m_electronEffSFChargeMisIDLoose; - - std::string m_decor_triggerEff; - std::string m_decor_triggerEff_loose; - std::string m_decor_triggerSF; - std::string m_decor_triggerSF_loose; - std::string m_decor_recoSF; - std::string m_decor_idSF; - std::string m_decor_idSF_loose; - std::string m_decor_isoSF; - std::string m_decor_isoSF_loose; - std::string m_decor_chargeidSF; - std::string m_decor_chargeidSF_loose; - std::string m_decor_chargemisidSF; - std::string m_decor_chargemisidSF_loose; +namespace top { + class ElectronScaleFactorCalculator final: public asg::AsgTool { + public: + explicit ElectronScaleFactorCalculator(const std::string& name); + virtual ~ElectronScaleFactorCalculator() {} + // Delete Standard constructors + ElectronScaleFactorCalculator(const ElectronScaleFactorCalculator& rhs) = delete; + ElectronScaleFactorCalculator(ElectronScaleFactorCalculator&& rhs) = delete; + ElectronScaleFactorCalculator& operator = (const ElectronScaleFactorCalculator& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(); + private: + std::shared_ptr<top::TopConfig> m_config; + + CP::SystematicSet m_systNominal; + CP::SystematicSet m_systTrigger_UP; + CP::SystematicSet m_systTrigger_DOWN; + CP::SystematicSet m_systReco_UP; + CP::SystematicSet m_systReco_DOWN; + CP::SystematicSet m_systID_UP; + CP::SystematicSet m_systID_DOWN; + CP::SystematicSet m_systIso_UP; + CP::SystematicSet m_systIso_DOWN; + CP::SystematicSet m_systChargeID_UP; + CP::SystematicSet m_systChargeID_DOWN; + CP::SystematicSet m_systChargeMisID_STAT_UP; + CP::SystematicSet m_systChargeMisID_STAT_DOWN; + CP::SystematicSet m_systChargeMisID_SYST_UP; + CP::SystematicSet m_systChargeMisID_SYST_DOWN; + + std::vector<CP::SystematicSet> m_systTriggerCorrModel; + std::vector<CP::SystematicSet> m_systRecoCorrModel; + std::vector<CP::SystematicSet> m_systIDCorrModel; + std::vector<CP::SystematicSet> m_systIsoCorrModel; + + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTrigger; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTriggerLoose; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTrigger; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTriggerLoose; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFReco; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFID; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDLoose; + + bool m_electronEffIso_exists; + bool m_electronEffIsoLoose_exists; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIso; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIsoLoose; + + + bool m_electronEffChargeID_exists; + bool m_electronEffChargeIDLoose_exists; + bool m_electronEffChargeMisID_exists; + bool m_electronEffChargeMisIDLoose_exists; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFChargeID; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFChargeIDLoose; + ToolHandle<CP::ElectronChargeEfficiencyCorrectionTool> m_electronEffSFChargeMisID; + ToolHandle<CP::ElectronChargeEfficiencyCorrectionTool> m_electronEffSFChargeMisIDLoose; + + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTriggerCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFTriggerLooseCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTriggerCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffTriggerLooseCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFRecoCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDLooseCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIsoCorrModel; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIsoLooseCorrModel; + + std::string m_decor_triggerEff; + std::string m_decor_triggerEff_loose; + std::string m_decor_triggerSF; + std::string m_decor_triggerSF_loose; + std::string m_decor_recoSF; + std::string m_decor_idSF; + std::string m_decor_idSF_loose; + std::string m_decor_isoSF; + std::string m_decor_isoSF_loose; + std::string m_decor_chargeidSF; + std::string m_decor_chargeidSF_loose; + std::string m_decor_chargemisidSF; + std::string m_decor_chargemisidSF_loose; }; } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/FwdElectronScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/FwdElectronScaleFactorCalculator.h new file mode 100644 index 000000000000..456968746811 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/FwdElectronScaleFactorCalculator.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPCORRECTIONS_FWDELECTRONSCALEFACTORCALCULATOR_H +#define ANALYSISTOP_TOPCORRECTIONS_FWDELECTRONSCALEFACTORCALCULATOR_H + +/** + * @author Marco Vanadia <marco.vanadia@cern.ch> + * + * @brief FwdElectronScaleFactorCalculator + * Calculate all forward electron scale factors and decorate + * + **/ + +// system include(s): +#include <memory> +#include <set> + +// Framework include(s): +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +// Systematic include(s): +#include "PATInterfaces/SystematicSet.h" + +// CP Tool include(s): +#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h" +#include "ElectronEfficiencyCorrection/ElectronChargeEfficiencyCorrectionTool.h" + +// Forward declaration(s): +namespace top { + class TopConfig; +} + +namespace top { + class FwdElectronScaleFactorCalculator final: public asg::AsgTool { + public: + explicit FwdElectronScaleFactorCalculator(const std::string& name); + virtual ~FwdElectronScaleFactorCalculator() {} + + // Delete Standard constructors + FwdElectronScaleFactorCalculator(const FwdElectronScaleFactorCalculator& rhs) = delete; + FwdElectronScaleFactorCalculator(FwdElectronScaleFactorCalculator&& rhs) = delete; + FwdElectronScaleFactorCalculator& operator = (const FwdElectronScaleFactorCalculator& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(); + private: + std::shared_ptr<top::TopConfig> m_config; + + CP::SystematicSet m_systNominal; + CP::SystematicSet m_systID_UP; + CP::SystematicSet m_systID_DOWN; + + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFID; + ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_electronEffSFIDLoose; + + std::string m_decor_idSF; + std::string m_decor_idSF_loose; + }; +} // namespace +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/GlobalLeptonTriggerCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/GlobalLeptonTriggerCalculator.h new file mode 100644 index 000000000000..94acaae813be --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/GlobalLeptonTriggerCalculator.h @@ -0,0 +1,68 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +// $Id: GlobalLeptonTriggerCalculator.h 799556 2017-03-05 19:46:03Z tpelzer $ +#ifndef ANALYSISTOP_TOPCORRECTIONS_GLOBALLEPTONTRIGGERCALCULATOR_H +#define ANALYSISTOP_TOPCORRECTIONS_GLOBALLEPTONTRIGGERCALCULATOR_H + +/** + * @author Ian Connelly <ian.connelly@cern.ch> + * + * @brief Global lepton trigger calculator + * Interface to retrieve the global lepton trigger scale factors + * + **/ + +// system include(s): +#include <memory> +#include <set> + +// Framework include(s): +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +// Systematic include(s): +#include "PATInterfaces/SystematicSet.h" + +// CP Tool include(s): +#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h" +#include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h" +#include "TriggerAnalysisInterfaces/ITrigGlobalEfficiencyCorrectionTool.h" + +// Forward declaration(s): +namespace xAOD { + class SystematicEvent; +} +namespace top { + class TopConfig; +} + +namespace top { + class GlobalLeptonTriggerCalculator final: public asg::AsgTool { + public: + explicit GlobalLeptonTriggerCalculator(const std::string& name); + virtual ~GlobalLeptonTriggerCalculator() {} + + // Delete Standard constructors + GlobalLeptonTriggerCalculator(const GlobalLeptonTriggerCalculator& rhs) = delete; + GlobalLeptonTriggerCalculator(GlobalLeptonTriggerCalculator&& rhs) = delete; + GlobalLeptonTriggerCalculator& operator = (const GlobalLeptonTriggerCalculator& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(); + private: + void processEvent(const xAOD::SystematicEvent* systEvent, bool withScaleFactorVariations); + + std::shared_ptr<top::TopConfig> m_config; + + ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerSF; + ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerSFLoose; + + std::vector<ToolHandle<IAsgElectronEfficiencyCorrectionTool> > m_electronTools; + std::vector<ToolHandle<CP::IMuonTriggerScaleFactors> > m_muonTools; + + std::string m_decor_triggerSF; + }; +} // namespace +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/JetScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/JetScaleFactorCalculator.h index 2382c616ba53..1cbc8853d4b5 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/JetScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/JetScaleFactorCalculator.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // $Id: JetScaleFactorCalculator.h 724681 2016-02-17 18:20:27Z tneep $ #ifndef ANALYSISTOP_TOPCORRECTIONS_JETSCALEFACTORCALCULATOR_H #define ANALYSISTOP_TOPCORRECTIONS_JETSCALEFACTORCALCULATOR_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief JetScaleFactorCalculator - * Calculate all jet scale factors and decorate - * - * $Revision: 724681 $ - * $Date: 2016-02-17 19:20:27 +0100 (Wed, 17 Feb 2016) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief JetScaleFactorCalculator + * Calculate all jet scale factors and decorate + * + * $Revision: 724681 $ + * $Date: 2016-02-17 18:20:27 +0000 (Wed, 17 Feb 2016) $ + * + **/ // system include(s): #include <memory> @@ -28,39 +28,40 @@ // Systematic include(s): #include "PATInterfaces/SystematicSet.h" -#include "JetJvtEfficiency/IJetJvtEfficiency.h" +#include "JetAnalysisInterfaces/IJetJvtEfficiency.h" // CP Tool include(s): // #include "ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h" // Forward declaration(s): namespace top { -class TopConfig; + class TopConfig; } namespace top { + class JetScaleFactorCalculator final: public asg::AsgTool { + public: + explicit JetScaleFactorCalculator(const std::string& name); + virtual ~JetScaleFactorCalculator() {} -class JetScaleFactorCalculator final : public asg::AsgTool { - public: - explicit JetScaleFactorCalculator(const std::string& name); - virtual ~JetScaleFactorCalculator() {} + // Delete Standard constructors + JetScaleFactorCalculator(const JetScaleFactorCalculator& rhs) = delete; + JetScaleFactorCalculator(JetScaleFactorCalculator&& rhs) = delete; + JetScaleFactorCalculator& operator = (const JetScaleFactorCalculator& rhs) = delete; - // Delete Standard constructors - JetScaleFactorCalculator(const JetScaleFactorCalculator& rhs) = delete; - JetScaleFactorCalculator(JetScaleFactorCalculator&& rhs) = delete; - JetScaleFactorCalculator& operator=(const JetScaleFactorCalculator& rhs) = delete; + StatusCode initialize(); + StatusCode execute(); + private: + StatusCode decorateJets(const xAOD::JetContainer* jets, bool isNominal); + + std::shared_ptr<top::TopConfig> m_config; - StatusCode initialize(); - StatusCode execute(); + CP::SystematicSet m_systNominal; + CP::SystematicSet m_systUP; + CP::SystematicSet m_systDOWN; - private: - std::shared_ptr<top::TopConfig> m_config; - - CP::SystematicSet m_systNominal; - CP::SystematicSet m_systUP; - CP::SystematicSet m_systDOWN; - - ToolHandle<CP::IJetJvtEfficiency> m_jvt_tool; -}; + ToolHandle<CP::IJetJvtEfficiency> m_jvt_tool; + ToolHandle<CP::IJetJvtEfficiency> m_fjvt_tool; + }; } // namespace top #endif // ANALYSISTOP_TOPCORRECTIONS_JETSCALEFACTORCALCULATOR_H diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/MsgCategory.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/MsgCategory.h new file mode 100644 index 000000000000..e3ef1381b800 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/MsgCategory.h @@ -0,0 +1,10 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#ifndef TOPCORRECTIONS_MSG_CATEGORY_H_ +#define TOPCORRECTIONS_MSG_CATEGORY_H_ +#include <AsgMessaging/MessageCheck.h> + +ANA_MSG_HEADER(TopCorrections) + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/MuonScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/MuonScaleFactorCalculator.h index 3a3e73956065..e0ef1594aaf8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/MuonScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/MuonScaleFactorCalculator.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: MuonScaleFactorCalculator.h 786766 2016-11-28 03:21:13Z tpelzer $ #ifndef ANALYSISTOP_TOPCORRECTIONS_MUONSCALEFACTORCALCULATOR_H #define ANALYSISTOP_TOPCORRECTIONS_MUONSCALEFACTORCALCULATOR_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief MuonScaleFactorCalculator - * Calculate all muon scale factors and decorate - * - * $Revision: 786766 $ - * $Date: 2016-11-28 04:21:13 +0100 (Mon, 28 Nov 2016) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief MuonScaleFactorCalculator + * Calculate all muon scale factors and decorate + * + * $Revision: 786766 $ + * $Date: 2016-11-28 03:21:13 +0000 (Mon, 28 Nov 2016) $ + * + **/ // system include(s): #include <memory> @@ -35,173 +35,178 @@ // Forward declaration(s): namespace top { -class TopConfig; + class TopConfig; } namespace top { - -class MuonScaleFactorCalculator final : public asg::AsgTool { - public: - explicit MuonScaleFactorCalculator(const std::string& name); - virtual ~MuonScaleFactorCalculator() {} - - // Delete Standard constructors - MuonScaleFactorCalculator(const MuonScaleFactorCalculator& rhs) = delete; - MuonScaleFactorCalculator(MuonScaleFactorCalculator&& rhs) = delete; - MuonScaleFactorCalculator& operator=(const MuonScaleFactorCalculator& rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - - private: - // Helper function to retrieve a toolhandle and - // get the recommended systematics of that tool - // into a std::set - template<typename T> + class MuonScaleFactorCalculator final: public asg::AsgTool { + public: + explicit MuonScaleFactorCalculator(const std::string& name); + virtual ~MuonScaleFactorCalculator() {} + + // Delete Standard constructors + MuonScaleFactorCalculator(const MuonScaleFactorCalculator& rhs) = delete; + MuonScaleFactorCalculator(MuonScaleFactorCalculator&& rhs) = delete; + MuonScaleFactorCalculator& operator = (const MuonScaleFactorCalculator& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(); + private: + // Helper function to retrieve a toolhandle and + // get the recommended systematics of that tool + // into a std::set + template<typename T> void retrieveSystematicTool(const ToolHandle<T>& tool, std::set<std::string>& recommended_systematics); - // We have (had) a lot of lines like :: - // top::check(tool->applySystematicVariation(...), - // "Failed to set systematic variation"); - // This function will essentially do that but try to give a more - // sensible and specific error message. - // If the SystematicSet is empty then it sets to the nominal, - // so edit error message accordingly. - // (This might be expensive). - // - // Since this is general, we should maybe move somewhere - // more common. - template<typename T> + // We have (had) a lot of lines like :: + // top::check(tool->applySystematicVariation(...), + // "Failed to set systematic variation"); + // This function will essentially do that but try to give a more + // sensible and specific error message. + // If the SystematicSet is empty then it sets to the nominal, + // so edit error message accordingly. + // (This might be expensive). + // + // Since this is general, we should maybe move somewhere + // more common. + template<typename T> void applySystematicVariation(ToolHandle<T>& tool, const CP::SystematicSet& systematic); - // Check that all recommended systematics are implemented - // The arguments are two c++ std::set, for recommended & implemented - // systematics. Recommended systematics can be automatically extracted - // from tools (see retrieveSystematicTool above) while the implemented - // systematics must be hard-coded by the maintainer of this class. - StatusCode checkSystematicsImplemented(const std::set<std::string>& recommended, - const std::set<std::string>& implemented); - - // Use this function to decorate the trigger efficiency - // onto the muon. Try not to use directly, instead use - // decorateTrigSFandEff(), see below. - void decorateTriggerEfficiency(ToolHandle<CP::IMuonTriggerScaleFactors>& tool, - const xAOD::Muon& muon, - const SG::AuxElement::Decorator<float>& decor); - - // Use this function to decorate the trigger SF - // onto the muon. Try not to use directly, instead use - // decorateTrigSFandEff(), see below. - void decorateTriggerSF(ToolHandle<CP::IMuonTriggerScaleFactors>& tool, - const ConstDataVector<xAOD::MuonContainer>& muon_cont, - const SG::AuxElement::Decorator<float>& decor); - - // This function is a nice wrapper of:: - // applySystematicVariation(...); - // decorateTriggerEfficiency(...); - // and:: - // decorateTriggerSF(...); - // We have this code block ~10 times so this hopefully - // keeps it simple and ensures each block is the same. - void decorateTrigSFandEff(ToolHandle<CP::IMuonTriggerScaleFactors>& tool, - const CP::SystematicSet& systematic, - const ConstDataVector<xAOD::MuonContainer>& muon_cont, - const SG::AuxElement::Decorator<float>& sf_decor, - const SG::AuxElement::Decorator<float>& eff_decor); - - // To keep things as readable as possible this function - // decorates the muon with the loose and tight trigger SFs and effs - void decorateTriggerSystematics(const ConstDataVector<xAOD::MuonContainer>& trigger_SF_muon); - - // As with ``applySystematicVariation``, we have (had) a - // lot of lines:: - // top::check(tool->getEfficiencyScaleFactor(muon, syst), - // "Failed to get efficiency SF"); - // This helper function will replace that, as well as calling - // applySystematicVariation try and avoid errors - void decorateEfficiencySF(ToolHandle<CP::IMuonEfficiencyScaleFactors>& tool, - const CP::SystematicSet& systematic, - const xAOD::Muon& muon, - const SG::AuxElement::Decorator<float>& decor); - - // Helper function to decorate isolation systematics - // if we have set isolation to None for either the - // tight or loose muon selections then this will still - // decorate the SFs all set to 1.0 - void decorateIsolationSystematics(const xAOD::Muon& muon); - - // Helper function to decorate all TTVA SF systematics onto muon - void decorateTTVASystematics(const xAOD::Muon& muon); - - // For a single systematic, decorate the ID SF onto muon - // no reco Eff since 2.4.22 - void decorateIDSFandRecoEff(ToolHandle<CP::IMuonEfficiencyScaleFactors>& tool, + // Check that all recommended systematics are implemented + // The arguments are two c++ std::set, for recommended & implemented + // systematics. Recommended systematics can be automatically extracted + // from tools (see retrieveSystematicTool above) while the implemented + // systematics must be hard-coded by the maintainer of this class. + StatusCode checkSystematicsImplemented(const std::set<std::string>& recommended, + const std::set<std::string>& implemented); + + // Use this function to decorate the trigger efficiency + // onto the muon. Try not to use directly, instead use + // decorateTrigSFandEff(), see below. + void decorateTriggerEfficiency(ToolHandle<CP::IMuonTriggerScaleFactors>& tool, + const xAOD::Muon& muon, + const SG::AuxElement::Decorator<float>& decor); + + // Use this function to decorate the trigger SF + // onto the muon. Try not to use directly, instead use + // decorateTrigSFandEff(), see below. + void decorateTriggerSF(ToolHandle<CP::IMuonTriggerScaleFactors>& tool, + const ConstDataVector<xAOD::MuonContainer>& muon_cont, + const SG::AuxElement::Decorator<float>& decor); + + // This function is a nice wrapper of:: + // applySystematicVariation(...); + // decorateTriggerEfficiency(...); + // and:: + // decorateTriggerSF(...); + // We have this code block ~10 times so this hopefully + // keeps it simple and ensures each block is the same. + void decorateTrigSFandEff(ToolHandle<CP::IMuonTriggerScaleFactors>& tool, + const CP::SystematicSet& systematic, + const ConstDataVector<xAOD::MuonContainer>& muon_cont, + const SG::AuxElement::Decorator<float>& sf_decor, + const SG::AuxElement::Decorator<float>& eff_decor); + + // To keep things as readable as possible this function + // decorates the muon with the loose and tight trigger SFs and effs + void decorateTriggerSystematics(const ConstDataVector<xAOD::MuonContainer>& trigger_SF_muon); + + // As with ``applySystematicVariation``, we have (had) a + // lot of lines:: + // top::check(tool->getEfficiencyScaleFactor(muon, syst), + // "Failed to get efficiency SF"); + // This helper function will replace that, as well as calling + // applySystematicVariation try and avoid errors + void decorateEfficiencySF(ToolHandle<CP::IMuonEfficiencyScaleFactors>& tool, const CP::SystematicSet& systematic, const xAOD::Muon& muon, - const SG::AuxElement::Decorator<float>& id_sf_decor); - - // Helper funciton to do above for all systematics - void decorateIDSFandRecoEffSystematics(const xAOD::Muon& muon); - - std::shared_ptr<top::TopConfig> m_config; - - CP::SystematicSet m_systNominal; - - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors; - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose; - - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_2015; - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_2015; - - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_2016; - ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_2016; - - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsTool; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolLoose; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolIso; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolLooseIso; - ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolTTVA; - - std::string m_decor_triggerEff; - std::string m_decor_triggerEff_loose; - std::string m_decor_triggerSF; - std::string m_decor_triggerSF_loose; - std::string m_decor_idSF; - std::string m_decor_idSF_loose; - std::string m_decor_isoSF; - std::string m_decor_isoSF_loose; - std::string m_decor_TTVA; - - bool m_do_muon_isolation_SFs; - bool m_do_muon_isolation_SFs_loose; - - CP::SystematicSet m_trig_sf_stat_UP; - CP::SystematicSet m_trig_sf_stat_DOWN; - CP::SystematicSet m_trig_sf_syst_UP; - CP::SystematicSet m_trig_sf_syst_DOWN; - - CP::SystematicSet m_reco_stat_UP; - CP::SystematicSet m_reco_stat_DOWN; - CP::SystematicSet m_reco_syst_UP; - CP::SystematicSet m_reco_syst_DOWN; - - CP::SystematicSet m_reco_stat_lowpt_UP; - CP::SystematicSet m_reco_stat_lowpt_DOWN; - CP::SystematicSet m_reco_syst_lowpt_UP; - CP::SystematicSet m_reco_syst_lowpt_DOWN; - - CP::SystematicSet m_iso_stat_UP; - CP::SystematicSet m_iso_stat_DOWN; - CP::SystematicSet m_iso_syst_UP; - CP::SystematicSet m_iso_syst_DOWN; - - CP::SystematicSet m_TTVA_stat_UP; - CP::SystematicSet m_TTVA_stat_DOWN; - CP::SystematicSet m_TTVA_syst_UP; - CP::SystematicSet m_TTVA_syst_DOWN; - - std::string m_muon_trigger_sf_config = ""; -}; + const SG::AuxElement::Decorator<float>& decor); + + // Helper function to decorate isolation systematics + // if we have set isolation to None for either the + // tight or loose muon selections then this will still + // decorate the SFs all set to 1.0 + void decorateIsolationSystematics(const xAOD::Muon& muon); + + // Helper function to decorate all TTVA SF systematics onto muon + void decorateTTVASystematics(const xAOD::Muon& muon); + + // For a single systematic, decorate the ID SF onto muon + // no reco Eff since 2.4.22 + void decorateIDSFandRecoEff(ToolHandle<CP::IMuonEfficiencyScaleFactors>& tool, + const CP::SystematicSet& systematic, + const xAOD::Muon& muon, + const SG::AuxElement::Decorator<float>& id_sf_decor); + + // Helper funciton to do above for all systematics + void decorateIDSFandRecoEffSystematics(const xAOD::Muon& muon); + void decorateIDSFandRecoEffSystematicsSoftMuon(const xAOD::Muon& muon); + + std::shared_ptr<top::TopConfig> m_config; + + CP::SystematicSet m_systNominal; + + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose; + + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_2015; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_2015; + + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_2016; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_2016; + + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactors_R21; + ToolHandle<CP::IMuonTriggerScaleFactors> m_muonTriggerScaleFactorsLoose_R21; + + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsTool; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_softmuonEfficiencyCorrectionsTool; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolLoose; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolIso; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolLooseIso; + ToolHandle<CP::IMuonEfficiencyScaleFactors> m_muonEfficiencyCorrectionsToolTTVA; + + std::string m_decor_triggerEff; + std::string m_decor_triggerEff_loose; + std::string m_decor_triggerSF; + std::string m_decor_triggerSF_loose; + std::string m_decor_idSF; + std::string m_decor_idSF_loose; + std::string m_decor_isoSF; + std::string m_decor_isoSF_loose; + std::string m_decor_TTVA; + + std::string m_decor_softmuon_idSF; + + bool m_do_muon_isolation_SFs; + bool m_do_muon_isolation_SFs_loose; + + CP::SystematicSet m_trig_sf_stat_UP; + CP::SystematicSet m_trig_sf_stat_DOWN; + CP::SystematicSet m_trig_sf_syst_UP; + CP::SystematicSet m_trig_sf_syst_DOWN; + + CP::SystematicSet m_reco_stat_UP; + CP::SystematicSet m_reco_stat_DOWN; + CP::SystematicSet m_reco_syst_UP; + CP::SystematicSet m_reco_syst_DOWN; + + CP::SystematicSet m_reco_stat_lowpt_UP; + CP::SystematicSet m_reco_stat_lowpt_DOWN; + CP::SystematicSet m_reco_syst_lowpt_UP; + CP::SystematicSet m_reco_syst_lowpt_DOWN; + + CP::SystematicSet m_iso_stat_UP; + CP::SystematicSet m_iso_stat_DOWN; + CP::SystematicSet m_iso_syst_UP; + CP::SystematicSet m_iso_syst_DOWN; + + CP::SystematicSet m_TTVA_stat_UP; + CP::SystematicSet m_TTVA_stat_DOWN; + CP::SystematicSet m_TTVA_syst_UP; + CP::SystematicSet m_TTVA_syst_DOWN; + + std::string m_muon_trigger_sf_config = ""; + }; } // namespace top #endif // ANALYSISTOP_TOPCORRECTIONS_MUONSCALEFACTORCALCULATOR_H diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PDFScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PDFScaleFactorCalculator.h index 52a34504717b..f411f112545e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PDFScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PDFScaleFactorCalculator.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef PDFSCALEFACTORCALCULATOR #define PDFSCALEFACTORCALCULATOR @@ -25,25 +25,25 @@ #include "TopEvent/Event.h" namespace top { - class TopConfig; /** * @brief For testing PDF reweighting with LHAPDF6. Not serious, just a toy. * * Lots of stuff is available on cvmfs, set this: - * export LHAPDF_DATA_PATH=$ROOTCOREBIN/data/Asg_Lhapdf_LHAPDF:/cvmfs/sft.cern.ch/lcg/external/lhapdfsets/current/:$LHAPDF_DATA_PATH + * export + *LHAPDF_DATA_PATH=$ROOTCOREBIN/data/Asg_Lhapdf_LHAPDF:/cvmfs/sft.cern.ch/lcg/external/lhapdfsets/current/:$LHAPDF_DATA_PATH */ - class PDFScaleFactorCalculator final : public asg::AsgTool { + class PDFScaleFactorCalculator final: public asg::AsgTool { public: - explicit PDFScaleFactorCalculator( const std::string& name ); - - virtual ~PDFScaleFactorCalculator(){}; + explicit PDFScaleFactorCalculator(const std::string& name); + + virtual ~PDFScaleFactorCalculator() {}; // Delete Standard constructors PDFScaleFactorCalculator(const PDFScaleFactorCalculator& rhs) = delete; PDFScaleFactorCalculator(PDFScaleFactorCalculator&& rhs) = delete; - PDFScaleFactorCalculator& operator=(const PDFScaleFactorCalculator& rhs) = delete; + PDFScaleFactorCalculator& operator = (const PDFScaleFactorCalculator& rhs) = delete; StatusCode initialize(); StatusCode execute(); @@ -51,6 +51,7 @@ namespace top { int numberInSet(const std::string& name) const { const LHAPDF::PDFSet set(name); + return set.size(); } @@ -61,14 +62,13 @@ namespace top { * variable. */ void printAvailablePDFs() const { - std::cout << "List of available PDFs:" << std::endl; + ATH_MSG_INFO("List of available PDFs:"); for (const std::string& pdfname : LHAPDF::availablePDFSets()) - std::cout << " " << pdfname << std::endl; + msg(MSG::Level::INFO) << " " << pdfname << "\n"; + msg(MSG::Level::INFO) << std::endl; } - private: - std::shared_ptr<top::TopConfig> m_config; std::vector< std::string > m_pdf_names; @@ -77,32 +77,25 @@ namespace top { // Small helper class to hold the information we need class PDFSet { - public: + PDFSet() {;}; - PDFSet(){;}; - - explicit PDFSet( const std::string& name ){ - - LHAPDF::mkPDFs( name, pdf_members ); - unsigned int n_members = pdf_members.size(); - event_weights.resize( n_members ); - sum_of_event_weights.resize( n_members ); - + explicit PDFSet(const std::string& name) { + LHAPDF::mkPDFs(name, pdf_members); + unsigned int n_members = pdf_members.size(); + event_weights.resize(n_members); + sum_of_event_weights.resize(n_members); }; - + std::vector< std::unique_ptr<const LHAPDF::PDF> > pdf_members = {}; std::vector< float > event_weights = {}; - + std::vector< float > sum_of_event_weights = {}; - }; std::unordered_map< std::string, PDFSet > m_pdf_sets; - }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PhotonScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PhotonScaleFactorCalculator.h index 87ef808a016e..2f579ea1eb0c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PhotonScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PhotonScaleFactorCalculator.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: PhotonScaleFactorCalculator.h 802226 2017-04-04 16:13:10Z grancagn $ #ifndef TOPCORRECTIONS_PHOTONSCALEFACTORCALCULATOR_H_ #define TOPCORRECTIONS_PHOTONSCALEFACTORCALCULATOR_H_ /** - * @author John Morris <john.morris@cern.ch> - * - * @brief PhotonScaleFactorCalculator - * Calculate all photon scale factors and decorate - * - * $Revision: 802226 $ - * $Date: 2017-04-04 18:13:10 +0200 (Tue, 04 Apr 2017) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief PhotonScaleFactorCalculator + * Calculate all photon scale factors and decorate + * + * $Revision: 802226 $ + * $Date: 2017-04-04 17:13:10 +0100 (Tue, 04 Apr 2017) $ + * + **/ // system include(s): #include <memory> @@ -29,48 +29,42 @@ #include "PATInterfaces/SystematicSet.h" // CP Tool include(s): -#include "PhotonEfficiencyCorrection/IAsgPhotonEfficiencyCorrectionTool.h" +#include "EgammaAnalysisInterfaces/IAsgPhotonEfficiencyCorrectionTool.h" namespace top { // Forward declaration(s): -class TopConfig; - -class PhotonScaleFactorCalculator final : public asg::AsgTool { - public: - explicit PhotonScaleFactorCalculator(const std::string& name); - virtual ~PhotonScaleFactorCalculator() {} - - // Delete Standard constructors - PhotonScaleFactorCalculator(const PhotonScaleFactorCalculator& rhs) = delete; - PhotonScaleFactorCalculator(PhotonScaleFactorCalculator&& rhs) = delete; - PhotonScaleFactorCalculator& operator=(const PhotonScaleFactorCalculator& rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - CP::SystematicSet m_systNominal; - CP::SystematicSet m_systEffIDUp; - CP::SystematicSet m_systEffIDDown; - CP::SystematicSet m_systEffLowPtIsoUp; - CP::SystematicSet m_systEffLowPtIsoDown; - CP::SystematicSet m_systEffTrkIsoUp; - CP::SystematicSet m_systEffTrkIsoDown; - CP::SystematicSet m_systIsoDDonoffUp; - CP::SystematicSet m_systIsoDDonoffDown; - - ToolHandle<IAsgPhotonEfficiencyCorrectionTool> m_photonEffSF; - ToolHandle<IAsgPhotonEfficiencyCorrectionTool> m_photonIsoSF; - ToolHandle<IAsgPhotonEfficiencyCorrectionTool> m_photonLooseIsoSF; - - bool m_photonIsoSF_exists; - bool m_photonLooseIsoSF_exists; - - std::string m_decor_isoSF; - std::string m_decor_isoSF_loose; - -}; + class TopConfig; + + class PhotonScaleFactorCalculator final: public asg::AsgTool { + public: + explicit PhotonScaleFactorCalculator(const std::string& name); + virtual ~PhotonScaleFactorCalculator() {} + + // Delete Standard constructors + PhotonScaleFactorCalculator(const PhotonScaleFactorCalculator& rhs) = delete; + PhotonScaleFactorCalculator(PhotonScaleFactorCalculator&& rhs) = delete; + PhotonScaleFactorCalculator& operator = (const PhotonScaleFactorCalculator& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(); + private: + std::shared_ptr<top::TopConfig> m_config; + + CP::SystematicSet m_systNominal; + CP::SystematicSet m_systEffIDUp; + CP::SystematicSet m_systEffIDDown; + CP::SystematicSet m_systEffIsoUp; + CP::SystematicSet m_systEffIsoDown; + + ToolHandle<IAsgPhotonEfficiencyCorrectionTool> m_photonEffSF; + ToolHandle<IAsgPhotonEfficiencyCorrectionTool> m_photonIsoSF; + ToolHandle<IAsgPhotonEfficiencyCorrectionTool> m_photonLooseIsoSF; + + bool m_photonIsoSF_exists; + bool m_photonLooseIsoSF_exists; + + std::string m_decor_isoSF; + std::string m_decor_isoSF_loose; + }; } // namespace top #endif // TOPCORRECTIONS_PHOTONSCALEFACTORCALCULATOR_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PileupScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PileupScaleFactorCalculator.h index 2c1c3bb25592..1e60b01fe5e8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PileupScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/PileupScaleFactorCalculator.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOP_TOPCORRECTIONS_PILEUPSCALEFACTORCALCULATOR_H #define ANALYSISTOP_TOPCORRECTIONS_PILEUPSCALEFACTORCALCULATOR_H @@ -15,37 +15,35 @@ #include "AsgAnalysisInterfaces/IPileupReweightingTool.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ +namespace top { + class PileupScaleFactorCalculator final: public asg::AsgTool { + public: + explicit PileupScaleFactorCalculator(const std::string& name); + virtual ~PileupScaleFactorCalculator() {} - class PileupScaleFactorCalculator final : public asg::AsgTool { - public: - explicit PileupScaleFactorCalculator( const std::string& name ); - virtual ~PileupScaleFactorCalculator(){} + // Delete Standard constructors + PileupScaleFactorCalculator(const PileupScaleFactorCalculator& rhs) = delete; + PileupScaleFactorCalculator(PileupScaleFactorCalculator&& rhs) = delete; + PileupScaleFactorCalculator& operator = (const PileupScaleFactorCalculator& rhs) = delete; - // Delete Standard constructors - PileupScaleFactorCalculator(const PileupScaleFactorCalculator& rhs) = delete; - PileupScaleFactorCalculator(PileupScaleFactorCalculator&& rhs) = delete; - PileupScaleFactorCalculator& operator=(const PileupScaleFactorCalculator& rhs) = delete; + StatusCode initialize(); + StatusCode execute(); + private: + std::shared_ptr<top::TopConfig> m_config; - StatusCode initialize(); - StatusCode execute(); + ///Pileup Reweighting Tool + ToolHandle<CP::IPileupReweightingTool> m_pileupReweightingTool; - private: - std::shared_ptr<top::TopConfig> m_config; - - ///Pileup Reweighting Tool - ToolHandle<CP::IPileupReweightingTool> m_pileupReweightingTool; + // systematics + CP::SystematicSet m_systNominal; + CP::SystematicSet m_systDataSFUp; + CP::SystematicSet m_systDataSFDown; - // systematics - CP::SystematicSet m_systNominal; - CP::SystematicSet m_systDataSFUp; - CP::SystematicSet m_systDataSFDown; - - bool m_mu_dependent_PRW = true; + bool m_mu_dependent_PRW = true; }; } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ScaleFactorCalculator.h index 61e388e10789..37a71aca316a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ScaleFactorCalculator.h @@ -1,20 +1,20 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef SCALEFACTORCALCULATOR_H_ #define SCALEFACTORCALCULATOR_H_ /** - * @author John Morris <john.morris@cern.ch> - * - * @brief ScaleFactorCalculator - * Scale factors for all objects - * - * $Revision: 766520 $ - * $Date: 2016-08-04 18:39:21 +0200 (Thu, 04 Aug 2016) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief ScaleFactorCalculator + * Scale factors for all objects + * + * $Revision: 766520 $ + * $Date: 2016-08-04 17:39:21 +0100 (Thu, 04 Aug 2016) $ + * + **/ // system include(s): #include <vector> @@ -25,49 +25,56 @@ // PMG Tools #include "PMGTools/PMGSherpa22VJetsWeightTool.h" +#include "PMGAnalysisInterfaces/IPMGTruthWeightTool.h" // Local include(s): #include "TopCorrections/PhotonScaleFactorCalculator.h" #include "TopCorrections/ElectronScaleFactorCalculator.h" +#include "TopCorrections/FwdElectronScaleFactorCalculator.h" #include "TopCorrections/MuonScaleFactorCalculator.h" #include "TopCorrections/TauScaleFactorCalculator.h" #include "TopCorrections/JetScaleFactorCalculator.h" #include "TopCorrections/BTagScaleFactorCalculator.h" #include "TopCorrections/PileupScaleFactorCalculator.h" +#include "TopCorrections/GlobalLeptonTriggerCalculator.h" namespace top { + class TopConfig; -class TopConfig; + class ScaleFactorCalculator final: public asg::AsgTool { + public: + explicit ScaleFactorCalculator(const std::string& name); + virtual ~ScaleFactorCalculator() {} -class ScaleFactorCalculator final : public asg::AsgTool{ - public: - explicit ScaleFactorCalculator( const std::string& name ); - virtual ~ScaleFactorCalculator() {} - - ScaleFactorCalculator(const ScaleFactorCalculator& rhs) = delete; - ScaleFactorCalculator(ScaleFactorCalculator&& rhs) = delete; - ScaleFactorCalculator& operator=(const ScaleFactorCalculator& rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - - StatusCode executePileup(); - float pileupWeight() const; - float mcEventWeight() const; - - private: - std::shared_ptr<top::TopConfig> m_config; - - std::unique_ptr<top::PhotonScaleFactorCalculator> m_photonSF; - std::unique_ptr<top::ElectronScaleFactorCalculator> m_electronSF; - std::unique_ptr<top::MuonScaleFactorCalculator> m_muonSF; - std::unique_ptr<top::TauScaleFactorCalculator> m_tauSF; - std::unique_ptr<top::JetScaleFactorCalculator> m_jetSF; - std::unique_ptr<top::BTagScaleFactorCalculator> m_btagSF; - std::unique_ptr<top::PileupScaleFactorCalculator> m_pileupSF; - ToolHandle<PMGTools::PMGSherpa22VJetsWeightTool> m_sherpa_22_reweight_tool; - -}; + ScaleFactorCalculator(const ScaleFactorCalculator& rhs) = delete; + ScaleFactorCalculator(ScaleFactorCalculator&& rhs) = delete; + ScaleFactorCalculator& operator = (const ScaleFactorCalculator& rhs) = delete; + + StatusCode initialize(); + StatusCode initialize_nominal_MC_weight(); // determine what MC weight to use as nominal + StatusCode execute(); + + StatusCode executePileup(); + float pileupWeight() const; + float mcEventWeight() const; + private: + std::shared_ptr<top::TopConfig> m_config; + + std::unique_ptr<top::PhotonScaleFactorCalculator> m_photonSF; + std::unique_ptr<top::ElectronScaleFactorCalculator> m_electronSF; + std::unique_ptr<top::FwdElectronScaleFactorCalculator> m_fwdElectronSF; + std::unique_ptr<top::MuonScaleFactorCalculator> m_muonSF; + std::unique_ptr<top::TauScaleFactorCalculator> m_tauSF; + std::unique_ptr<top::JetScaleFactorCalculator> m_jetSF; + std::unique_ptr<top::BTagScaleFactorCalculator> m_btagSF; + std::unique_ptr<top::PileupScaleFactorCalculator> m_pileupSF; + ToolHandle<PMGTools::PMGSherpa22VJetsWeightTool> m_sherpa_22_reweight_tool; + std::unique_ptr<top::GlobalLeptonTriggerCalculator> m_globalLeptonTriggerSF; + ToolHandle<PMGTools::IPMGTruthWeightTool> m_pmg_truth_weight_tool; + + bool m_sample_multiple_MCweights; + std::string m_nominal_weight_name; + }; } // namespace top #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ScaleFactorRetriever.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ScaleFactorRetriever.h index 362fb0bbf276..be78919ae6ea 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ScaleFactorRetriever.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/ScaleFactorRetriever.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ #ifndef SCALEFACTORRETRIEVER_H_ #define SCALEFACTORRETRIEVER_H_ @@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "AsgTools/AsgTool.h" #include "xAODEgamma/ElectronContainer.h" #include "xAODEgamma/PhotonContainer.h" #include "xAODMuon/MuonContainer.h" @@ -17,268 +18,463 @@ // Forward declare: namespace top { -class Event; -class TopConfig; + class Event; + class TopConfig; } namespace top { - ///-- Top SF enmu, as CP::SystematicSet won't do the job --/// -enum topSFSyst{nominal = 0, - // Electron Trigger SFs - EL_SF_Trigger_UP, EL_SF_Trigger_DOWN, - // Electron reconstruction SFs - EL_SF_Reco_UP, EL_SF_Reco_DOWN, - // Electron ID SFs - EL_SF_ID_UP, EL_SF_ID_DOWN, - // Electron isolation SFs - EL_SF_Isol_UP, EL_SF_Isol_DOWN, - // Electron Charge flip SFs - EL_SF_ChargeID_UP, EL_SF_ChargeID_DOWN, - EL_SF_ChargeMisID_STAT_UP, EL_SF_ChargeMisID_STAT_DOWN, - EL_SF_ChargeMisID_SYST_UP, EL_SF_ChargeMisID_SYST_DOWN, - // Muon Trigger SFs - MU_SF_Trigger_UP, MU_SF_Trigger_DOWN, - MU_SF_Trigger_STAT_UP, MU_SF_Trigger_STAT_DOWN, - MU_SF_Trigger_SYST_UP, MU_SF_Trigger_SYST_DOWN, - // Muon ID SFs (regular) - MU_SF_ID_STAT_UP, MU_SF_ID_STAT_DOWN, - MU_SF_ID_SYST_UP, MU_SF_ID_SYST_DOWN, - // Muon ID SFs (low pT) - MU_SF_ID_STAT_LOWPT_UP, MU_SF_ID_STAT_LOWPT_DOWN, - MU_SF_ID_SYST_LOWPT_UP, MU_SF_ID_SYST_LOWPT_DOWN, - // Muon isolation SFs - MU_SF_Isol_STAT_UP, MU_SF_Isol_STAT_DOWN, - MU_SF_Isol_SYST_UP, MU_SF_Isol_SYST_DOWN, - // Muon TTVA SFs - MU_SF_TTVA_STAT_UP, MU_SF_TTVA_STAT_DOWN, - MU_SF_TTVA_SYST_UP, MU_SF_TTVA_SYST_DOWN, - // Tau SFs - TAU_SF_ELEOLR_TOTAL_UP, TAU_SF_ELEOLR_TOTAL_DOWN, - TAU_SF_JETID_TOTAL_UP, TAU_SF_JETID_TOTAL_DOWN, - TAU_SF_RECO_TOTAL_UP, TAU_SF_RECO_TOTAL_DOWN, - // Photon SFs - PHOTON_IDSF_UP, PHOTON_IDSF_DOWN, PHOTON_EFF_ISO, - PHOTON_EFF_LOWPTISO_UP, PHOTON_EFF_TRKISO_UP, - PHOTON_EFF_LOWPTISO_DOWN, PHOTON_EFF_TRKISO_DOWN, - // B-tagging SFs - BTAG_SF_EIGEN_B, BTAG_SF_EIGEN_C, - BTAG_SF_EIGEN_LIGHT, - BTAG_SF_NAMED_UP, BTAG_SF_NAMED_DOWN, - // JVT SFs - JVT_UP, JVT_DOWN, - - lastsys -}; - - -enum topSFComp{ALL = 0, TRIGGER, RECO, ID, ISOLATION, CHARGEID, CHARGEMISID, TTVA}; - - -class ScaleFactorRetriever final { - public: - explicit ScaleFactorRetriever(std::shared_ptr<top::TopConfig> config); - virtual ~ScaleFactorRetriever() {} - - // Delete Standard constructors - ScaleFactorRetriever(const ScaleFactorRetriever& rhs) = delete; - ScaleFactorRetriever(ScaleFactorRetriever&& rhs) = delete; - ScaleFactorRetriever& operator=(const ScaleFactorRetriever& rhs) = delete; - - // Pile up SF - static bool hasPileupSF(const top::Event& event); - static float pileupSF(const top::Event& event, int var = 0); - - // Obtain the lepton SF - float leptonSF(const top::Event& event, const top::topSFSyst SFSyst) const; - - // Obtain the trigger SF - float triggerSF(const top::Event& event, const top::topSFSyst SFSyst) const; - - // Obtain the electron SF - float electronSF(const top::Event& event, - const top::topSFSyst SFSyst, - const top::topSFComp SFComp) const; - - // Obtain the muon SF - float muonSF(const top::Event& event, - const top::topSFSyst SFSyst, - const top::topSFComp SFComp) const; - - /** - * @brief: get the tauSF for all taus in event - * @param: event, a top::Event object - * @param: SFSyst, systematic variation enum - */ - float tauSF(const top::Event& event, - const top::topSFSyst SFSyst) const; - - /** - * @brief: get the photonSF for all photons in event - * @param: event, a top::Event object - * @param: SFSyst, systematic variation enum - */ - float photonSF(const top::Event& event, - const top::topSFSyst SFSyst) const; - - /** - * @brief Missing important functionality, but testing... - */ - float btagSF(const top::Event& event, - const top::topSFSyst SFSyst = top::topSFSyst::nominal, - std::string WP = "FixedCutBEff_77", - bool do_trackjets = false, - std::string uncert_name = "") const; - - void btagSF_eigen_vars(const top::Event& event, - const top::topSFSyst SFSyst, - std::vector<float>& btagSF_up, - std::vector<float>& btagSF_down, - std::string WP = "FixedCutBEff_77", - bool do_trackjets = false) const; - - /** - * - * JVT Efficiency SFs - * @brief: Get the total JVT SF by taking the product of SFs for all jets - * - * @param: event, a top::Event object - * @param: SFSyst, systematic variation enum - * - * @return: prod_jvt, the product of the jvt SFs for selected jets - * - **/ - float jvtSF(const top::Event& event, - const top::topSFSyst SFsyst) const; - - - /** - * @brief Print all the SF values to cout - */ - void print(const top::Event& event); - - float electronSF_Reco(const xAOD::Electron& x, - const top::topSFSyst SFSyst) const; + enum topSFSyst { + nominal = 0, + // Electron Trigger SFs + EL_SF_Trigger_UP, EL_SF_Trigger_DOWN, + // Electron reconstruction SFs + EL_SF_Reco_UP, EL_SF_Reco_DOWN, + // Electron ID SFs + EL_SF_ID_UP, EL_SF_ID_DOWN, + // Electron isolation SFs + EL_SF_Isol_UP, EL_SF_Isol_DOWN, + // Electron Charge flip SFs + EL_SF_ChargeID_UP, EL_SF_ChargeID_DOWN, + EL_SF_ChargeMisID_STAT_UP, EL_SF_ChargeMisID_STAT_DOWN, + EL_SF_ChargeMisID_SYST_UP, EL_SF_ChargeMisID_SYST_DOWN, + // Muon Trigger SFs + MU_SF_Trigger_UP, MU_SF_Trigger_DOWN, + MU_SF_Trigger_STAT_UP, MU_SF_Trigger_STAT_DOWN, + MU_SF_Trigger_SYST_UP, MU_SF_Trigger_SYST_DOWN, + // Muon ID SFs (regular) + MU_SF_ID_STAT_UP, MU_SF_ID_STAT_DOWN, + MU_SF_ID_SYST_UP, MU_SF_ID_SYST_DOWN, + // Muon ID SFs (low pT) + MU_SF_ID_STAT_LOWPT_UP, MU_SF_ID_STAT_LOWPT_DOWN, + MU_SF_ID_SYST_LOWPT_UP, MU_SF_ID_SYST_LOWPT_DOWN, + // Muon isolation SFs + MU_SF_Isol_STAT_UP, MU_SF_Isol_STAT_DOWN, + MU_SF_Isol_SYST_UP, MU_SF_Isol_SYST_DOWN, + // Muon TTVA SFs + MU_SF_TTVA_STAT_UP, MU_SF_TTVA_STAT_DOWN, + MU_SF_TTVA_SYST_UP, MU_SF_TTVA_SYST_DOWN, + + TAU_SF_NOMINAL, + // Tau EleOLR SFs + TAUS_TRUEHADTAU_EFF_ELEOLR_TOTAL__1up, TAUS_TRUEHADTAU_EFF_ELEOLR_TOTAL__1down, + TAUS_TRUEELECTRON_EFF_ELEOLR_STAT__1up, TAUS_TRUEELECTRON_EFF_ELEOLR_STAT__1down, + TAUS_TRUEELECTRON_EFF_ELEOLR_SYST__1up, TAUS_TRUEELECTRON_EFF_ELEOLR_SYST__1down, + // Tau RNNID SFs + TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2025__1up, TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2025__1down, + TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2530__1up, TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2530__1down, + TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT3040__1up, TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT3040__1down, + TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPTGE40__1up, TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPTGE40__1down, + TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2025__1up, TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2025__1down, + TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2530__1up, TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2530__1down, + TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT3040__1up, TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT3040__1down, + TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPTGE40__1up, TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPTGE40__1down, + TAUS_TRUEHADTAU_EFF_RNNID_HIGHPT__1up, TAUS_TRUEHADTAU_EFF_RNNID_HIGHPT__1down, + TAUS_TRUEHADTAU_EFF_RNNID_SYST__1up, TAUS_TRUEHADTAU_EFF_RNNID_SYST__1down, + + // Tau BDTID SFs + TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETAHIGH__1up, TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETAHIGH__1down, + TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETALOW__1up, TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETALOW__1down, + TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETAHIGH__1up, TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETAHIGH__1down, + TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETALOW__1up, TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETALOW__1down, + TAUS_TRUEHADTAU_EFF_JETID_SYST__1up, + TAUS_TRUEHADTAU_EFF_JETID_SYST__1down, + TAUS_TRUEHADTAU_EFF_JETID_HIGHPT__1up, + TAUS_TRUEHADTAU_EFF_JETID_HIGHPT__1down, + // Tau Reconstruction SFs + TAUS_TRUEHADTAU_EFF_RECO_TOTAL__1up, TAUS_TRUEHADTAU_EFF_RECO_TOTAL__1down, + TAU_SF_END, + // Photon SFs + PHOTON_IDSF_UP, PHOTON_IDSF_DOWN, + PHOTON_EFF_ISO_UP, PHOTON_EFF_ISO_DOWN, + // B-tagging SFs + BTAG_SF_EIGEN_B, BTAG_SF_EIGEN_C, + BTAG_SF_EIGEN_LIGHT, + BTAG_SF_NAMED_UP, BTAG_SF_NAMED_DOWN, + // JVT SFs + JVT_UP, JVT_DOWN, + // fJVT SFs + FJVT_UP, FJVT_DOWN, + // FWD Electron ID SFs + FWDEL_SF_ID_UP, FWDEL_SF_ID_DOWN, + + lastsys + }; + const std::map<topSFSyst, TString> tauSF_name = { + {TAU_SF_NOMINAL, "TAU_SF_NOMINAL"}, + {TAUS_TRUEHADTAU_EFF_RECO_TOTAL__1up, "TAUS_TRUEHADTAU_EFF_RECO_TOTAL__1up"}, + {TAUS_TRUEHADTAU_EFF_RECO_TOTAL__1down, "TAUS_TRUEHADTAU_EFF_RECO_TOTAL__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2025__1up, + "TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2025__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2025__1down, + "TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2025__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2530__1up, + "TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2530__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2530__1down, + "TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2530__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT3040__1up, + "TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT3040__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT3040__1down, + "TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT3040__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPTGE40__1up, + "TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPTGE40__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPTGE40__1down, + "TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPTGE40__1down"}, + {TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETAHIGH__1up, "TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETAHIGH__1up"}, + {TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETAHIGH__1down, "TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETAHIGH__1down"}, + {TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETALOW__1up, "TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETALOW__1up"}, + {TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETALOW__1down, "TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETALOW__1down"}, + {TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETAHIGH__1up, "TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETAHIGH__1up"}, + {TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETAHIGH__1down, "TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETAHIGH__1down"}, + {TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETALOW__1up, "TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETALOW__1up"}, + {TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETALOW__1down, "TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETALOW__1down"}, + {TAUS_TRUEHADTAU_EFF_JETID_SYST__1up, "TAUS_TRUEHADTAU_EFF_JETID_SYST__1up"}, + {TAUS_TRUEHADTAU_EFF_JETID_SYST__1down, "TAUS_TRUEHADTAU_EFF_JETID_SYST__1down"}, + {TAUS_TRUEHADTAU_EFF_JETID_HIGHPT__1up, "TAUS_TRUEHADTAU_EFF_JETID_HIGHPT__1up"}, + {TAUS_TRUEHADTAU_EFF_JETID_HIGHPT__1down, "TAUS_TRUEHADTAU_EFF_JETID_HIGHPT__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2025__1up, + "TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2025__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2025__1down, + "TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2025__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2530__1up, + "TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2530__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2530__1down, + "TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2530__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT3040__1up, + "TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT3040__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT3040__1down, + "TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT3040__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPTGE40__1up, + "TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPTGE40__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPTGE40__1down, + "TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPTGE40__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_HIGHPT__1up, "TAUS_TRUEHADTAU_EFF_RNNID_HIGHPT__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_HIGHPT__1down, "TAUS_TRUEHADTAU_EFF_RNNID_HIGHPT__1down"}, + {TAUS_TRUEHADTAU_EFF_RNNID_SYST__1up, "TAUS_TRUEHADTAU_EFF_RNNID_SYST__1up"}, + {TAUS_TRUEHADTAU_EFF_RNNID_SYST__1down, "TAUS_TRUEHADTAU_EFF_RNNID_SYST__1down"}, + {TAUS_TRUEHADTAU_EFF_ELEOLR_TOTAL__1up, "TAUS_TRUEHADTAU_EFF_ELEOLR_TOTAL__1up"}, + {TAUS_TRUEHADTAU_EFF_ELEOLR_TOTAL__1down, "TAUS_TRUEHADTAU_EFF_ELEOLR_TOTAL__1down"}, + {TAUS_TRUEELECTRON_EFF_ELEOLR_STAT__1up, "TAUS_TRUEELECTRON_EFF_ELEOLR_STAT__1up"}, + {TAUS_TRUEELECTRON_EFF_ELEOLR_STAT__1down, "TAUS_TRUEELECTRON_EFF_ELEOLR_STAT__1down"}, + {TAUS_TRUEELECTRON_EFF_ELEOLR_SYST__1up, "TAUS_TRUEELECTRON_EFF_ELEOLR_SYST__1up"}, + {TAUS_TRUEELECTRON_EFF_ELEOLR_SYST__1down, "TAUS_TRUEELECTRON_EFF_ELEOLR_SYST__1down"}, + }; + + const std::map<topSFSyst, TString> tauSF_alias = { + {TAU_SF_NOMINAL, "TAU_SF_NOMINAL"}, + {TAUS_TRUEHADTAU_EFF_RECO_TOTAL__1up, "EFF_RECO_TOTAL_UP"}, + {TAUS_TRUEHADTAU_EFF_RECO_TOTAL__1down, "EFF_RECO_TOTAL_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2025__1up, "EFF_RNNID_1PRONGSTATSYSTPT2025_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2025__1down, "EFF_RNNID_1PRONGSTATSYSTPT2025_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2530__1up, "EFF_RNNID_1PRONGSTATSYSTPT2530_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT2530__1down, "EFF_RNNID_1PRONGSTATSYSTPT2530_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT3040__1up, "EFF_RNNID_1PRONGSTATSYSTPT3040_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPT3040__1down, "EFF_RNNID_1PRONGSTATSYSTPT3040_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPTGE40__1up, "EFF_RNNID_1PRONGSTATSYSTPTGE40_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_1PRONGSTATSYSTPTGE40__1down, "EFF_RNNID_1PRONGSTATSYSTPTGE40_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2025__1up, "EFF_RNNID_1PRONGSTATSYSTPT2025_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2025__1down, "EFF_RNNID_3PRONGSTATSYSTPT2025_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2530__1up, "EFF_RNNID_3PRONGSTATSYSTPT2530_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT2530__1down, "EFF_RNNID_3PRONGSTATSYSTPT2530_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT3040__1up, "EFF_RNNID_3PRONGSTATSYSTPT3040_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPT3040__1down, "EFF_RNNID_3PRONGSTATSYSTPT3040_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPTGE40__1up, "EFF_RNNID_3PRONGSTATSYSTPTGE40_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_3PRONGSTATSYSTPTGE40__1down, "EFF_RNNID_3PRONGSTATSYSTPTGE40_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_HIGHPT__1up, "EFF_RNNID_HIGHPT_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_HIGHPT__1down, "EFF_RNNID_HIGHPT_DOWN"}, + {TAUS_TRUEHADTAU_EFF_RNNID_SYST__1up, "EFF_RNNID_SYST_UP"}, + {TAUS_TRUEHADTAU_EFF_RNNID_SYST__1down, "EFF_RNNID_SYST_DOWN"}, + {TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETAHIGH__1up, "EFF_JETID_1PETAHIGH_UP"}, + {TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETAHIGH__1down, "EFF_JETID_1PETAHIGH_DOWN"}, + {TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETALOW__1up, "EFF_JETID_1PETALOW_UP"}, + {TAUS_TRUEHADTAU_EFF_JETID_1PRONGSTATSYSTETALOW__1down, "EFF_JETID_1PETALOW_DOWN"}, + {TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETAHIGH__1up, "EFF_JETID_3PETAHIGH_UP"}, + {TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETAHIGH__1down, "EFF_JETID_3PETAHIGH_DOWN"}, + {TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETALOW__1up, "EFF_JETID_3PETALOW_UP"}, + {TAUS_TRUEHADTAU_EFF_JETID_3PRONGSTATSYSTETALOW__1down, "EFF_JETID_3PETALOW_DOWN"}, + {TAUS_TRUEHADTAU_EFF_JETID_SYST__1up, "EFF_JETID_SYST_UP"}, + {TAUS_TRUEHADTAU_EFF_JETID_SYST__1down, "EFF_JETID_SYST_DOWN"}, + {TAUS_TRUEHADTAU_EFF_JETID_HIGHPT__1up, "EFF_JETID_HIGHPT_UP"}, + {TAUS_TRUEHADTAU_EFF_JETID_HIGHPT__1down, "EFF_JETID_HIGHPT_DOWN"}, + {TAUS_TRUEHADTAU_EFF_ELEOLR_TOTAL__1up, "EFF_ELEOLR_TOTAL_UP"}, + {TAUS_TRUEHADTAU_EFF_ELEOLR_TOTAL__1down, "EFF_ELEOLR_TOTAL_DOWN"}, + {TAUS_TRUEELECTRON_EFF_ELEOLR_STAT__1up, "ELE_EFF_ELEOLR_STAT_UP"}, + {TAUS_TRUEELECTRON_EFF_ELEOLR_STAT__1down, "ELE_EFF_ELEOLR_STAT_DOWN"}, + {TAUS_TRUEELECTRON_EFF_ELEOLR_SYST__1up, "ELE_EFF_ELEOLR_SYST_UP"}, + {TAUS_TRUEELECTRON_EFF_ELEOLR_SYST__1down, "ELE_EFF_ELEOLR_SYST_DOWN"}, + }; + + + enum topSFComp { + ALL = 0, TRIGGER, RECO, ID, ISOLATION, CHARGEID, CHARGEMISID, TTVA + }; + + class ScaleFactorRetriever final: public asg::AsgTool { + // Specify that we will overload print with top::Event later on + using asg::AsgTool::print; + public: + explicit ScaleFactorRetriever(const std::string& name); + virtual ~ScaleFactorRetriever() {} + + // Delete Standard constructors + ScaleFactorRetriever(const ScaleFactorRetriever& rhs) = delete; + ScaleFactorRetriever(ScaleFactorRetriever&& rhs) = delete; + ScaleFactorRetriever& operator = (const ScaleFactorRetriever& rhs) = delete; + + StatusCode initialize(); + + // Pile up SF + static bool hasPileupSF(const top::Event& event); + static float pileupSF(const top::Event& event, int var = 0); + + // Obtain the lepton SF + float leptonSF(const top::Event& event, const top::topSFSyst SFSyst) const; + + // Obtain the trigger SF + float triggerSF(const top::Event& event, const top::topSFSyst SFSyst) const; + + // Obtain trigger SF via global tool + float globalTriggerSF(const top::Event& event, const top::topSFSyst SFSyst) const; + + // Obtain the trigger SF via approximate formula + float oldTriggerSF(const top::Event& event, const top::topSFSyst SFSyst) const; + + // Obtain the electron SF + float electronSF(const top::Event& event, + const top::topSFSyst SFSyst, + const top::topSFComp SFComp) const; + + //get vector of systematic variations of electron SFs, var=1 for up, var=-1 for down + std::vector<float> electronSFSystVariationVector(const top::Event& event, const top::topSFComp SFComp, int var = 1) const; + + // Obtain the fwd electron SF + float fwdElectronSF(const top::Event& event, + const top::topSFSyst SFSyst, + const top::topSFComp SFComp = top::topSFComp::ALL) const; - float electronSF_Trigger(const xAOD::Electron& x, const top::topSFSyst SFSyst, bool isLoose) const; + // Obtain the muon SF + float muonSF(const top::Event& event, + const top::topSFSyst SFSyst, + const top::topSFComp SFComp) const; - float electronEff_Trigger(const xAOD::Electron& x, const top::topSFSyst SFSyst, bool isLoose) const ; + // Obtain the soft muon SF + float softmuonSF(const top::Event& event, + const top::topSFSyst SFSyst, + const top::topSFComp SFComp) const; - float electronSF_ID(const xAOD::Electron& x, - const top::topSFSyst SFSyst, - bool isLoose) const; + /** + * @brief: get the tauSF for all taus in event + * @param: event, a top::Event object + * @param: SFSyst, systematic variation enum + */ + float tauSF(const top::Event& event, + const top::topSFSyst SFSyst) const; + + /** + * @brief: get the photonSF for all photons in event + * @param: event, a top::Event object + * @param: SFSyst, systematic variation enum + */ + float photonSF(const top::Event& event, + const top::topSFSyst SFSyst) const; - float electronSF_Isol(const xAOD::Electron& x, + /** + * @brief Missing important functionality, but testing... + */ + float btagSF(const top::Event& event, + const top::topSFSyst SFSyst = top::topSFSyst::nominal, + std::string WP = "FixedCutBEff_77", + bool do_trackjets = false, + std::string uncert_name = "") const; + + void btagSF_eigen_vars(const top::Event& event, + const top::topSFSyst SFSyst, + std::vector<float>& btagSF_up, + std::vector<float>& btagSF_down, + std::string WP = "FixedCutBEff_77", + bool do_trackjets = false) const; + + /** + * + * JVT Efficiency SFs + * @brief: Get the total JVT SF by taking the product of SFs for all jets + * + * @param: event, a top::Event object + * @param: SFSyst, systematic variation enum + * + * @return: prod_jvt, the product of the jvt SFs for selected jets + * + **/ + float jvtSF(const top::Event& event, + const top::topSFSyst SFsyst) const; + + /** + * + * fJVT Efficiency SFs + * @brief: Get the total fJVT SF by taking the product of SFs for all jets, as of AnalysisBase124 by default central jets get a SF value of 1 + * + * @param: event, a top::Event object + * @param: SFSyst, systematic variation enum + * + * @return: prod_fjvt, the product of the fjvt SFs for selected jets + * + **/ + float fjvtSF(const top::Event& event, + const top::topSFSyst SFsyst) const; + + /** + * @brief Print all the SF values to msg stream + */ + void print(const top::Event& event); + + float electronSF_Reco(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const; + + float electronSF_Trigger(const xAOD::Electron& x, const top::topSFSyst SFSyst, bool isLoose) const; + + float electronEff_Trigger(const xAOD::Electron& x, const top::topSFSyst SFSyst, bool isLoose) const; + + float electronSF_ID(const xAOD::Electron& x, const top::topSFSyst SFSyst, bool isLoose) const; - float electronSF_ChargeID(const xAOD::Electron& x, - const top::topSFSyst SFSyst, - bool isLoose) const; + float electronSF_Isol(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const; + + float electronSF_ChargeID(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const; - float electronSF_ChargeMisID(const xAOD::Electron& x, - const top::topSFSyst SFSyst, - bool isLoose) const; + float electronSF_ChargeMisID(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const; - float muonSF_Trigger(const xAOD::Muon& x, - const top::topSFSyst SFSyst, - bool isLoose) const; + float fwdElectronSF_ID(const xAOD::Electron& x, + const top::topSFSyst SFSyst, + bool isLoose) const; - float muonEff_Trigger(const xAOD::Muon& x, - const top::topSFSyst SFSyst, - bool isLoose) const; + float muonSF_Trigger(const xAOD::Muon& x, + const top::topSFSyst SFSyst, + bool isLoose) const; - float muonSF_ID(const xAOD::Muon& x, - const top::topSFSyst SFSyst, - bool isLoose) const; + float muonEff_Trigger(const xAOD::Muon& x, + const top::topSFSyst SFSyst, + bool isLoose) const; - float muonSF_Isol(const xAOD::Muon& x, + float muonSF_ID(const xAOD::Muon& x, const top::topSFSyst SFSyst, bool isLoose) const; - float muonSF_TTVA(const xAOD::Muon& x, - const top::topSFSyst SFSyst) const; - - /** - * @brief: get the tauSF for a single tau - * @param: x, an xAOD::TauJet object - * @param: SFSyst, systematic variation enum - * @param: whether you want the SF for loose event or not - */ - float tauSF(const xAOD::TauJet& x, - const top::topSFSyst SFSyst, - bool isLoose) const; - - /** - * @brief: get the photonSF for a single photon - * @param: x, an xAOD::Photon object - * @param: SFSyst, systematic variation enum - * @param: whether you want the SF for loose event or not - */ - float photonSF(const xAOD::Photon& x, - const top::topSFSyst SFSyst, - bool isLoose) const; - - float photonSF_Isol(const xAOD::Photon& x, + float muonSF_Isol(const xAOD::Muon& x, const top::topSFSyst SFSyst, bool isLoose) const; - private: - float electronSF_Trigger(const xAOD::Electron& x, - const std::string& id, - const top::topSFSyst SFSyst) const; + float muonSF_TTVA(const xAOD::Muon& x, + const top::topSFSyst SFSyst) const; - float electronEff_Trigger(const xAOD::Electron& x, - const std::string& id, - const top::topSFSyst SFSyst) const; + float softmuonSF_ID(const xAOD::Muon& x, + const top::topSFSyst SFSyst) const; - float electronSF_ID(const xAOD::Electron& x, - const std::string& id, - const top::topSFSyst SFSyst) const; + /** + * @brief: get the tauSF for a single tau + * @param: x, an xAOD::TauJet object + * @param: SFSyst, systematic variation enum + * @param: whether you want the SF for loose event or not + */ + float tauSF(const xAOD::TauJet& x, + const top::topSFSyst SFSyst, + bool isLoose) const; - float electronSF_Isol(const xAOD::Electron& x, + /** + * @brief: get the photonSF for a single photon + * @param: x, an xAOD::Photon object + * @param: SFSyst, systematic variation enum + */ + float photonSF_Reco(const xAOD::Photon& x, + const top::topSFSyst SFSyst) const; + + float photonSF_Isol(const xAOD::Photon& x, + const top::topSFSyst SFSyst, + bool isLoose) const; + private: + float electronSF_Trigger(const xAOD::Electron& x, + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const; + + float electronEff_Trigger(const xAOD::Electron& x, + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const; + + float electronSF_ID(const xAOD::Electron& x, const std::string& id, - const top::topSFSyst SFSyst) const; + const top::topSFSyst SFSyst, + bool isLoose) const; - float electronSF_ChargeID(const xAOD::Electron& x, - const std::string& id, const std::string& iso, - const top::topSFSyst SFSyst) const; + float electronSF_Isol(const xAOD::Electron& x, + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const; - float electronSF_ChargeMisID(const xAOD::Electron& x, - const std::string& id, const std::string& iso, - const top::topSFSyst SFSyst) const; + float electronSF_ChargeID(const xAOD::Electron& x, + const std::string& id, const std::string& iso, + const top::topSFSyst SFSyst, + bool isLoose) const; - float photonSF_Isol(const xAOD::Photon& x, - const std::string& iso, - const top::topSFSyst SFSyst) const; + float electronSF_ChargeMisID(const xAOD::Electron& x, + const std::string& id, const std::string& iso, + const top::topSFSyst SFSyst, + bool isLoose) const; - float muonSF_Trigger(const xAOD::Muon& x, - const std::string& id, - const top::topSFSyst SFSyst) const; - float muonEff_Trigger(const xAOD::Muon& x, - const std::string& id, - const top::topSFSyst SFSyst) const; + float fwdElectronSF_ID(const xAOD::Electron& x, + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const; - float muonSF_ID(const xAOD::Muon& x, - const std::string& id, - const top::topSFSyst SFSyst) const; + float photonSF_Isol(const xAOD::Photon& x, + const std::string& iso, + const top::topSFSyst SFSyst, + bool isLoose) const; - float muonSF_Isol(const xAOD::Muon& x, - const std::string& iso, - const top::topSFSyst SFSyst) const; + float muonSF_Trigger(const xAOD::Muon& x, + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const; + float muonEff_Trigger(const xAOD::Muon& x, + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const; + + float muonSF_ID(const xAOD::Muon& x, + const std::string& id, + const top::topSFSyst SFSyst, + bool isLoose) const; - float m_event_el_trigger; + float softmuonSF_ID(const xAOD::Muon& x, + const std::string& id, + const top::topSFSyst SFSyst) const; - // List of triggers to 'or' together for each event. - // If any one passes, the event passes - std::vector<std::string> m_electronTriggers; - std::vector<std::string> m_muonTriggers; - // Do we need to add tau triggers? + float muonSF_Isol(const xAOD::Muon& x, + const std::string& iso, + const top::topSFSyst SFSyst, + bool isLoose) const; - // Configuration - std::shared_ptr<top::TopConfig> m_config; -}; + // List of triggers to 'or' together for each event. + // If any one passes, the event passes + std::vector<std::string> m_electronTriggers_Tight; + std::vector<std::string> m_muonTriggers_Tight; + std::vector<std::string> m_electronTriggers_Loose; + std::vector<std::string> m_muonTriggers_Loose; + // Do we need to add tau triggers? + + // Configuration + std::shared_ptr<top::TopConfig> m_config; + bool m_preferGlobalTriggerSF; + }; } // namespace top #endif // SCALEFACTORRETRIEVER_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/TauScaleFactorCalculator.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/TauScaleFactorCalculator.h index abaff879c46c..5181619c290d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/TauScaleFactorCalculator.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/TauScaleFactorCalculator.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: TauScaleFactorCalculator.h 718402 2016-01-19 11:58:25Z tneep $ #ifndef ANALYSISTOP_TOPCORRECTIONS_TAUSCALEFACTORCALCULATOR_H #define ANALYSISTOP_TOPCORRECTIONS_TAUSCALEFACTORCALCULATOR_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief TauScaleFactorCalculator - * Calculate all tau scale factors and decorate - * - * $Revision: 718402 $ - * $Date: 2016-01-19 12:58:25 +0100 (Tue, 19 Jan 2016) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief TauScaleFactorCalculator + * Calculate all tau scale factors and decorate + * + * $Revision: 718402 $ + * $Date: 2016-01-19 11:58:25 +0000 (Tue, 19 Jan 2016) $ + * + **/ // system include(s): #include <memory> @@ -34,32 +34,30 @@ // Forward declaration(s): namespace top { -class TopConfig; + class TopConfig; } namespace top { - -class TauScaleFactorCalculator final : public asg::AsgTool { - public: - explicit TauScaleFactorCalculator(const std::string& name); - virtual ~TauScaleFactorCalculator() {} - - // Delete Standard constructors - TauScaleFactorCalculator(const TauScaleFactorCalculator& rhs) = delete; - TauScaleFactorCalculator(TauScaleFactorCalculator&& rhs) = delete; - TauScaleFactorCalculator& operator=(const TauScaleFactorCalculator& rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - ToolHandle<TauAnalysisTools::ITauEfficiencyCorrectionsTool> m_tauEffCorrTool; - ToolHandle<TauAnalysisTools::ITauEfficiencyCorrectionsTool> m_tauEffCorrToolLoose; - - CP::SystematicSet m_systNominal; - std::map< std::string, CP::SystematicSet > m_syst_map; -}; + class TauScaleFactorCalculator final: public asg::AsgTool { + public: + explicit TauScaleFactorCalculator(const std::string& name); + virtual ~TauScaleFactorCalculator() {} + + // Delete Standard constructors + TauScaleFactorCalculator(const TauScaleFactorCalculator& rhs) = delete; + TauScaleFactorCalculator(TauScaleFactorCalculator&& rhs) = delete; + TauScaleFactorCalculator& operator = (const TauScaleFactorCalculator& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(); + private: + std::shared_ptr<top::TopConfig> m_config; + + ToolHandle<TauAnalysisTools::ITauEfficiencyCorrectionsTool> m_tauEffCorrTool; + ToolHandle<TauAnalysisTools::ITauEfficiencyCorrectionsTool> m_tauEffCorrToolLoose; + + CP::SystematicSet m_systNominal; + std::map< std::string, CP::SystematicSet > m_syst_map; + }; } // namespace top #endif // ANALYSISTOP_TOPCORRECTIONS_TAUSCALEFACTORCALCULATOR_H diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/TopCorrectionsTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/TopCorrectionsTools.h new file mode 100644 index 000000000000..e42a1f12023b --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/TopCorrections/TopCorrectionsTools.h @@ -0,0 +1,21 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TOPTOPCORRECTIONTOOLS_H__ +#define TOPTOPCORRECTIONTOOLS_H__ + +#include "TopConfiguration/TopConfig.h" +#include <string> + +namespace top { + // Functions useful for b-tagging systematic name mapping + std::string bTagNamedSystCheck(std::shared_ptr<top::TopConfig>, + const std::string&, + const std::string&, + const bool, + const bool); + std::string betterBtagNamedSyst(const std::string&); +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt index ef2ff4ab1deb..d2754af30015 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt @@ -1,6 +1,7 @@ +# Auto-generated on: 2017-03-08 14:47:36.020351 # Declare the name of this package: -atlas_subdir( TopEvent ) +atlas_subdir( TopEvent None ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -17,17 +18,25 @@ atlas_depends_on_subdirs( PUBLIC xAODTau xAODMissingET xAODTracking + FourMomUtils TopConfiguration - TopPartons ) + TopPartons + JetAnalysisInterfaces + JetSubStructureMomentTools + JetSubStructureUtils + JetReclustering ) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) +# Need fast jet for the RC jet substructure code +find_package( FastJet COMPONENTS fastjetplugins fastjettools ) +find_package( FastJetContrib COMPONENTS EnergyCorrelator Nsubjettiness ) + # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopEvent _cintDictSource - ROOT_HEADERS TopEvent/SystematicEvent.h TopEvent/KLFitterResult.h - TopEvent/PseudoTopResult.h Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) # Build a library that other components can link against: atlas_add_library( TopEvent Root/*.cxx Root/*.h Root/*.icc @@ -47,8 +56,15 @@ atlas_add_library( TopEvent Root/*.cxx Root/*.h Root/*.icc xAODTau xAODMissingET xAODTracking + FourMomUtils TopConfiguration TopPartons + JetAnalysisInterfacesLib + JetSubStructureMomentToolsLib + JetSubStructureUtils + JetReclusteringLib + ${FASTJET_LIBRARIES} + ${FASTJETCONTRIB_LIBRARIES} ${ROOT_LIBRARIES} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/Event.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/Event.cxx index 64ed39fdfb13..d5832af222dc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/Event.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/Event.cxx @@ -1,66 +1,88 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEvent/Event.h" #include "TopEvent/EventTools.h" #include "xAODEventInfo/EventInfo.h" #include "xAODEgamma/ElectronContainer.h" +#include "xAODEgamma/ElectronContainerFwd.h" #include "xAODMuon/MuonContainer.h" #include "xAODJet/JetContainer.h" #include "xAODTau/TauJetContainer.h" #include "xAODMissingET/MissingETContainer.h" +#include "xAODTracking/TrackParticleContainer.h" #include "xAODTruth/TruthParticleContainer.h" #include "xAODTruth/TruthVertex.h" #include "xAODCore/ShallowCopy.h" #include <iomanip> -std::ostream& operator<<(std::ostream& os, const TLorentzVector& v) { - os << "TLorentzVector" << - " pt=" << v.Pt() << - " eta " << v.Eta() << - " phi " << v.Phi() << - " m " << v.M(); +std::ostream & operator << (std::ostream& os, const TLorentzVector& v) { + os << "TLorentzVector" << + " pt=" << v.Pt() << + " eta " << v.Eta() << + " phi " << v.Phi() << + " m " << v.M(); - return os; + return os; } -std::ostream& operator<<(std::ostream& os, const top::Event& event) { - +std::ostream& operator << (std::ostream& os, const top::Event& event) { // os << *event.m_info << "\n"; - os << "Electrons: " << event.m_electrons.size() << "\n"; - for (const auto* const elPtr : event.m_electrons) - os << " " << *elPtr << "\n"; - - os << "Muons: " << event.m_muons.size() << "\n"; - for (const auto* const muPtr : event.m_muons) - os << " " << *muPtr << "\n"; - - os << "Jets: " << event.m_jets.size() << "\n"; - for (const auto* const jetPtr : event.m_jets) - os << " " << *jetPtr << "\n"; - - os << "Large jets: " << event.m_largeJets.size() << "\n"; - for (const auto* const jetPtr : event.m_largeJets) - os << " " << *jetPtr << "\n"; - - os << "Track jets: " << event.m_trackJets.size() << "\n"; - for (const auto* const jetPtr : event.m_trackJets) - os << " " << *jetPtr << "\n"; - - os << "Taus: " << event.m_tauJets.size() << "\n"; - for (const auto* const tauPtr : event.m_tauJets) - os << " " << *tauPtr << "\n"; - - os << *event.m_met; - return os; + os << "Electrons: " << event.m_electrons.size() << "\n"; + for (const auto* const elPtr : event.m_electrons) { + os << " " << *elPtr << "\n"; + } + os << "FwdElectrons: " << event.m_fwdElectrons.size() << "\n"; + for (const auto* const elPtr : event.m_fwdElectrons) { + os << " " << *elPtr << "\n"; + } + os << "Muons: " << event.m_muons.size() << "\n"; + for (const auto* const muPtr : event.m_muons) { + os << " " << *muPtr << "\n"; + } + os << "Soft Muons: " << event.m_softmuons.size() << "\n"; + for (const auto* const muPtr : event.m_softmuons) { + os << " " << *muPtr << "\n"; + } + os << "Jets: " << event.m_jets.size() << "\n"; + for (const auto* const jetPtr : event.m_jets) { + os << " " << *jetPtr << "\n"; + } + os << "Fail-JVT jets: " << event.m_failJvt_jets.size() << "\n"; + for (const auto* const jetPtr : event.m_failJvt_jets) { + os << " " << *jetPtr << "\n"; + } + os << "Fail-FJVT jets: " << event.m_failFJvt_jets.size() << "\n"; + for (const auto* const jetPtr : event.m_failFJvt_jets) { + os << " " << *jetPtr << "\n"; + } + os << "Large jets: " << event.m_largeJets.size() << "\n"; + for (const auto* const jetPtr : event.m_largeJets) { + os << " " << *jetPtr << "\n"; + } + os << "Track jets: " << event.m_trackJets.size() << "\n"; + for (const auto* const jetPtr : event.m_trackJets) { + os << " " << *jetPtr << "\n"; + } + os << "Tracks: " << event.m_tracks.size() << "\n"; + for (const auto* const trackPtr : event.m_tracks) { + os << " " << *trackPtr << "\n"; + } + os << "Taus: " << event.m_tauJets.size() << "\n"; + for (const auto* const tauPtr : event.m_tauJets) { + os << " " << *tauPtr << "\n"; + } + os << "MET: " << *event.m_met << "\n"; + + return os; } /* -std::ostream& operator<<(std::ostream& os, const xAOD::EventInfo& ei) { + std::ostream& operator<<(std::ostream& os, const xAOD::EventInfo& ei) { os << "EventInfo" << " isSimulation " << std::boolalpha << ei.eventType(xAOD::EventInfo::IS_SIMULATION) << " runNumber " << ei.runNumber() << @@ -73,73 +95,83 @@ std::ostream& operator<<(std::ostream& os, const xAOD::EventInfo& ei) { } return os; -}*/ + }*/ + +std::ostream& operator << (std::ostream& os, const xAOD::Electron& el) { + os << "Electron" << + " author " << el.author() << + " pt " << el.pt() << + " eta " << el.eta() << + " phi " << el.phi() << + " m " << el.m() << + " charge " << el.charge(); + + return os; +} -std::ostream& operator<<(std::ostream& os, const xAOD::Electron& el) { - os << "Electron" << - " author " << el.author() << - " pt " << el.pt() << - " eta " << el.eta() << - " phi " << el.phi() << - " m " << el.m() << - " charge " << el.charge(); +std::ostream& operator << (std::ostream& os, const xAOD::Muon& mu) { + os << "Muon" << + " author " << mu.author() << + " pt " << mu.pt() << + " eta " << mu.eta() << + " phi " << mu.phi() << + " m " << mu.m() << + " charge " << mu.charge(); - return os; + return os; } -std::ostream& operator<<(std::ostream& os, const xAOD::Muon& mu) { - os << "Muon" << - " author " << mu.author() << - " pt " << mu.pt() << - " eta " << mu.eta() << - " phi " << mu.phi() << - " m " << mu.m() << - " charge " << mu.charge(); +std::ostream& operator << (std::ostream& os, const xAOD::Jet& jet) { + os << "Jet" << + " pt " << jet.pt() << + " eta " << jet.eta() << + " phi " << jet.phi() << + " m " << jet.m(); - return os; + return os; } -std::ostream& operator<<(std::ostream& os, const xAOD::Jet& jet) { - os << "Jet" << - " pt " << jet.pt() << - " eta " << jet.eta() << - " phi " << jet.phi() << - " m " << jet.m(); +std::ostream& operator << (std::ostream& os, const xAOD::TauJet& tau) { + os << "TauJet" << + " pt " << tau.pt() << + " eta " << tau.eta() << + " phi " << tau.phi() << + " m " << tau.m() << + " charge " << tau.charge(); - return os; + return os; } -std::ostream& operator<<(std::ostream& os, const xAOD::TauJet& tau) { - os << "TauJet" << - " pt " << tau.pt() << - " eta " << tau.eta() << - " phi " << tau.phi() << - " m " << tau.m() << - " charge " << tau.charge(); +std::ostream& operator << (std::ostream& os, const xAOD::TrackParticle& track) { + os << "Track" << + " pt " << track.pt() << + " eta " << track.eta() << + " phi " << track.phi() << + " m " << track.m(); - return os; + return os; } -std::ostream& operator<<(std::ostream& os, const xAOD::TruthParticle& truth) { - const unsigned int w = 10; - os << "TruthParticle" << - " pdg " << std::setw(w) << truth.pdgId() << - " status " << std::setw(w) << truth.status() << - " pt " << std::setw(w) << truth.pt() << - " eta " << std::setw(w) << truth.eta() << - " phi " << std::setw(w) << truth.phi() << - " e " << std::setw(w) << truth.e() << - " m " << std::setw(w) << truth.p4().M(); - return os; -} +std::ostream& operator << (std::ostream& os, const xAOD::TruthParticle& truth) { + const unsigned int w = 10; -std::ostream& operator<<(std::ostream& os, const xAOD::MissingET& met) { - os << "MET" << - " et " << met.met() << - " phi " << met.phi() << "\n"; + os << "TruthParticle" << + " pdg " << std::setw(w) << truth.pdgId() << + " status " << std::setw(w) << truth.status() << + " pt " << std::setw(w) << truth.pt() << + " eta " << std::setw(w) << truth.eta() << + " phi " << std::setw(w) << truth.phi() << + " e " << std::setw(w) << truth.e() << + " m " << std::setw(w) << truth.p4().M(); - return os; + return os; } +std::ostream& operator << (std::ostream& os, const xAOD::MissingET& met) { + os << "MET" << + " et " << met.met() << + " phi " << met.phi() << "\n"; + return os; +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/EventTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/EventTools.cxx index 97443dcd43a9..c43460f98efe 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/EventTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/EventTools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEvent/EventTools.h" #include "TopEvent/Event.h" @@ -9,51 +9,65 @@ #include "xAODBase/IParticle.h" -namespace top { +#include "TRandom3.h" -void check(bool thingToCheck, const std::string& usefulFailureMessage) { +namespace top { + void check(bool thingToCheck, const std::string& usefulFailureMessage) { if (!thingToCheck) { - std::cout << usefulFailureMessage << "\n"; - exit(1); + throw std::runtime_error("top::check: " + usefulFailureMessage); } -} + } -double deltaR(const xAOD::IParticle& p1, const xAOD::IParticle& p2) { + double deltaR(const xAOD::IParticle& p1, const xAOD::IParticle& p2) { return p1.p4().DeltaR(p2.p4()); -} + } -double deltaPhi(const xAOD::IParticle& p1, const xAOD::IParticle& p2) { + double deltaPhi(const xAOD::IParticle& p1, const xAOD::IParticle& p2) { return p1.p4().DeltaPhi(p2.p4()); -} + } -double mwt(const xAOD::IParticle& lepton, const xAOD::MissingET& met) { + double mwt(const xAOD::IParticle& lepton, const xAOD::MissingET& met) { return sqrt(2. * lepton.pt() * met.met() * (1. - cos(lepton.phi() - met.phi()))); -} + } -double ht(const top::Event& event) { + double ht(const top::Event& event) { double sumHt = 0.; + for (const auto el : event.m_electrons) - sumHt += el->pt(); + sumHt += el->pt(); for (const auto mu : event.m_muons) - sumHt += mu->pt(); + sumHt += mu->pt(); for (const auto jet : event.m_jets) - sumHt += jet->pt(); + sumHt += jet->pt(); return sumHt; -} + } -double invariantMass(const xAOD::IParticle& p1, const xAOD::IParticle& p2) { + double invariantMass(const xAOD::IParticle& p1, const xAOD::IParticle& p2) { return (p1.p4() + p2.p4()).M(); -} + } -bool isSimulation(const top::Event& event) { + bool isSimulation(const top::Event& event) { return event.m_info->eventType(xAOD::EventInfo::IS_SIMULATION); -} + } -bool descendingPtSorter(const xAOD::IParticle* p1, const xAOD::IParticle* p2) { + bool descendingPtSorter(const xAOD::IParticle* p1, const xAOD::IParticle* p2) { return CxxUtils::fpcompare::greater(p1->pt(), p2->pt()); -} + } + + std::vector<int> calculateBootstrapWeights(int nreplicas, int eventNumber, int mcChannelNumber) { + TRandom3 rand; + unsigned long long seed = eventNumber + 100 * mcChannelNumber; // Set the seed to be unique for this event, but + // reproducible for systematics + rand.SetSeed(seed); + std::vector<int> weight_poisson(nreplicas, 0); // Initialise vector of length nreplicas, to all have weight of 0 + for (int i = 0; i < nreplicas; i++) { + weight_poisson.at(i) = rand.PoissonD(1); // Fill with a weight drawn from Poisson distribution with mean of 1 + } + // Return the vector to be stored in top::Event + return weight_poisson; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/KLFitterResult.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/KLFitterResult.cxx index 24e16d26812f..51b14390ff49 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/KLFitterResult.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/KLFitterResult.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: SystematicEvent.cxx 661144 2015-04-17 09:09:07Z morrisj $ #include "TopEvent/KLFitterResult.h" @@ -9,135 +9,240 @@ #include "xAODCore/AuxStoreAccessorMacros.h" #include "xAODCore/AddDVProxy.h" -namespace xAOD{ +namespace xAOD { // Aux Container KLFitterResultAuxContainer::KLFitterResultAuxContainer() : - AuxContainerBase() - { - AUX_VARIABLE( minuitDidNotConverge ); - AUX_VARIABLE( fitAbortedDueToNaN ); - AUX_VARIABLE( atLeastOneFitParameterAtItsLimit ); - AUX_VARIABLE( invalidTransferFunctionAtConvergence ); - - AUX_VARIABLE( bestPermutation ); - AUX_VARIABLE( logLikelihood ); - AUX_VARIABLE( eventProbability ); - AUX_VARIABLE( parameters ); - AUX_VARIABLE( parameterErrors ); - - AUX_VARIABLE( model_bhad_pt ); - AUX_VARIABLE( model_bhad_eta ); - AUX_VARIABLE( model_bhad_phi ); - AUX_VARIABLE( model_bhad_E ); - AUX_VARIABLE( model_bhad_jetIndex ); - - AUX_VARIABLE( model_blep_pt ); - AUX_VARIABLE( model_blep_eta ); - AUX_VARIABLE( model_blep_phi ); - AUX_VARIABLE( model_blep_E ); - AUX_VARIABLE( model_blep_jetIndex ); - - AUX_VARIABLE( model_lq1_pt ); - AUX_VARIABLE( model_lq1_eta ); - AUX_VARIABLE( model_lq1_phi ); - AUX_VARIABLE( model_lq1_E ); - AUX_VARIABLE( model_lq1_jetIndex ); - - AUX_VARIABLE( model_lq2_pt ); - AUX_VARIABLE( model_lq2_eta ); - AUX_VARIABLE( model_lq2_phi ); - AUX_VARIABLE( model_lq2_E ); - AUX_VARIABLE( model_lq2_jetIndex ); - - AUX_VARIABLE( model_Higgs_b1_pt ); - AUX_VARIABLE( model_Higgs_b1_eta ); - AUX_VARIABLE( model_Higgs_b1_phi ); - AUX_VARIABLE( model_Higgs_b1_E ); - AUX_VARIABLE( model_Higgs_b1_jetIndex ); - - AUX_VARIABLE( model_Higgs_b2_pt ); - AUX_VARIABLE( model_Higgs_b2_eta ); - AUX_VARIABLE( model_Higgs_b2_phi ); - AUX_VARIABLE( model_Higgs_b2_E ); - AUX_VARIABLE( model_Higgs_b2_jetIndex ); - - AUX_VARIABLE( model_lep_pt ); - AUX_VARIABLE( model_lep_eta ); - AUX_VARIABLE( model_lep_phi ); - AUX_VARIABLE( model_lep_E ); - - AUX_VARIABLE( model_nu_pt ); - AUX_VARIABLE( model_nu_eta ); - AUX_VARIABLE( model_nu_phi ); - AUX_VARIABLE( model_nu_E ); - - + AuxContainerBase() { + AUX_VARIABLE(selectionCode); + + AUX_VARIABLE(minuitDidNotConverge); + AUX_VARIABLE(fitAbortedDueToNaN); + AUX_VARIABLE(atLeastOneFitParameterAtItsLimit); + AUX_VARIABLE(invalidTransferFunctionAtConvergence); + + AUX_VARIABLE(bestPermutation); + AUX_VARIABLE(logLikelihood); + AUX_VARIABLE(eventProbability); + AUX_VARIABLE(parameters); + AUX_VARIABLE(parameterErrors); + + AUX_VARIABLE(model_bhad_pt); + AUX_VARIABLE(model_bhad_eta); + AUX_VARIABLE(model_bhad_phi); + AUX_VARIABLE(model_bhad_E); + AUX_VARIABLE(model_bhad_jetIndex); + + AUX_VARIABLE(model_blep_pt); + AUX_VARIABLE(model_blep_eta); + AUX_VARIABLE(model_blep_phi); + AUX_VARIABLE(model_blep_E); + AUX_VARIABLE(model_blep_jetIndex); + + AUX_VARIABLE(model_lq1_pt); + AUX_VARIABLE(model_lq1_eta); + AUX_VARIABLE(model_lq1_phi); + AUX_VARIABLE(model_lq1_E); + AUX_VARIABLE(model_lq1_jetIndex); + + AUX_VARIABLE(model_lq2_pt); + AUX_VARIABLE(model_lq2_eta); + AUX_VARIABLE(model_lq2_phi); + AUX_VARIABLE(model_lq2_E); + AUX_VARIABLE(model_lq2_jetIndex); + + AUX_VARIABLE(model_Higgs_b1_pt); + AUX_VARIABLE(model_Higgs_b1_eta); + AUX_VARIABLE(model_Higgs_b1_phi); + AUX_VARIABLE(model_Higgs_b1_E); + AUX_VARIABLE(model_Higgs_b1_jetIndex); + + AUX_VARIABLE(model_Higgs_b2_pt); + AUX_VARIABLE(model_Higgs_b2_eta); + AUX_VARIABLE(model_Higgs_b2_phi); + AUX_VARIABLE(model_Higgs_b2_E); + AUX_VARIABLE(model_Higgs_b2_jetIndex); + + AUX_VARIABLE(model_lep_pt); + AUX_VARIABLE(model_lep_eta); + AUX_VARIABLE(model_lep_phi); + AUX_VARIABLE(model_lep_E); + AUX_VARIABLE(model_lep_index); + + AUX_VARIABLE(model_lepZ1_pt); + AUX_VARIABLE(model_lepZ1_eta); + AUX_VARIABLE(model_lepZ1_phi); + AUX_VARIABLE(model_lepZ1_E); + AUX_VARIABLE(model_lepZ1_index); + + AUX_VARIABLE(model_lepZ2_pt); + AUX_VARIABLE(model_lepZ2_eta); + AUX_VARIABLE(model_lepZ2_phi); + AUX_VARIABLE(model_lepZ2_E); + AUX_VARIABLE(model_lepZ2_index); + + AUX_VARIABLE(model_nu_pt); + AUX_VARIABLE(model_nu_eta); + AUX_VARIABLE(model_nu_phi); + AUX_VARIABLE(model_nu_E); + + AUX_VARIABLE(model_b_from_top1_pt); + AUX_VARIABLE(model_b_from_top1_eta); + AUX_VARIABLE(model_b_from_top1_phi); + AUX_VARIABLE(model_b_from_top1_E); + AUX_VARIABLE(model_b_from_top1_jetIndex); + + AUX_VARIABLE(model_b_from_top2_pt); + AUX_VARIABLE(model_b_from_top2_eta); + AUX_VARIABLE(model_b_from_top2_phi); + AUX_VARIABLE(model_b_from_top2_E); + AUX_VARIABLE(model_b_from_top2_jetIndex); + + AUX_VARIABLE(model_lj1_from_top1_pt); + AUX_VARIABLE(model_lj1_from_top1_eta); + AUX_VARIABLE(model_lj1_from_top1_phi); + AUX_VARIABLE(model_lj1_from_top1_E); + AUX_VARIABLE(model_lj1_from_top1_jetIndex); + + AUX_VARIABLE(model_lj2_from_top1_pt); + AUX_VARIABLE(model_lj2_from_top1_eta); + AUX_VARIABLE(model_lj2_from_top1_phi); + AUX_VARIABLE(model_lj2_from_top1_E); + AUX_VARIABLE(model_lj2_from_top1_jetIndex); + + AUX_VARIABLE(model_lj1_from_top2_pt); + AUX_VARIABLE(model_lj1_from_top2_eta); + AUX_VARIABLE(model_lj1_from_top2_phi); + AUX_VARIABLE(model_lj1_from_top2_E); + AUX_VARIABLE(model_lj1_from_top2_jetIndex); + + AUX_VARIABLE(model_lj2_from_top2_pt); + AUX_VARIABLE(model_lj2_from_top2_eta); + AUX_VARIABLE(model_lj2_from_top2_phi); + AUX_VARIABLE(model_lj2_from_top2_E); + AUX_VARIABLE(model_lj2_from_top2_jetIndex); } - + /// Interface class KLFitterResult::KLFitterResult() : - SG::AuxElement() - { - } - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , short , minuitDidNotConverge , setMinuitDidNotConverge ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , short , fitAbortedDueToNaN , setFitAbortedDueToNaN ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , short , atLeastOneFitParameterAtItsLimit , setAtLeastOneFitParameterAtItsLimit ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , short , invalidTransferFunctionAtConvergence , setInvalidTransferFunctionAtConvergence ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , unsigned int , bestPermutation , setBestPermutation ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , logLikelihood , setLogLikelihood ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , eventProbability , setEventProbability ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( KLFitterResult , std::vector<double> , parameters , setParameters ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( KLFitterResult , std::vector<double> , parameterErrors , setParameterErrors ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_bhad_pt , setModel_bhad_pt ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_bhad_eta , setModel_bhad_eta ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_bhad_phi , setModel_bhad_phi ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_bhad_E , setModel_bhad_E ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , unsigned int , model_bhad_jetIndex , setModel_bhad_jetIndex ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_blep_pt , setModel_blep_pt ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_blep_eta , setModel_blep_eta ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_blep_phi , setModel_blep_phi ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_blep_E , setModel_blep_E ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , unsigned int , model_blep_jetIndex , setModel_blep_jetIndex ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lq1_pt , setModel_lq1_pt ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lq1_eta , setModel_lq1_eta ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lq1_phi , setModel_lq1_phi ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lq1_E , setModel_lq1_E ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , unsigned int , model_lq1_jetIndex , setModel_lq1_jetIndex ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lq2_pt , setModel_lq2_pt ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lq2_eta , setModel_lq2_eta ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lq2_phi , setModel_lq2_phi ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lq2_E , setModel_lq2_E ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , unsigned int , model_lq2_jetIndex , setModel_lq2_jetIndex ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_Higgs_b1_pt , setModel_Higgs_b1_pt ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_Higgs_b1_eta , setModel_Higgs_b1_eta ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_Higgs_b1_phi , setModel_Higgs_b1_phi ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_Higgs_b1_E , setModel_Higgs_b1_E ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , unsigned int , model_Higgs_b1_jetIndex , setModel_Higgs_b1_jetIndex ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_Higgs_b2_pt , setModel_Higgs_b2_pt ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_Higgs_b2_eta , setModel_Higgs_b2_eta ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_Higgs_b2_phi , setModel_Higgs_b2_phi ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_Higgs_b2_E , setModel_Higgs_b2_E ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , unsigned int , model_Higgs_b2_jetIndex , setModel_Higgs_b2_jetIndex ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lep_pt , setModel_lep_pt ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lep_eta , setModel_lep_eta ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lep_phi , setModel_lep_phi ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_lep_E , setModel_lep_E ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_nu_pt , setModel_nu_pt ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_nu_eta , setModel_nu_eta ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_nu_phi , setModel_nu_phi ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( KLFitterResult , float , model_nu_E , setModel_nu_E ) - + SG::AuxElement() { + } + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, std::size_t, selectionCode, setSelectionCode) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, short, minuitDidNotConverge, setMinuitDidNotConverge) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, short, fitAbortedDueToNaN, setFitAbortedDueToNaN) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, short, atLeastOneFitParameterAtItsLimit, + setAtLeastOneFitParameterAtItsLimit) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, short, invalidTransferFunctionAtConvergence, + setInvalidTransferFunctionAtConvergence) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, bestPermutation, setBestPermutation) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, logLikelihood, setLogLikelihood) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, eventProbability, setEventProbability) + AUXSTORE_OBJECT_SETTER_AND_GETTER(KLFitterResult, std::vector<double>, parameters, setParameters) + AUXSTORE_OBJECT_SETTER_AND_GETTER(KLFitterResult, std::vector<double>, parameterErrors, setParameterErrors) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_bhad_pt, setModel_bhad_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_bhad_eta, setModel_bhad_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_bhad_phi, setModel_bhad_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_bhad_E, setModel_bhad_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_bhad_jetIndex, setModel_bhad_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_blep_pt, setModel_blep_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_blep_eta, setModel_blep_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_blep_phi, setModel_blep_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_blep_E, setModel_blep_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_blep_jetIndex, setModel_blep_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lq1_pt, setModel_lq1_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lq1_eta, setModel_lq1_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lq1_phi, setModel_lq1_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lq1_E, setModel_lq1_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lq1_jetIndex, setModel_lq1_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lq2_pt, setModel_lq2_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lq2_eta, setModel_lq2_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lq2_phi, setModel_lq2_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lq2_E, setModel_lq2_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lq2_jetIndex, setModel_lq2_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_Higgs_b1_pt, setModel_Higgs_b1_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_Higgs_b1_eta, setModel_Higgs_b1_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_Higgs_b1_phi, setModel_Higgs_b1_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_Higgs_b1_E, setModel_Higgs_b1_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_Higgs_b1_jetIndex, + setModel_Higgs_b1_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_Higgs_b2_pt, setModel_Higgs_b2_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_Higgs_b2_eta, setModel_Higgs_b2_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_Higgs_b2_phi, setModel_Higgs_b2_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_Higgs_b2_E, setModel_Higgs_b2_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_Higgs_b2_jetIndex, + setModel_Higgs_b2_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lep_pt, setModel_lep_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lep_eta, setModel_lep_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lep_phi, setModel_lep_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lep_E, setModel_lep_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lep_index, setModel_lep_index) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lepZ1_pt, setModel_lepZ1_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lepZ1_eta, setModel_lepZ1_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lepZ1_phi, setModel_lepZ1_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lepZ1_E, setModel_lepZ1_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lepZ1_index, setModel_lepZ1_index) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lepZ2_pt, setModel_lepZ2_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lepZ2_eta, setModel_lepZ2_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lepZ2_phi, setModel_lepZ2_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lepZ2_E, setModel_lepZ2_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lepZ2_index, setModel_lepZ2_index) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_nu_pt, setModel_nu_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_nu_eta, setModel_nu_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_nu_phi, setModel_nu_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_nu_E, setModel_nu_E) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_b_from_top1_pt, setModel_b_from_top1_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_b_from_top1_eta, setModel_b_from_top1_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_b_from_top1_phi, setModel_b_from_top1_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_b_from_top1_E, setModel_b_from_top1_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_b_from_top1_jetIndex, + setModel_b_from_top1_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_b_from_top2_pt, setModel_b_from_top2_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_b_from_top2_eta, setModel_b_from_top2_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_b_from_top2_phi, setModel_b_from_top2_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_b_from_top2_E, setModel_b_from_top2_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_b_from_top2_jetIndex, + setModel_b_from_top2_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj1_from_top1_pt, setModel_lj1_from_top1_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj1_from_top1_eta, setModel_lj1_from_top1_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj1_from_top1_phi, setModel_lj1_from_top1_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj1_from_top1_E, setModel_lj1_from_top1_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lj1_from_top1_jetIndex, + setModel_lj1_from_top1_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj2_from_top1_pt, setModel_lj2_from_top1_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj2_from_top1_eta, setModel_lj2_from_top1_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj2_from_top1_phi, setModel_lj2_from_top1_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj2_from_top1_E, setModel_lj2_from_top1_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lj2_from_top1_jetIndex, + setModel_lj2_from_top1_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj1_from_top2_pt, setModel_lj1_from_top2_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj1_from_top2_eta, setModel_lj1_from_top2_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj1_from_top2_phi, setModel_lj1_from_top2_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj1_from_top2_E, setModel_lj1_from_top2_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lj1_from_top2_jetIndex, + setModel_lj1_from_top2_jetIndex) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj2_from_top2_pt, setModel_lj2_from_top2_pt) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj2_from_top2_eta, setModel_lj2_from_top2_eta) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj2_from_top2_phi, setModel_lj2_from_top2_phi) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, float, model_lj2_from_top2_E, setModel_lj2_from_top2_E) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(KLFitterResult, unsigned int, model_lj2_from_top2_jetIndex, + setModel_lj2_from_top2_jetIndex) } -ADD_NS_DV_PROXY( xAOD , KLFitterResultContainer ); - +ADD_NS_DV_PROXY(xAOD, KLFitterResultContainer); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/LinkDef.h index 16fcef788a76..5a16ca6fa198 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/LinkDef.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/LinkDef.h @@ -1,15 +1,17 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #include "TopEvent/SystematicEvent.h" #include "TopEvent/KLFitterResult.h" #include "TopEvent/PseudoTopResult.h" +#include "TopEvent/RCJetMC15.h" #ifdef __CINT__ #pragma extra_include "TopEvent/SystematicEvent.h"; #pragma extra_include "TopEvent/KLFitterResult.h"; #pragma extra_include "TopEvent/PseudoTopResult.h"; +#pragma extra_include "TopEvent/RCJetMC15.h"; #pragma link off all globals; #pragma link off all classes; @@ -28,4 +30,6 @@ #pragma link C++ class xAOD::PseudoTopResultContainer+; #pragma link C++ class xAOD::PseudoTopResultAuxContainer+; +#pragma link C++ class RCJetMC15+; + #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/PseudoTopResult.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/PseudoTopResult.cxx index 92485f1dd7a6..95448abe29d3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/PseudoTopResult.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/PseudoTopResult.cxx @@ -1,60 +1,50 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEvent/PseudoTopResult.h" #include "xAODCore/AddDVProxy.h" -namespace xAOD{ - /// Aux Container +namespace xAOD { + /// Aux Container PseudoTopResultAuxContainer::PseudoTopResultAuxContainer() : - AuxContainerBase() - { + AuxContainerBase() { } - + /// Interface class PseudoTopResult::PseudoTopResult() : - SG::AuxElement() - { + SG::AuxElement() { } //Initialize variables - void PseudoTopResult::IniVar(bool isReco){ - - if(isReco){ - - this->auxdecor< float >( "PseudoTop_Reco_ttbar_eta" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_ttbar_phi" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_ttbar_m" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_ttbar_pt" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_top_had_pt" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_top_had_eta" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_top_had_phi" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_top_had_m" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_top_lep_pt" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_top_lep_eta" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_top_lep_phi" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Reco_top_lep_m" ) = -100.0; - + void PseudoTopResult::IniVar(bool isReco) { + if (isReco) { + this->auxdecor< float >("PseudoTop_Reco_ttbar_eta") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_ttbar_phi") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_ttbar_m") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_ttbar_pt") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_top_had_pt") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_top_had_eta") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_top_had_phi") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_top_had_m") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_top_lep_pt") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_top_lep_eta") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_top_lep_phi") = -100.0; + this->auxdecor< float >("PseudoTop_Reco_top_lep_m") = -100.0; + } else { + this->auxdecor< float >("PseudoTop_Particle_ttbar_eta") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_ttbar_phi") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_ttbar_m") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_ttbar_pt") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_top_had_pt") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_top_had_eta") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_top_had_phi") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_top_had_m") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_top_lep_pt") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_top_lep_eta") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_top_lep_phi") = -100.0; + this->auxdecor< float >("PseudoTop_Particle_top_lep_m") = -100.0; } - else{ - - this->auxdecor< float >( "PseudoTop_Particle_ttbar_eta" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_ttbar_phi" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_ttbar_m" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_ttbar_pt" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_top_had_pt" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_top_had_eta" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_top_had_phi" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_top_had_m" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_top_lep_pt" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_top_lep_eta" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_top_lep_phi" ) = -100.0; - this->auxdecor< float >( "PseudoTop_Particle_top_lep_m" ) = -100.0; - - } - } - } -ADD_NS_DV_PROXY( xAOD , PseudoTopResultContainer ); +ADD_NS_DV_PROXY(xAOD, PseudoTopResultContainer); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/RCJetMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/RCJetMC15.cxx new file mode 100644 index 000000000000..41195394b9ca --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/RCJetMC15.cxx @@ -0,0 +1,653 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +/************************************************************** + // + // Created: 19 January 2016 + // Last Updated: 22 February 2016 + // + // Daniel Marley + // demarley@umich.edu + // University of Michigan, Ann Arbor, MI + // + // File for initializing and making re-clustered jets. + // + ***************************************************************/ +#include "TopEvent/RCJetMC15.h" + +#include "TopConfiguration/TopConfig.h" +#include "AsgTools/AsgTool.h" +#include "AthContainers/ConstDataVector.h" + +#include "xAODJet/JetContainer.h" +#include "xAODJet/JetAuxContainer.h" +#include "xAODEventInfo/EventInfo.h" +#include "xAODCore/ShallowCopy.h" +#include "xAODBase/IParticleHelpers.h" +#include "PATInterfaces/SystematicsUtil.h" + +#include "fastjet/ClusterSequence.hh" +#include <fastjet/contrib/EnergyCorrelator.hh> +#include <fastjet/contrib/Nsubjettiness.hh> +#include "JetSubStructureUtils/Qw.h" +#include "JetSubStructureUtils/KtSplittingScale.h" +#include "JetSubStructureUtils/EnergyCorrelatorGeneralized.h" +#include "JetSubStructureUtils/EnergyCorrelator.h" + +RCJetMC15::RCJetMC15(const std::string& name) : + asg::AsgTool(name), + m_name(name), + m_config(nullptr), + m_ptcut(0.), + m_etamax(0.), + m_inputJetPtMin(0.), + m_inputJetEtaMax(999.), + m_trim(0.), + m_radius(0.), + m_minradius(0.), + m_massscale(0.), + m_useJSS(false), + m_useAdditionalJSS(false), + m_egamma("EG_"), + m_jetsyst("JET_"), + m_muonsyst("MUON_"), + m_tracksyst("TRK_"), + m_InJetContainerBase("AntiKt4EMTopoJets_RC"), + m_OutJetContainerBase("AntiKtRCJets"), + m_InputJetContainer("AntiKt4EMTopoJets_RC"), + m_OutputJetContainer("AntiKtRCJets"), + m_loose_hashValue(2), + m_jet_def_rebuild(nullptr), + m_nSub1_beta1(nullptr), + m_nSub2_beta1(nullptr), + m_nSub3_beta1(nullptr), + m_ECF1(nullptr), + m_ECF2(nullptr), + m_ECF3(nullptr), + m_split12(nullptr), + m_split23(nullptr), + m_qw(nullptr), + m_gECF332(nullptr), + m_gECF461(nullptr), + m_gECF322(nullptr), + m_gECF331(nullptr), + m_gECF422(nullptr), + m_gECF441(nullptr), + m_gECF212(nullptr), + m_gECF321(nullptr), + m_gECF311(nullptr), + m_unique_syst(false) { + declareProperty("config", m_config); + declareProperty("VarRCjets", m_VarRCjets = false); + declareProperty("VarRCjets_rho", m_VarRCjets_rho = ""); + declareProperty("VarRCjets_mass_scale", m_VarRCjets_mass_scale = ""); +} + +RCJetMC15::~RCJetMC15() {} + + +StatusCode RCJetMC15::initialize() { + /* Initialize the re-clustered jets */ + ATH_MSG_INFO(" Initializing Re-clustered jets "); + + // load the necessary parameters from the Dynamic Keys in the config file + top::ConfigurationSettings* configSettings = top::ConfigurationSettings::get(); + + m_name = m_VarRCjets_rho + m_VarRCjets_mass_scale; + if (m_VarRCjets) { + m_ptcut = std::stof(configSettings->value("VarRCJetPt")); // 100 GeV + m_etamax = std::stof(configSettings->value("VarRCJetEta")); // 2.5 + m_trim = std::stof(configSettings->value("VarRCJetTrim")); // 0.05 (5% jet pT) + m_radius = std::stof(configSettings->value("VarRCJetMaxRadius")); // 1.2 (min=0.4) + m_minradius = 0.4; // 0.4 default (until we have smaller jets!) + std::string original_rho(m_VarRCjets_rho); + std::replace(original_rho.begin(), original_rho.end(), '_', '.'); + float rho = std::stof(original_rho); + float m_scale = mass_scales.at(m_VarRCjets_mass_scale); + m_massscale = rho * m_scale * 1e-3; // e.g., 2*m_top; in [GeV]! + + m_useJSS = m_config->useVarRCJetSubstructure(); + m_useAdditionalJSS = m_config->useVarRCJetAdditionalSubstructure(); + } else { + m_ptcut = std::stof(configSettings->value("RCJetPt")); // for initialize [GeV] & passSelection + m_etamax = std::stof(configSettings->value("RCJetEta")); // for passSelection + m_trim = std::stof(configSettings->value("RCJetTrim")); // for initialize + m_radius = std::stof(configSettings->value("RCJetRadius")); // for initialize + m_minradius = -1.0; + m_massscale = -1.0; + m_useJSS = m_config->useRCJetSubstructure(); + m_useAdditionalJSS = m_config->useRCJetAdditionalSubstructure(); + } + + m_inputJetPtMin = std::stof(configSettings->value("RCInputJetPtMin")); + m_inputJetEtaMax = std::stof(configSettings->value("RCInputJetEtaMax")); + + + if (m_useJSS || m_useAdditionalJSS) { + ATH_MSG_INFO("Calculating RCJet Substructure"); + + // Setup a bunch of FastJet stuff + //define the type of jets you will build (http://fastjet.fr/repo/doxygen-3.0.3/classfastjet_1_1JetDefinition.html) + m_jet_def_rebuild = std::make_shared<fastjet::JetDefinition>(fastjet::antikt_algorithm, 1.0, fastjet::E_scheme, + fastjet::Best); + } + if (m_useJSS) { + //Substructure tool definitions + m_nSub1_beta1 = std::make_shared<fastjet::contrib::Nsubjettiness>(1, + fastjet::contrib::OnePass_WTA_KT_Axes(), + fastjet::contrib::UnnormalizedMeasure(1.0)); + m_nSub2_beta1 = std::make_shared<fastjet::contrib::Nsubjettiness>(2, + fastjet::contrib::OnePass_WTA_KT_Axes(), + fastjet::contrib::UnnormalizedMeasure(1.0)); + m_nSub3_beta1 = std::make_shared<fastjet::contrib::Nsubjettiness>(3, + fastjet::contrib::OnePass_WTA_KT_Axes(), + fastjet::contrib::UnnormalizedMeasure(1.0)); + + + m_split12 = std::make_shared<JetSubStructureUtils::KtSplittingScale>(1); + m_split23 = std::make_shared<JetSubStructureUtils::KtSplittingScale>(2); + + m_qw = std::make_shared<JetSubStructureUtils::Qw>(); + + m_ECF1 = std::make_shared<fastjet::contrib::EnergyCorrelator>(1, 1.0, fastjet::contrib::EnergyCorrelator::pt_R); + m_ECF2 = std::make_shared<fastjet::contrib::EnergyCorrelator>(2, 1.0, fastjet::contrib::EnergyCorrelator::pt_R); + m_ECF3 = std::make_shared<fastjet::contrib::EnergyCorrelator>(3, 1.0, fastjet::contrib::EnergyCorrelator::pt_R); + + } + if (m_useAdditionalJSS) { + + m_gECF332 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(3, 3, 2, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF461 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(6, 4, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF322 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(2, 3, 2, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF331 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(3, 3, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF422 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(2, 4, 2, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF441 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(4, 4, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF212 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(1, 2, 2, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF321 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(2, 3, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF311 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(1, 3, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + } + + + + for (auto treeName : *m_config->systAllTTreeNames()) { + // only make a new tool if it is the nominal systematic or one that could affect small-r jets (el, mu, jet) + std::string hash_name(""); + + if (isUniqueSyst(treeName.second)) { + if (treeName.second.compare("nominal") != 0) hash_name = treeName.second; // no extra strings for nominal (so all + // other non-unique systs have same name + // as nominal) + + m_InputJetContainer = m_InJetContainerBase + hash_name; + m_OutputJetContainer = m_OutJetContainerBase + hash_name + m_name; + + // build a jet re-clustering tool for each case + std::shared_ptr<JetReclusteringTool> tool(new JetReclusteringTool(treeName.second + m_name)); + top::check(tool->setProperty("InputJetContainer", + m_InputJetContainer), "Failed inputjetcontainer initialize reclustering tool"); + top::check(tool->setProperty("OutputJetContainer", + m_OutputJetContainer), "Failed outputjetcontainer initialize reclustering tool"); + top::check(tool->setProperty("ReclusterRadius", + m_radius), "Failed re-clustering radius initialize reclustering tool"); + top::check(tool->setProperty("RCJetPtMin", m_ptcut * 1e-3), "Failed ptmin [GeV] initialize reclustering tool"); + top::check(tool->setProperty("InputJetPtMin", m_inputJetPtMin * 1e-3), "Failed InputJetPtMin [GeV] initialize reclustering tool"); + top::check(tool->setProperty("TrimPtFrac", m_trim), "Failed pT fraction initialize reclustering tool"); + top::check(tool->setProperty("VariableRMinRadius", + m_minradius), "Failed VarRC min radius initialize reclustering tool"); + top::check(tool->setProperty("VariableRMassScale", + m_massscale), "Failed VarRC mass scale initialize reclustering tool"); + top::check(tool->initialize(), "Failed to initialize reclustering tool"); + + m_jetReclusteringTool.insert({treeName.first, tool}); // insert the re-clustering tool into map + // this stores a tool for each systematic based on hash + // value + + // map of container names to access in event saver + m_inputContainerNames.insert({treeName.first, m_InputJetContainer}); + m_outputContainerNames.insert({treeName.first, m_OutputJetContainer}); + + // make a re-clustering tool for 'loose' events, too. + if (m_config->doLooseEvents()) { + std::shared_ptr<JetReclusteringTool> tool_loose(new JetReclusteringTool(treeName.second + m_name + "_Loose")); + top::check(tool_loose->setProperty("InputJetContainer", + m_InputJetContainer + "_Loose"), + "Failed inputjetcontainer reclustering tool"); + top::check(tool_loose->setProperty("OutputJetContainer", + m_OutputJetContainer + "_Loose"), + "Failed outputjetcontainer loose initialize reclustering tool"); + top::check(tool_loose->setProperty("ReclusterRadius", + m_radius), "Failed re-clustering radius initialize reclustering tool"); + top::check(tool_loose->setProperty("RCJetPtMin", m_ptcut * 1e-3), "Failed ptmin [GeV] reclustering tool"); + top::check(tool->setProperty("InputJetPtMin", m_inputJetPtMin * 1e-3), "Failed InputJetPtMin [GeV] initialize reclustering tool"); + top::check(tool_loose->setProperty("TrimPtFrac", m_trim), "Failed pT fraction initialize reclustering tool"); + top::check(tool_loose->setProperty("VariableRMinRadius", + m_minradius), "Failed VarRC min radius initialize reclustering tool"); + top::check(tool_loose->setProperty("VariableRMassScale", + m_massscale), "Failed VarRC mass scale initialize reclustering tool"); + top::check(tool_loose->initialize(), "Failed to initialize reclustering tool"); + + m_jetReclusteringTool.insert({m_loose_hashValue* treeName.first, tool_loose}); // making up a number as index + // for the loose event + // map of container names to access in event saver + m_inputContainerNames.insert({m_loose_hashValue* treeName.first, m_InputJetContainer + "_Loose"}); + m_outputContainerNames.insert({m_loose_hashValue* treeName.first, m_OutputJetContainer + "_Loose"}); + } // end if loose + } // end if unique syst + else { + m_InputJetContainer = m_InJetContainerBase; + m_OutputJetContainer = m_OutJetContainerBase + m_name; + + // map of container names to access in event saver + if (m_config->doLooseEvents()) { + m_inputContainerNames.insert({m_loose_hashValue* treeName.first, m_InputJetContainer + "_Loose"}); + m_outputContainerNames.insert({m_loose_hashValue* treeName.first, m_OutputJetContainer + "_Loose"}); + } else { + m_inputContainerNames.insert({treeName.first, m_InputJetContainer}); + m_outputContainerNames.insert({treeName.first, m_OutputJetContainer}); + } + } + + } // end for loop over systematics + + ATH_MSG_INFO(" Re-clustered jets initialized "); + + return StatusCode::SUCCESS; +} // end initialize() + +StatusCode RCJetMC15::execute(const top::Event& event) { + /* + Make the jet container (if necessary) and execute the re-clustering tool + https://svnweb.cern.ch/trac/atlasoff/browser/PhysicsAnalysis/TopPhys/xAOD/TopEvent/trunk/Root/TopEventMaker.cxx#L31 + */ + m_InputJetContainer = inputContainerName(event.m_hashValue, event.m_isLoose); + m_OutputJetContainer = rcjetContainerName(event.m_hashValue, event.m_isLoose); + + + // -- Save the jet container to the TStore (only if it doesn't already exist!) + // -- Then, we can access it with the re-clustering tool further down + if (!evtStore()->contains<xAOD::JetContainer>(m_InputJetContainer)) { + // Save the nominal container once, and each jet systematic container once + // Make the new jet container (only do this if we have to!) + // 22 Feb 2016: + // Code significantly shortened to make this container + // thanks to email exchange between Davide Gerbaudo & Attila Krasznahorkay + auto rcJetInputs = std::make_unique< ConstDataVector< xAOD::JetContainer >>(SG::VIEW_ELEMENTS); + for(const xAOD::Jet* jet : event.m_jets) { + if(jet->pt() < m_inputJetPtMin || std::abs(jet->eta()) > m_inputJetEtaMax) continue; + rcJetInputs->push_back(jet); + } + top::check(evtStore()->tds()->record(std::move(rcJetInputs), m_InputJetContainer), + "Failed to put jets in TStore for re-clustering"); + } // end if jet container exists + + // --- EXECUTE --- // + // only execute if the jet container doesn't exist + // (do not re-make the 'nominal' jet container over & over again!) + if (!evtStore()->contains<xAOD::JetContainer>(m_OutputJetContainer)) { + int hash_factor = (event.m_isLoose) ? m_loose_hashValue : 1; + + // tools only exist for unique systematics & nominal (save time/space)! + m_tool_iterator tool_iter = m_jetReclusteringTool.find(hash_factor * event.m_hashValue); + + // if this is a unique systematic or nominal, execute from the tool; else execute nominal + if (tool_iter != m_jetReclusteringTool.end()) tool_iter->second->execute(); + else m_jetReclusteringTool.at(hash_factor * m_config->nominalHashValue())->execute(); + + xAOD::JetContainer* myJets(nullptr); + top::check(evtStore()->retrieve(myJets, m_OutputJetContainer), "Failed to retrieve RC JetContainer"); + for (auto rcjet : *myJets) { + rcjet->auxdecor<bool>("PassedSelection") = passSelection(*rcjet); + } + + if (m_useJSS || m_useAdditionalJSS) { + static const SG::AuxElement::ConstAccessor<bool> passedSelection("PassedSelection"); + + for (auto rcjet : *myJets) { + if (!passedSelection(*rcjet)) continue; // Calculate JSS only if passed object selection + + // get the subjets and clusters of the rcjets + + std::vector<fastjet::PseudoJet> clusters; + + + if (m_config->sgKeyJetsTDS(hash_factor * m_config->nominalHashValue(), + false).find("AntiKt4EMTopoJets") != std::string::npos) { + getEMTopoClusters(clusters,rcjet); // use subjet constituents + } + else if (m_config->sgKeyJetsTDS(hash_factor * m_config->nominalHashValue(), + false).find("AntiKt4EMPFlowJets") != std::string::npos) { + getPflowConstituent(clusters, rcjet, event); // use ghost-matched tracks + } + else getLCTopoClusters(clusters, rcjet); // // use LCTOPO CLUSTERS matched to subjet + + if (m_config->sgKeyJetsTDS(hash_factor * m_config->nominalHashValue(), + false).find("AntiKt4EMPFlowJets") == std::string::npos) { + // In case of AntiKt4EMPFlowJets the tracks could be removed by the pile-up cuts + top::check( + !clusters.empty(), + "RCJetMC15::execute(const top::Event& event): Failed to get vector of clusters! Unable to calculate RC jets substructure variables!\n Aborting!"); + } + + if (clusters.size() != 0) { + // Now rebuild the large jet from the small jet constituents aka the original clusters + fastjet::ClusterSequence clust_seq_rebuild = fastjet::ClusterSequence(clusters, *m_jet_def_rebuild); + std::vector<fastjet::PseudoJet> my_pjets = fastjet::sorted_by_pt(clust_seq_rebuild.inclusive_jets(0.0)); + + + fastjet::PseudoJet correctedJet; + correctedJet = my_pjets[0]; + //Sometimes fastjet splits the jet into two, so need to correct for that!! + if (my_pjets.size() > 1) correctedJet += my_pjets[1]; + + if (m_useJSS) { + // Now finally we can calculate some substructure! + double tau32 = -1, tau21 = -1; + + double tau1 = m_nSub1_beta1->result(correctedJet); + double tau2 = m_nSub2_beta1->result(correctedJet); + double tau3 = m_nSub3_beta1->result(correctedJet); + + if (std::abs(tau1) > 1e-8) tau21 = tau2 / tau1; + else tau21 = -999.0; + if (std::abs(tau2) > 1e-8) tau32 = tau3 / tau2; + else tau32 = -999.0; + + + + double split12 = m_split12->result(correctedJet); + double split23 = m_split23->result(correctedJet); + double qw = m_qw->result(correctedJet); + + double D2 = -1; + + double vECF1 = m_ECF1->result(correctedJet); + double vECF2 = m_ECF2->result(correctedJet); + double vECF3 = m_ECF3->result(correctedJet); + if (std::abs(vECF2) > 1e-8) D2 = vECF3 * vECF1* vECF1* vECF1 / (vECF2 * vECF2 * vECF2); + else D2 = -999.0; + + + // now attach the results to the original jet + rcjet->auxdecor<float>("Tau32_clstr") = tau32; + rcjet->auxdecor<float>("Tau21_clstr") = tau21; + + // lets also write out the components so we can play with them later + rcjet->auxdecor<float>("Tau3_clstr") = tau3; + rcjet->auxdecor<float>("Tau2_clstr") = tau2; + rcjet->auxdecor<float>("Tau1_clstr") = tau1; + + rcjet->auxdecor<float>("d12_clstr") = split12; + rcjet->auxdecor<float>("d23_clstr") = split23; + rcjet->auxdecor<float>("Qw_clstr") = qw; + + rcjet->auxdecor<float>("nconstituent_clstr") = clusters.size(); + + rcjet->auxdecor<float>("ECF1_clstr") = vECF1; + rcjet->auxdecor<float>("ECF2_clstr") = vECF2; + rcjet->auxdecor<float>("ECF3_clstr") = vECF3; + rcjet->auxdecor<float>("D2_clstr") = D2; + + } // end of if useJSS + + if (m_useAdditionalJSS) { + + // MlB's t/H discriminators + // E = (a*n) / (b*m) + // for an ECFG_X_Y_Z, a=Y, n=Z -> dimenionless variable + double gECF332 = m_gECF332->result(correctedJet); + double gECF461 = m_gECF461->result(correctedJet); + double gECF322 = m_gECF322->result(correctedJet); + double gECF331 = m_gECF331->result(correctedJet); + double gECF422 = m_gECF422->result(correctedJet); + double gECF441 = m_gECF441->result(correctedJet); + double gECF212 = m_gECF212->result(correctedJet); + double gECF321 = m_gECF321->result(correctedJet); + double gECF311 = m_gECF311->result(correctedJet); + + double L1 = -999.0, L2 = -999.0, L3 = -999.0, L4 = -999.0, L5 = -999.0; + if (std::abs(gECF212) > 1e-12) { + L1 = gECF321 / gECF212; + L2 = gECF331 / sqrt(gECF212*gECF212*gECF212); + } + if (std::abs(gECF331) > 1e-12) { + L3 = gECF311 / pow(gECF331,1./3.); + L4 = gECF322 / pow(gECF331,4./3.); + } + if (std::abs(gECF441) > 1e-12) { + L5 = gECF422/gECF441; + } + + rcjet->auxdecor<float>("gECF332_clstr") = gECF332; + rcjet->auxdecor<float>("gECF461_clstr") = gECF461; + rcjet->auxdecor<float>("gECF322_clstr") = gECF322; + rcjet->auxdecor<float>("gECF331_clstr") = gECF331; + rcjet->auxdecor<float>("gECF422_clstr") = gECF422; + rcjet->auxdecor<float>("gECF441_clstr") = gECF441; + rcjet->auxdecor<float>("gECF212_clstr") = gECF212; + rcjet->auxdecor<float>("gECF321_clstr") = gECF321; + rcjet->auxdecor<float>("gECF311_clstr") = gECF311; + rcjet->auxdecor<float>("L1_clstr") = L1; + rcjet->auxdecor<float>("L2_clstr") = L2; + rcjet->auxdecor<float>("L3_clstr") = L3; + rcjet->auxdecor<float>("L4_clstr") = L4; + rcjet->auxdecor<float>("L5_clstr") = L5; + // lets also store the rebuilt jet incase we need it later + rcjet->auxdecor<float>("RRCJet_pt") = correctedJet.pt(); + rcjet->auxdecor<float>("RRCJet_eta") = correctedJet.eta(); + rcjet->auxdecor<float>("RRCJet_phi") = correctedJet.phi(); + rcjet->auxdecor<float>("RRCJet_e") = correctedJet.e(); + }// end of if useAdditional JSS + } + }// end of rcjet loop + }//m_useJSS || m_useAdditionalJSS + } //if (!evtStore()->contains<xAOD::JetContainer>(m_OutputJetContainer)) + + + + + + + + + + return StatusCode::SUCCESS; +} // end execute() + +StatusCode RCJetMC15::finalize() { + m_jetReclusteringTool.clear(); + + return StatusCode::SUCCESS; +} + +bool RCJetMC15::isUniqueSyst(const std::string syst_name) { + /* + Check if the given systematic (besides nominal) needs a unique container + Keep this in one function so it easier to update than having multiple checks everywhere. + Only need jet containers for EGamma, Muon, Jet and Nominal systematics + */ + + bool isSmallRJetSys = (syst_name.find(m_jetsyst) != std::string::npos); + + // Systematic branches for small-R and large-R jets both contain "JET_" string. We want to recluster only if they + // correspond to small-R jets. + if ((syst_name.find("_R10_") != std::string::npos) || + (syst_name.find("_CombMass_") != std::string::npos) || + (syst_name.find("_LargeR_") != std::string::npos) || + (syst_name.find("_MassRes_") != std::string::npos) || + (syst_name.find("_SigSF_") != std::string::npos) || + (syst_name.find("_BGSF_") != std::string::npos) ) isSmallRJetSys = false; + + m_unique_syst = (syst_name.find(m_egamma) == 0 || + syst_name.find(m_muonsyst) == 0 || + isSmallRJetSys || + syst_name.find(m_tracksyst) == 0 || + syst_name.compare("nominal") == 0); + + return m_unique_syst; +} + +std::string RCJetMC15::inputContainerName(std::size_t hash_value, bool isLooseEvent) { + /* Return the name of the input container */ + std::string this_container_name(""); + if (isLooseEvent) hash_value *= m_loose_hashValue; // loose events have a slightly different hash value to keep track + // of + + m_iterator iter = m_inputContainerNames.find(hash_value); + + if (iter != m_inputContainerNames.end()) this_container_name = iter->second; + else this_container_name = m_InJetContainerBase; + + return this_container_name; +} + +std::string RCJetMC15::rcjetContainerName(std::size_t hash_value, bool isLooseEvent) { + /* Return the name of the rcjet container for a given systematic */ + std::string this_container_name(""); + if (isLooseEvent) hash_value *= m_loose_hashValue; // loose events have a slightly different hash value + + m_iterator iter = m_outputContainerNames.find(hash_value); + + if (iter != m_outputContainerNames.end()) this_container_name = iter->second; + else this_container_name = m_OutJetContainerBase; + + return this_container_name; +} + +bool RCJetMC15::passSelection(const xAOD::Jet& jet) const { + /* + Check if the re-clustered jet passes selection. + Right now, this only does something for |eta| because + pT is taken care of in the re-clustering tool. When + small-r jet mass is available (calibrated+uncertainties), + we can cut on that. + */ + // [pT] calibrated to >~ 22 GeV (23 Jan 2016) + if (jet.pt() < m_ptcut) return false; + + // [|eta|] calibrated < 2.5 + if (std::abs(jet.eta()) > m_etamax) return false; + + // small-r jet mass not calibrated and no uncertainties + + return true; +} + +void RCJetMC15::getEMTopoClusters(std::vector<fastjet::PseudoJet>& clusters, const xAOD::Jet* rcjet) { + clusters.clear(); + + for (auto subjet : rcjet->getConstituents()) { + const xAOD::Jet* subjet_raw = static_cast<const xAOD::Jet*>(subjet->rawConstituent()); + + // Make sure we don't try to access jets that have had the clusters thinned + bool hasConstituents = true; + auto links = subjet_raw->constituentLinks(); + for (auto link : links) { + if (!link.isValid()) { + ATH_MSG_WARNING( + "Some of the RC Jet Constituents have been thinned - will not be included in RCJet JSS calculation"); + hasConstituents = false; + break; + } + } + if (!hasConstituents) { + continue; + } + + for (auto clus_itr : subjet_raw->getConstituents()) { + if (clus_itr->e() > 0) { + TLorentzVector temp_p4; + + double sf = 1.0; + temp_p4.SetPtEtaPhiM(clus_itr->pt() * sf, clus_itr->eta(), clus_itr->phi(), clus_itr->m()); + + clusters.push_back(fastjet::PseudoJet(temp_p4.Px(), temp_p4.Py(), temp_p4.Pz(), temp_p4.E())); + } + } + } +} + +void RCJetMC15::getLCTopoClusters(std::vector<fastjet::PseudoJet>& clusters, const xAOD::Jet* rcjet) { + //LCTOPO CLUSTERS + clusters.clear(); + + // get the clusters (directly we so can try using the LCTopo clusters) + const xAOD::CaloClusterContainer* myClusters(nullptr); + top::check(evtStore()->retrieve(myClusters, "CaloCalTopoClusters"), "Failed to retrieve CaloCalTopoClusters"); + + + + for (auto cluster : *myClusters) { + for (auto subjet : rcjet->getConstituents()) { + const xAOD::Jet* subjet_raw = static_cast<const xAOD::Jet*>(subjet->rawConstituent()); + + float dR = subjet_raw->p4().DeltaR(cluster->p4()); + if (dR < 0.4) { + TLorentzVector temp_p4; + temp_p4.SetPtEtaPhiE(cluster->pt((xAOD::CaloCluster_v1::State(1))), + cluster->eta((xAOD::CaloCluster_v1::State(1))), + cluster->phi((xAOD::CaloCluster_v1::State(1))), + cluster->e((xAOD::CaloCluster_v1::State(1)))); + clusters.push_back(fastjet::PseudoJet(temp_p4.Px(), temp_p4.Py(), temp_p4.Pz(), temp_p4.E())); + break; + } + } + } +} + +void RCJetMC15::getPflowConstituent(std::vector<fastjet::PseudoJet>& clusters, const xAOD::Jet* rcjet, + const top::Event& event) { + // At the moment the proper constituent of the PFlows aren't available in TOPQ1 and there is no strategy to provide + // uncertainty on that consequently + // at the moment just the tracks ghost matched to the PFLow objects are considered to define the substructure (under + // suggestion of the JSS group). + // As a consiquence all the neutral component of the jet is missing from the substructure, this choice is consistently + // copied at particle level + + clusters.clear(); + std::vector<const xAOD::TrackParticle*> jetTracks; + + + for (auto subjet : rcjet->getConstituents()) { + const xAOD::Jet* subjet_raw = static_cast<const xAOD::Jet*>(subjet->rawConstituent()); + + if(subjet->pt() < m_config->jetPtGhostTracks() || std::abs(subjet->eta()) > m_config->jetEtaGhostTracks()) continue; + + + jetTracks.clear(); + + jetTracks = subjet_raw->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack(event.m_hashValue)); + bool haveJetTracks = jetTracks.size() != 0; + + if (haveJetTracks) { + + for ( const xAOD::TrackParticle* jet: jetTracks ){ + TLorentzVector temp_p4; + + if (jet != nullptr) { + + // Select on track quality, pt, eta and match to vertex + if(jet->auxdataConst< char >("passPreORSelection") != 1){ + continue; + } + + temp_p4.SetPtEtaPhiE(jet->pt(), jet->eta(), jet->phi(), jet->e()); + clusters.emplace_back(fastjet::PseudoJet(temp_p4.Px(), temp_p4.Py(), temp_p4.Pz(), temp_p4.E())); + + } + } + } else { + ATH_MSG_WARNING( + "RCJETMC15::No remaining tracks associated to the PFlow jet"); + } + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/SystematicEvent.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/SystematicEvent.cxx index c4b17f54dc68..996f51400d60 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/SystematicEvent.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/SystematicEvent.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: SystematicEvent.cxx 692539 2015-09-02 00:20:52Z morrisj $ #include "TopEvent/SystematicEvent.h" @@ -9,40 +9,43 @@ #include "xAODCore/AuxStoreAccessorMacros.h" #include "xAODCore/AddDVProxy.h" -namespace xAOD{ +namespace xAOD { // Aux Container SystematicEventAuxContainer::SystematicEventAuxContainer() : - AuxContainerBase() - { - AUX_VARIABLE( hashValue ); - AUX_VARIABLE( ttreeIndex ); - AUX_VARIABLE( isLooseEvent ); + AuxContainerBase() { + AUX_VARIABLE(hashValue); + AUX_VARIABLE(ttreeIndex); + AUX_VARIABLE(isLooseEvent); - AUX_VARIABLE( goodPhotons ); - AUX_VARIABLE( goodElectrons ); - AUX_VARIABLE( goodMuons ); - AUX_VARIABLE( goodTaus ); - AUX_VARIABLE( goodJets ); - AUX_VARIABLE( goodLargeRJets ); - AUX_VARIABLE( goodTrackJets ); + AUX_VARIABLE(goodPhotons); + AUX_VARIABLE(goodElectrons); + AUX_VARIABLE(goodFwdElectrons); + AUX_VARIABLE(goodMuons); + AUX_VARIABLE(goodSoftMuons); + AUX_VARIABLE(goodTaus); + AUX_VARIABLE(goodJets); + AUX_VARIABLE(goodLargeRJets); + AUX_VARIABLE(goodTrackJets); + AUX_VARIABLE(goodTracks); } - + /// Interface class - SystematicEvent::SystematicEvent() : - SG::AuxElement() - { - } - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( SystematicEvent , std::size_t , hashValue , setHashValue ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( SystematicEvent , unsigned int , ttreeIndex , setTtreeIndex ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( SystematicEvent , char , isLooseEvent , setIsLooseEvent ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( SystematicEvent , std::vector<unsigned int> , goodPhotons , setGoodPhotons ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( SystematicEvent , std::vector<unsigned int> , goodElectrons , setGoodElectrons ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( SystematicEvent , std::vector<unsigned int> , goodMuons , setGoodMuons ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( SystematicEvent , std::vector<unsigned int> , goodTaus , setGoodTaus ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( SystematicEvent , std::vector<unsigned int> , goodJets , setGoodJets ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( SystematicEvent , std::vector<unsigned int> , goodLargeRJets , setGoodLargeRJets ) - AUXSTORE_OBJECT_SETTER_AND_GETTER( SystematicEvent , std::vector<unsigned int> , goodTrackJets , setGoodTrackJets ) - + SystematicEvent::SystematicEvent() : + SG::AuxElement() { + } + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(SystematicEvent, std::size_t, hashValue, setHashValue) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(SystematicEvent, unsigned int, ttreeIndex, setTtreeIndex) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(SystematicEvent, char, isLooseEvent, setIsLooseEvent) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodPhotons, setGoodPhotons) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodElectrons, setGoodElectrons) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodFwdElectrons, setGoodFwdElectrons) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodMuons, setGoodMuons) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodSoftMuons, setGoodSoftMuons) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodTaus, setGoodTaus) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodJets, setGoodJets) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodLargeRJets, setGoodLargeRJets) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodTrackJets, setGoodTrackJets) + AUXSTORE_OBJECT_SETTER_AND_GETTER(SystematicEvent, std::vector<unsigned int>, goodTracks, setGoodTracks) } -ADD_NS_DV_PROXY( xAOD , SystematicEventContainer ); +ADD_NS_DV_PROXY(xAOD, SystematicEventContainer); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/TopEventMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/TopEventMaker.cxx index 0438fabc7e1e..631731bcd9c8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/TopEventMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/Root/TopEventMaker.cxx @@ -1,8 +1,8 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -// $Id: TopEventMaker.cxx 795594 2017-02-04 22:12:45Z tpelzer $ +// $Id: TopEventMaker.cxx 809847 2017-08-29 15:18:19Z iconnell $ #include "TopEvent/TopEventMaker.h" #include "TopEvent/EventTools.h" @@ -20,74 +20,131 @@ #include "xAODJet/JetAuxContainer.h" #include "xAODMissingET/MissingETContainer.h" #include "xAODCore/ShallowCopy.h" +#include "FourMomUtils/xAODP4Helpers.h" #include "TopPartons/PartonHistory.h" +#include <boost/algorithm/string.hpp> + +#include <iostream> + namespace top { + bool TopEventMaker::s_hasTruthEvent = true; - TopEventMaker::TopEventMaker( const std::string& name ) : - asg::AsgTool( name ), - m_config(nullptr) - { - declareProperty( "config" , m_config ); + TopEventMaker::TopEventMaker(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr) { + declareProperty("config", m_config); } - + + StatusCode TopEventMaker::initialize() { + if (m_config->useRCJets() == true) { + m_rc = std::unique_ptr<RCJetMC15> (new RCJetMC15("RCJetMC15")); + top::check(m_rc->setProperty("config", m_config), "Failed to set config property of RCJetMC15"); + top::check(m_rc->initialize(), "Failed to initialize RCJetMC15"); + } + + if (m_config->useVarRCJets() == true) { + boost::split(m_VarRCJetRho, m_config->VarRCJetRho(), boost::is_any_of(",")); + boost::split(m_VarRCJetMassScale, m_config->VarRCJetMassScale(), boost::is_any_of(",")); + + for (auto& rho : m_VarRCJetRho) { + for (auto& mass_scale : m_VarRCJetMassScale) { + std::replace(rho.begin(), rho.end(), '.', '_'); + std::string name = rho + mass_scale; + m_VarRC[name] = std::unique_ptr<RCJetMC15> (new RCJetMC15("VarRCJetMC15_" + name)); + top::check(m_VarRC[name]->setProperty("config", m_config), "Failed to set config property of VarRCJetMC15"); + top::check(m_VarRC[name]->setProperty("VarRCjets", true), "Failed to set VarRCjets property of VarRCJetMC15"); + top::check(m_VarRC[name]->setProperty("VarRCjets_rho", + rho), "Failed to set VarRCjets rho property of VarRCJetMC15"); + top::check(m_VarRC[name]->setProperty("VarRCjets_mass_scale", + mass_scale), + "Failed to set VarRCjets mass scale property of VarRCJetMC15"); + top::check(m_VarRC[name]->initialize(), "Failed to initialize VarRCJetMC15"); + } // end loop over mass scale parameters (e.g., top mass, w mass, etc.) + } // end loop over mass scale multiplies (e.g., 1.,2.,etc.) + } + + return StatusCode::SUCCESS; + } + /// As top-xaod isn't an asg::AsgTool, it doesn't have access to all the information /// Very annoying, as it's actually quite simple - const xAOD::SystematicEventContainer* TopEventMaker::systematicEvents(const std::string& sgKey) const - { + const xAOD::SystematicEventContainer* TopEventMaker::systematicEvents(const std::string& sgKey) const { const xAOD::SystematicEventContainer* systEvents(nullptr); - top::check( evtStore()->retrieve(systEvents,sgKey) , "Failed to get xAOD::SystematicEventContainer"); + + top::check(evtStore()->retrieve(systEvents, sgKey), "Failed to get xAOD::SystematicEventContainer"); return systEvents; } - top::Event TopEventMaker::makeTopEvent(const xAOD::SystematicEvent& currentSystematic) - { + top::Event TopEventMaker::makeTopEvent(const xAOD::SystematicEvent* currentSystematicPtr) { + xAOD::SystematicEvent const& currentSystematic = *currentSystematicPtr; //create a new event object top::Event event; - + // Set systematic hash value std::size_t hash = currentSystematic.hashValue(); event.m_hashValue = hash; - + // TTree index event.m_ttreeIndex = currentSystematic.ttreeIndex(); - + // Is Loose event? - event.m_isLoose = currentSystematic.isLooseEvent(); + event.m_isLoose = currentSystematic.isLooseEvent(); //event info - top::check(evtStore()->retrieve(event.m_info, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); - + top::check(evtStore()->retrieve(event.m_info, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); + event.m_systematicEvent = currentSystematicPtr; + //Primary Vertices if (evtStore()->contains<xAOD::VertexContainer>(m_config->sgKeyPrimaryVertices())) { - top::check(evtStore()->retrieve(event.m_primaryVertices, m_config->sgKeyPrimaryVertices()), "Failed to retrieve Primary Vertices"); - } - + top::check(evtStore()->retrieve(event.m_primaryVertices, + m_config->sgKeyPrimaryVertices()), "Failed to retrieve Primary Vertices"); + } + + //Poisson bootstrap weights + if (m_config->saveBootstrapWeights()) { + int second_seed; + if (m_config->isMC()) { + second_seed = event.m_info->mcChannelNumber(); + } else { + second_seed = event.m_info->runNumber(); + } + std::vector<int> weight_poisson = top::calculateBootstrapWeights(m_config->getNumberOfBootstrapReplicas(), + event.m_info->eventNumber(), + second_seed); + event.m_info->auxdecor< std::vector<int> >("weight_poisson") = weight_poisson; + } + //electrons if (m_config->useElectrons()) { ///-- Need to read const collections for mini-xaod read back --/// - + const xAOD::ElectronContainer* calibratedElectrons(nullptr); - top::check(evtStore()->retrieve(calibratedElectrons, m_config->sgKeyElectrons(hash) ), "Failed to retrieve electrons"); - + top::check(evtStore()->retrieve(calibratedElectrons, m_config->sgKeyElectrons( + hash)), "Failed to retrieve electrons"); + ///-- Shallow copy and save to TStore --/// if (!evtStore()->contains<xAOD::ElectronContainer>(m_config->sgKeyElectronsTDS(hash))) { - std::pair< xAOD::ElectronContainer*, xAOD::ShallowAuxContainer* > shallow_electrons = xAOD::shallowCopyContainer( *calibratedElectrons ); - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_electrons.first , m_config->sgKeyElectronsTDS(hash) ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_electrons.second , m_config->sgKeyElectronsTDSAux(hash) ); - top::check( (save && saveAux) , "Failed to store object in TStore"); + std::pair< xAOD::ElectronContainer*, + xAOD::ShallowAuxContainer* > shallow_electrons = xAOD::shallowCopyContainer(*calibratedElectrons); + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_electrons.first, m_config->sgKeyElectronsTDS(hash)); + xAOD::TReturnCode saveAux = + evtStore()->tds()->record(shallow_electrons.second, m_config->sgKeyElectronsTDSAux(hash)); + top::check((save && saveAux), "Failed to store object in TStore"); } - + ///-- Pull shallow copy back out of TStore in non-const way --/// xAOD::ElectronContainer* calibratedElectronsTDS(nullptr); - top::check(evtStore()->retrieve(calibratedElectronsTDS, m_config->sgKeyElectronsTDS(hash) ), "Failed to retrieve electrons"); - - + top::check(evtStore()->retrieve(calibratedElectronsTDS, m_config->sgKeyElectronsTDS( + hash)), "Failed to retrieve electrons"); + + // re-write overlap information if it is decorated onto currentSystematic if (currentSystematic.isAvailable< std::vector<unsigned int> >("overlapsEl")) { - std::vector<unsigned int> overlapsEl = currentSystematic.auxdataConst< std::vector<unsigned int> >("overlapsEl"); + std::vector<unsigned int> overlapsEl = + currentSystematic.auxdataConst< std::vector<unsigned int> >("overlapsEl"); if (overlapsEl.size() == calibratedElectronsTDS->size()) { unsigned int counter(0); for (auto x : *calibratedElectronsTDS) { @@ -96,14 +153,47 @@ namespace top { } } } - + for (auto index : currentSystematic.goodElectrons()) { event.m_electrons.push_back(calibratedElectronsTDS->at(index)); } - + //shallow copies aren't sorted! - //sort only the selected muons (faster) - event.m_electrons.sort(top::descendingPtSorter); + //sort only the selected electrons (faster) + event.m_electrons.sort(top::descendingPtSorter); + } + + //forward electrons + if (m_config->useFwdElectrons()) { + const xAOD::ElectronContainer* calibratedFwdElectrons(nullptr); + top::check(evtStore()->retrieve(calibratedFwdElectrons, m_config->sgKeyFwdElectrons( + hash)), "Failed to retrieve fwd electrons"); + + ///-- Shallow copy and save to TStore --/// + if (!evtStore()->contains<xAOD::ElectronContainer>(m_config->sgKeyFwdElectronsTDS(hash))) { + std::pair< xAOD::ElectronContainer*, + xAOD::ShallowAuxContainer* > shallow_fwdelectrons = xAOD::shallowCopyContainer( + *calibratedFwdElectrons); + + xAOD::TReturnCode save = + evtStore()->tds()->record(shallow_fwdelectrons.first, m_config->sgKeyFwdElectronsTDS(hash)); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_fwdelectrons.second, m_config->sgKeyFwdElectronsTDSAux( + hash)); + top::check((save && saveAux), "Failed to store object in TStore"); + } + + ///-- Pull shallow copy back out of TStore in non-const way --/// + xAOD::ElectronContainer* calibratedFwdElectronsTDS(nullptr); + top::check(evtStore()->retrieve(calibratedFwdElectronsTDS, m_config->sgKeyFwdElectronsTDS( + hash)), "Failed to retrieve fwd electrons"); + + for (const auto& index : currentSystematic.goodFwdElectrons()) { + event.m_fwdElectrons.push_back(calibratedFwdElectronsTDS->at(index)); + } + + //shallow copies aren't sorted! + //sort only the selected fwd electrons (faster) + event.m_fwdElectrons.sort(top::descendingPtSorter); } //photons @@ -111,20 +201,23 @@ namespace top { ///-- Need to read const collections for mini-xaod read back --/// const xAOD::PhotonContainer* calibratedPhotons(nullptr); - top::check(evtStore()->retrieve(calibratedPhotons, m_config->sgKeyPhotons(hash) ), "Failed to retrieve photons"); + top::check(evtStore()->retrieve(calibratedPhotons, m_config->sgKeyPhotons(hash)), "Failed to retrieve photons"); ///-- Shallow copy and save to TStore --/// if (!evtStore()->contains<xAOD::PhotonContainer>(m_config->sgKeyPhotonsTDS(hash))) { - std::pair< xAOD::PhotonContainer*, xAOD::ShallowAuxContainer* > shallow_photons = xAOD::shallowCopyContainer( *calibratedPhotons ); + std::pair< xAOD::PhotonContainer*, xAOD::ShallowAuxContainer* > shallow_photons = xAOD::shallowCopyContainer( + *calibratedPhotons); - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_photons.first , m_config->sgKeyPhotonsTDS(hash) ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_photons.second , m_config->sgKeyPhotonsTDSAux(hash) ); - top::check( (save && saveAux) , "Failed to store object in TStore"); + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_photons.first, m_config->sgKeyPhotonsTDS(hash)); + xAOD::TReturnCode saveAux = + evtStore()->tds()->record(shallow_photons.second, m_config->sgKeyPhotonsTDSAux(hash)); + top::check((save && saveAux), "Failed to store object in TStore"); } ///-- Pull shallow copy back out of TStore in non-const way --/// xAOD::PhotonContainer* calibratedPhotonsTDS(nullptr); - top::check(evtStore()->retrieve(calibratedPhotonsTDS, m_config->sgKeyPhotonsTDS(hash) ), "Failed to retrieve photons"); + top::check(evtStore()->retrieve(calibratedPhotonsTDS, m_config->sgKeyPhotonsTDS( + hash)), "Failed to retrieve photons"); for (auto index : currentSystematic.goodPhotons()) { event.m_photons.push_back(calibratedPhotonsTDS->at(index)); @@ -136,26 +229,28 @@ namespace top { //muons if (m_config->useMuons()) { - ///-- Need to read const collections for mini-xaod read back --/// + ///-- Need to read const collections for mini-xaod read back --/// const xAOD::MuonContainer* calibratedMuons(nullptr); - top::check(evtStore()->retrieve(calibratedMuons, m_config->sgKeyMuons(hash) ), "Failed to retrieve muons"); - + top::check(evtStore()->retrieve(calibratedMuons, m_config->sgKeyMuons(hash)), "Failed to retrieve muons"); + ///-- Shallow copy and save to TStore --/// if (!evtStore()->contains<xAOD::MuonContainer>(m_config->sgKeyMuonsTDS(hash))) { - std::pair< xAOD::MuonContainer*, xAOD::ShallowAuxContainer* > shallow_muons = xAOD::shallowCopyContainer( *calibratedMuons ); - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_muons.first , m_config->sgKeyMuonsTDS(hash) ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_muons.second , m_config->sgKeyMuonsTDSAux(hash) ); - top::check( (save && saveAux) , "Failed to store object in TStore"); + std::pair< xAOD::MuonContainer*, xAOD::ShallowAuxContainer* > shallow_muons = xAOD::shallowCopyContainer( + *calibratedMuons); + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_muons.first, m_config->sgKeyMuonsTDS(hash)); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_muons.second, m_config->sgKeyMuonsTDSAux(hash)); + top::check((save && saveAux), "Failed to store object in TStore"); } - + ///-- Pull shallow copy back out of TStore in non-const way --/// xAOD::MuonContainer* calibratedMuonsTDS(nullptr); - top::check(evtStore()->retrieve(calibratedMuonsTDS, m_config->sgKeyMuonsTDS(hash) ), "Failed to retrieve muons"); - + top::check(evtStore()->retrieve(calibratedMuonsTDS, m_config->sgKeyMuonsTDS(hash)), "Failed to retrieve muons"); + // re-write overlap information if it is decorated onto currentSystematic if (currentSystematic.isAvailable< std::vector<unsigned int> >("overlapsMu")) { - std::vector<unsigned int> overlapsMu = currentSystematic.auxdataConst< std::vector<unsigned int> >("overlapsMu"); + std::vector<unsigned int> overlapsMu = + currentSystematic.auxdataConst< std::vector<unsigned int> >("overlapsMu"); if (overlapsMu.size() == calibratedMuonsTDS->size()) { unsigned int counter(0); for (auto x : *calibratedMuons) { @@ -163,40 +258,76 @@ namespace top { ++counter; } } - } - + } + for (auto index : currentSystematic.goodMuons()) { event.m_muons.push_back(calibratedMuonsTDS->at(index)); - } + } //shallow copies aren't sorted! //sort only the selected muons (faster) event.m_muons.sort(top::descendingPtSorter); } + //soft muons + if (m_config->useSoftMuons()) { + ///-- Need to read const collections for mini-xaod read back --/// + const xAOD::MuonContainer* calibratedSoftMuons(nullptr); + + top::check(evtStore()->retrieve(calibratedSoftMuons, m_config->sgKeySoftMuons(hash)), "Failed to retrieve muons"); + + + ///-- Shallow copy and save to TStore --/// + if (!evtStore()->contains<xAOD::MuonContainer>(m_config->sgKeySoftMuonsTDS(hash))) { + std::pair< xAOD::MuonContainer*, xAOD::ShallowAuxContainer* > shallow_softmuons = xAOD::shallowCopyContainer( + *calibratedSoftMuons); + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_softmuons.first, m_config->sgKeySoftMuonsTDS(hash)); + xAOD::TReturnCode saveAux = + evtStore()->tds()->record(shallow_softmuons.second, m_config->sgKeySoftMuonsTDSAux(hash)); + top::check((save && saveAux), "Failed to store object in TStore"); + } + + ///-- Pull shallow copy back out of TStore in non-const way --/// + xAOD::MuonContainer* calibratedSoftMuonsTDS(nullptr); + top::check(evtStore()->retrieve(calibratedSoftMuonsTDS, m_config->sgKeySoftMuonsTDS( + hash)), "Failed to retrieve soft muons"); + + //no overlap procedure applied to soft muons for the time being + + for (auto index : currentSystematic.goodSoftMuons()) { + event.m_softmuons.push_back(calibratedSoftMuonsTDS->at(index)); + } + + //shallow copies aren't sorted! + //sort only the selected soft muons (faster) + event.m_softmuons.sort(top::descendingPtSorter); + } + //taus if (m_config->useTaus()) { - ///-- Need to read const collections for mini-xaod read back --/// + ///-- Need to read const collections for mini-xaod read back --/// const xAOD::TauJetContainer* calibratedTaus(nullptr); - top::check(evtStore()->retrieve(calibratedTaus,m_config->sgKeyTaus(hash) ), "Failed to retrieve taus"); + top::check(evtStore()->retrieve(calibratedTaus, m_config->sgKeyTaus(hash)), "Failed to retrieve taus"); ///-- Shallow copy and save to TStore --/// if (!evtStore()->contains<xAOD::TauJetContainer>(m_config->sgKeyTausTDS(hash))) { - std::pair< xAOD::TauJetContainer*, xAOD::ShallowAuxContainer* > shallow_taus = xAOD::shallowCopyContainer( *calibratedTaus ); - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_taus.first , m_config->sgKeyTausTDS(hash) ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_taus.second , m_config->sgKeyTausTDSAux(hash) ); - top::check( (save && saveAux) , "Failed to store object in TStore"); + std::pair< xAOD::TauJetContainer*, xAOD::ShallowAuxContainer* > shallow_taus = xAOD::shallowCopyContainer( + *calibratedTaus); + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_taus.first, m_config->sgKeyTausTDS(hash)); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_taus.second, m_config->sgKeyTausTDSAux(hash)); + top::check((save && saveAux), "Failed to store object in TStore"); } - + ///-- Pull shallow copy back out of TStore in non-const way --/// xAOD::TauJetContainer* calibratedTausTDS(nullptr); - top::check(evtStore()->retrieve(calibratedTausTDS, m_config->sgKeyTausTDS(hash) ), "Failed to retrieve taus"); - + top::check(evtStore()->retrieve(calibratedTausTDS, m_config->sgKeyTausTDS(hash)), "Failed to retrieve taus"); + for (auto index : currentSystematic.goodTaus()) { event.m_tauJets.push_back(calibratedTausTDS->at(index)); - } - + } + //shallow copies aren't sorted! //sort only the selected taus (faster) event.m_tauJets.sort(top::descendingPtSorter); @@ -211,109 +342,240 @@ namespace top { looseJets = true; } } - + if (m_config->useJets()) { ///-- Need to read const collections for mini-xaod read back --/// - std::string sgKeyCalibrated( m_config->sgKeyJets(hash,looseJets) ); - std::string sgKeyTmp = "tmp_"+sgKeyCalibrated; - std::string sgKeyTmpAux = sgKeyTmp+"Aux."; - + std::string sgKeyCalibrated(m_config->sgKeyJets(hash, looseJets)); + std::string sgKeyTmp = "tmp_" + sgKeyCalibrated; + std::string sgKeyTmpAux = sgKeyTmp + "Aux."; + const xAOD::JetContainer* calibratedJets(nullptr); - top::check(evtStore()->retrieve(calibratedJets, m_config->sgKeyJets(hash,looseJets)), "Failed to retrieve jets"); + top::check(evtStore()->retrieve(calibratedJets, m_config->sgKeyJets(hash, looseJets)), "Failed to retrieve jets"); ///-- Shallow copy and save to TStore --/// - if (!evtStore()->contains<xAOD::JetContainer>(m_config->sgKeyJetsTDS(hash,looseJets))) { - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jets = xAOD::shallowCopyContainer( *calibratedJets ); - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_jets.first , m_config->sgKeyJetsTDS(hash,looseJets) ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_jets.second , m_config->sgKeyJetsTDSAux(hash,looseJets) ); - top::check( (save && saveAux) , "Failed to store object in TStore"); + if (!evtStore()->contains<xAOD::JetContainer>(m_config->sgKeyJetsTDS(hash, looseJets))) { + std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jets = xAOD::shallowCopyContainer( + *calibratedJets); + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_jets.first, m_config->sgKeyJetsTDS(hash, looseJets)); + xAOD::TReturnCode saveAux = + evtStore()->tds()->record(shallow_jets.second, m_config->sgKeyJetsTDSAux(hash, looseJets)); + top::check((save && saveAux), "Failed to store object in TStore"); } - + ///-- Pull shallow copy back out of TStore in non-const way --/// xAOD::JetContainer* calibratedJetsTDS(nullptr); - top::check(evtStore()->retrieve(calibratedJetsTDS, m_config->sgKeyJetsTDS(hash,looseJets) ), "Failed to retrieve taus"); - + top::check(evtStore()->retrieve(calibratedJetsTDS, m_config->sgKeyJetsTDS(hash, + looseJets)), "Failed to retrieve taus"); + + for (auto index : currentSystematic.goodJets()) { auto jet = calibratedJetsTDS->at(index); if (m_config->isMC()) { - // make product of SF (initialised to 1 in the header) - top::check( jet->isAvailable<float>("JET_SF_jvt") , " Can't find jet decoration \"JET_SF_jvt\" - we need it to calculate the jet scale-factors!"); + // JVT and fJVT, make product of SF (initialised to 1 in the header) + top::check(jet->isAvailable<float>( + "JET_SF_jvt"), + " Can't find jet decoration \"JET_SF_jvt\" - we need it to calculate the jet scale-factors!"); event.m_jvtSF *= jet->auxdataConst<float>("JET_SF_jvt"); - if (currentSystematic.hashValue() == m_config->nominalHashValue()) {// we only need the up/down JVT SF systs for nominal - top::check( jet->isAvailable<float>("JET_SF_jvt_UP") , " Can't find jet decoration \"JET_SF_jvt_UP\" - we need it to calculate the jet scale-factors!"); + + // fJVT scale factors not added to jets unless fJVT is requested + if (m_config->getfJVTWP() != "None") { + top::check(jet->isAvailable<float>( + "JET_SF_fjvt"), + " Can't find jet decoration \"JET_SF_fjvt\" - we need it to calculate the forward jet scale-factors!"); + event.m_fjvtSF *= jet->auxdataConst<float>("JET_SF_fjvt"); + } + if (currentSystematic.hashValue() == m_config->nominalHashValue()) {// we only need the up/down JVT SF systs + // for nominal + top::check(jet->isAvailable<float>( + "JET_SF_jvt_UP"), + " Can't find jet decoration \"JET_SF_jvt_UP\" - we need it to calculate the jet scale-factors!"); event.m_jvtSF_UP *= jet->auxdataConst<float>("JET_SF_jvt_UP"); - top::check( jet->isAvailable<float>("JET_SF_jvt_DOWN") , " Can't find jet decoration \"JET_SF_jvt_DOWN\" - we need it to calculate the jet scale-factors!"); + top::check(jet->isAvailable<float>( + "JET_SF_jvt_DOWN"), + " Can't find jet decoration \"JET_SF_jvt_DOWN\" - we need it to calculate the jet scale-factors!"); event.m_jvtSF_DOWN *= jet->auxdataConst<float>("JET_SF_jvt_DOWN"); - } - } - top::check( jet->isAvailable<char>("passJVT") , " Can't find jet decoration \"passJVT\" - we need it to decide if we should keep the jet in the top::Event instance or not!"); - if (jet->auxdataConst<char>( "passJVT" )) - event.m_jets.push_back(calibratedJetsTDS->at(index)); + // fJVT scale factors not added to jets unless fJVT is requested + if (m_config->getfJVTWP() != "None") { + top::check(jet->isAvailable<float>( + "JET_SF_fjvt_UP"), + " Can't find jet decoration \"JET_SF_fjvt_UP\" - we need it to calculate the forward jet scale-factors!"); + event.m_fjvtSF_UP *= jet->auxdataConst<float>("JET_SF_fjvt_UP"); + top::check(jet->isAvailable<float>( + "JET_SF_fjvt_DOWN"), + " Can't find jet decoration \"JET_SF_fjvt_DOWN\" - we need it to calculate the forward jet scale-factors!"); + event.m_fjvtSF_DOWN *= jet->auxdataConst<float>("JET_SF_fjvt_DOWN"); + } + } //isNominal + } //isMC + + top::check(jet->isAvailable<char>( + "passJVT"), + " Can't find jet decoration \"passJVT\" - we need it to decide if we should keep the jet in the top::Event instance or not!"); + bool passfJVT(true); + if (m_config->doForwardJVTinMET() || m_config->getfJVTWP() != "None") { + top::check(jet->isAvailable<char>("AnalysisTop_fJVTdecision"), + " Can't find jet decoration \"AnalysisTop_fJVTdecision\" - we need it to decide if we should keep forward jets in the top::Event instance or not!"); + passfJVT = jet->auxdataConst<char>("AnalysisTop_fJVTdecision"); + if (m_config->saveFailForwardJVTJets()) { + if (!passfJVT) event.m_failFJvt_jets.push_back(calibratedJetsTDS->at(index)); + } + //Add to failFJVT collection but don't actually cut on fJVT if fJVT is only requested in MET calculation (I'm not sure people will ever actually do this) + if (m_config->getfJVTWP() == "None") passfJVT = true; + } + + if (jet->auxdataConst<char>("passJVT") && passfJVT) event.m_jets.push_back(calibratedJetsTDS->at(index)); + if (m_config->saveFailJVTJets()) { + if (!jet->auxdataConst<char>("passJVT")) event.m_failJvt_jets.push_back(calibratedJetsTDS->at(index)); + } } - + //shallow copies aren't sorted! //sort only the selected taus (faster) event.m_jets.sort(top::descendingPtSorter); + if (m_config->saveFailJVTJets()) event.m_failJvt_jets.sort(top::descendingPtSorter); + if ( (m_config->doForwardJVTinMET() || m_config->getfJVTWP() != "None") && m_config->saveFailForwardJVTJets()){ + event.m_failFJvt_jets.sort(top::descendingPtSorter); + } + } + + // Reclustered jets + if (m_config->useRCJets()) { + top::check(m_rc->execute(event), "Failed to execute RCJetMC15 container"); + std::string rcJetContainerName = m_rc->rcjetContainerName(event.m_hashValue, event.m_isLoose); + const xAOD::JetContainer* rc_jets(nullptr); + top::check(evtStore()->retrieve(rc_jets, rcJetContainerName), "Failed to retrieve RC JetContainer"); + //Object selection + for (auto rcjet : *rc_jets) { + top::check(rcjet->isAvailable<bool>( + "PassedSelection"), + " Can't find jet decoration \"PassedSelection\" - we need it to decide if we should keep the reclustered jet in the top::Event instance or not!"); + if (rcjet->auxdataConst<bool>("PassedSelection")) event.m_RCJets.push_back((xAOD::Jet*) rcjet); + } + } + // Variable-R reclustered jets + if (m_config->useVarRCJets()) { + for (auto& rho : m_VarRCJetRho) { + for (auto& mass_scale : m_VarRCJetMassScale) { + std::replace(rho.begin(), rho.end(), '.', '_'); + std::string name = rho + mass_scale; + top::check(m_VarRC[name]->execute(event), "Failed to execute RCJetMC15 container"); + + // Get the name of the container of re-clustered jets in TStore + std::string varRCJetContainerName = m_VarRC[name]->rcjetContainerName(event.m_hashValue, event.m_isLoose); + + // -- Retrieve the re-clustered jets from TStore & save good re-clustered jets -- // + const xAOD::JetContainer* vrc_jets(nullptr); + top::check(evtStore()->retrieve(vrc_jets, varRCJetContainerName), "Failed to retrieve RC JetContainer"); + + event.m_VarRCJets[name] = std::make_shared<xAOD::JetContainer>(SG::VIEW_ELEMENTS); + for (auto vrcjet : *vrc_jets) { + top::check(vrcjet->isAvailable<bool>( + "PassedSelection"), + " Can't find jet decoration \"PassedSelection\" - we need it to decide if we should keep the variable-R reclustered jet in the top::Event instance or not!"); + if (vrcjet->auxdataConst<bool>("PassedSelection")) event.m_VarRCJets[name]->push_back((xAOD::Jet*) vrcjet); + } + } + } } + //large-R jets if (m_config->useLargeRJets()) { - ///-- Need to read const collections for mini-xaod read back --/// + ///-- Need to read const collections for mini-xaod read back --/// const xAOD::JetContainer* calibratedJets(nullptr); - top::check(evtStore()->retrieve(calibratedJets,m_config->sgKeyLargeRJets(hash) ), "Failed to retrieve largeR jets"); + top::check(evtStore()->retrieve(calibratedJets, m_config->sgKeyLargeRJets(hash)), + "Failed to retrieve largeR jets"); ///-- Shallow copy and save to TStore --/// if (!evtStore()->contains<xAOD::JetContainer>(m_config->sgKeyLargeRJetsTDS(hash))) { - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jets = xAOD::shallowCopyContainer( *calibratedJets ); - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_jets.first , m_config->sgKeyLargeRJetsTDS(hash) ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_jets.second , m_config->sgKeyLargeRJetsTDSAux(hash) ); - top::check( (save && saveAux) , "Failed to store object in TStore"); + std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jets = xAOD::shallowCopyContainer( + *calibratedJets); + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_jets.first, m_config->sgKeyLargeRJetsTDS(hash)); + xAOD::TReturnCode saveAux = + evtStore()->tds()->record(shallow_jets.second, m_config->sgKeyLargeRJetsTDSAux(hash)); + top::check((save && saveAux), "Failed to store object in TStore"); } - + ///-- Pull shallow copy back out of TStore in non-const way --/// xAOD::JetContainer* calibratedJetsTDS(nullptr); - top::check(evtStore()->retrieve(calibratedJetsTDS, m_config->sgKeyLargeRJetsTDS(hash) ), "Failed to retrieve largeR jets"); - + top::check(evtStore()->retrieve(calibratedJetsTDS, m_config->sgKeyLargeRJetsTDS( + hash)), "Failed to retrieve largeR jets"); + for (auto index : currentSystematic.goodLargeRJets()) { event.m_largeJets.push_back(calibratedJetsTDS->at(index)); - } - + } + //shallow copies aren't sorted! //sort only the selected jets (faster) event.m_largeJets.sort(top::descendingPtSorter); } - + //track jets if (m_config->useTrackJets()) { - ///-- Need to read const collections for mini-xaod read back --/// + ///-- Need to read const collections for mini-xaod read back --/// const xAOD::JetContainer* calibratedJets(nullptr); - top::check(evtStore()->retrieve(calibratedJets,m_config->sgKeyTrackJets(hash) ), "Failed to retrieve track jets"); + top::check(evtStore()->retrieve(calibratedJets, m_config->sgKeyTrackJets(hash)), "Failed to retrieve track jets"); ///-- Shallow copy and save to TStore --/// if (!evtStore()->contains<xAOD::JetContainer>(m_config->sgKeyTrackJetsTDS(hash))) { - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jets = xAOD::shallowCopyContainer( *calibratedJets ); - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_jets.first , m_config->sgKeyTrackJetsTDS(hash) ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_jets.second , m_config->sgKeyTrackJetsTDSAux(hash) ); - top::check( (save && saveAux) , "Failed to store object in TStore"); + std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jets = xAOD::shallowCopyContainer( + *calibratedJets); + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_jets.first, m_config->sgKeyTrackJetsTDS(hash)); + xAOD::TReturnCode saveAux = + evtStore()->tds()->record(shallow_jets.second, m_config->sgKeyTrackJetsTDSAux(hash)); + top::check((save && saveAux), "Failed to store object in TStore"); } - + ///-- Pull shallow copy back out of TStore in non-const way --/// xAOD::JetContainer* calibratedJetsTDS(nullptr); - top::check(evtStore()->retrieve(calibratedJetsTDS, m_config->sgKeyTrackJetsTDS(hash) ), "Failed to retrieve track jets"); - + top::check(evtStore()->retrieve(calibratedJetsTDS, m_config->sgKeyTrackJetsTDS( + hash)), "Failed to retrieve track jets"); + for (auto index : currentSystematic.goodTrackJets()) { event.m_trackJets.push_back(calibratedJetsTDS->at(index)); - } - + } + //shallow copies aren't sorted! //sort only the selected jets (faster) event.m_trackJets.sort(top::descendingPtSorter); - } + } + + if (m_config->useTracks()) { + + ///-- Need to read const collections for mini-xaod read back --/// + const xAOD::TrackParticleContainer* calibratedTracks(nullptr); + top::check(evtStore()->retrieve(calibratedTracks, m_config->sgKeyTracks(hash)), "Failed to retrieve tracks"); + + ///-- Shallow copy and save to TStore --/// + if (!evtStore()->contains<xAOD::TrackParticleContainer>(m_config->sgKeyTracksTDS(hash))) { + + std::pair< xAOD::TrackParticleContainer*, xAOD::ShallowAuxContainer* > shallow_tracks = xAOD::shallowCopyContainer(*calibratedTracks); + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_tracks.first, m_config->sgKeyTracksTDS(hash)); + xAOD::TReturnCode saveAux = + evtStore()->tds()->record(shallow_tracks.second, m_config->sgKeyTracksTDSAux(hash)); + top::check((save && saveAux), "Failed to store object in TStore"); + } + + ///-- Pull shallow copy back out of TStore in non-const way --/// + xAOD::TrackParticleContainer* calibratedTracksTDS(nullptr); + top::check(evtStore()->retrieve(calibratedTracksTDS, m_config->sgKeyTracksTDS(hash)), "Failed to retrieve tracks"); + + for (auto index : currentSystematic.goodTracks()) { + event.m_tracks.push_back(calibratedTracksTDS->at(index)); + } + + //shallow copies aren't sorted! + //sort only the selected tracks (faster) + event.m_tracks.sort(top::descendingPtSorter); + + } + //met const xAOD::MissingETContainer* mets(nullptr); @@ -324,33 +586,90 @@ namespace top { top::check(evtStore()->retrieve(mets, m_config->sgKeyMissingEtLoose(hash)), "Failed to retrieve MET"); } event.m_met = (*mets)["FinalTrk"]; // MissingETBase::Source::total()]; - + //MC if (m_config->isMC()) { - // Truth particles (these are BIG) if (m_config->useTruthParticles()) { - top::check(evtStore()->retrieve(event.m_truth, m_config->sgKeyMCParticle()), "Failed to retrieve truth particles"); - } - + top::check(evtStore()->retrieve(event.m_truth, + m_config->sgKeyMCParticle()), "Failed to retrieve truth particles"); + } + // Truth Event - top::check(evtStore()->retrieve(event.m_truthEvent,m_config->sgKeyTruthEvent()),"Failed to retrieve truth Event"); - + if (TopEventMaker::s_hasTruthEvent) { + bool hasTruthEvent = evtStore()->retrieve(event.m_truthEvent, m_config->sgKeyTruthEvent()); + if (!hasTruthEvent) { + ATH_MSG_WARNING("Failed to retrieve truth Event. TopEvent::m_truthEvent will be nullptr!"); + TopEventMaker::s_hasTruthEvent = false; + } + } + // Parton History if (m_config->doTopPartonHistory()) { if (evtStore()->contains<xAOD::PartonHistoryContainer>(m_config->sgKeyTopPartonHistory())) { const xAOD::PartonHistoryContainer* partonHistory(nullptr); - top::check(evtStore()->retrieve(partonHistory, m_config->sgKeyTopPartonHistory()),"Failed to retrieve Top Parton History"); + top::check(evtStore()->retrieve(partonHistory, + m_config->sgKeyTopPartonHistory()), "Failed to retrieve Top Parton History"); if (partonHistory->size() == 1) { event.m_partonHistory = partonHistory->at(0); - } + } } } // end doTopPartonHistory - - } // end isMC - - + } // end isMC + decorateTopEvent(event); + return event; } + + void TopEventMaker::decorateTopEvent(top::Event &event) + { + if(m_config->useSoftMuons()) decorateTopEventSoftMuons(event); + } + + void TopEventMaker::decorateTopEventSoftMuons(top::Event &event) + { + if(!m_config->useJets()) return; + + //first we initialize decorations for all jets + for(const xAOD::Jet* jet : event.m_jets) + { + jet->auxdecor<int>("AT_SoftMuonIndex")=-1; + jet->auxdecor<float>("AT_SoftMuonDR")=-1; + } + + int imuon=0; + for(const xAOD::Muon* sm : event.m_softmuons) + { + //writing auxiliary info for SMT jet tagging + double dRmin=100.; + int nearestJetIndex=-1; + int ijet=0; + for(const xAOD::Jet *jet : event.m_jets) + { + double dr= xAOD::P4Helpers::deltaR(sm,jet,m_config->softmuonDRJetcutUseRapidity()); + if(dr<dRmin && dr<m_config->softmuonDRJetcut()) + { + dRmin=dr; + nearestJetIndex=ijet; + } + ijet++; + } + sm->auxdecor<int>("AT_SMTJetIndex")=nearestJetIndex; + sm->auxdecor<float>("AT_SMTJetDR")=dRmin; + + if(nearestJetIndex>=0) + { + const xAOD::Jet *jet = event.m_jets[nearestJetIndex]; + if(jet->auxdecor<int>("AT_SoftMuonIndex")<0) //in this way we only associate a jet with the highest pt soft muon + { + jet->auxdecor<int>("AT_SoftMuonIndex")=imuon; + jet->auxdecor<float>("AT_SoftMuonDR")=dRmin; + } + }//end of case where we found a jet nearby + + imuon++; + }//end of loop on muons + + }//end of TopEventMaker::decorateTopEvent } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/Event.h b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/Event.h index 6216e0afec92..205300b4823a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/Event.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/Event.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPEVENT_H_ #define TOPEVENT_H_ @@ -9,6 +9,7 @@ #include "xAODTracking/VertexContainer.h" #include "xAODEgamma/ElectronContainer.h" +#include "xAODEgamma/ElectronContainerFwd.h" #include "xAODEgamma/PhotonContainer.h" #include "xAODMuon/MuonContainer.h" #include "xAODJet/JetContainer.h" @@ -24,12 +25,17 @@ #include <ostream> #include <iostream> + + +namespace xAOD { + class SystematicEvent; +} + /** * @brief A namespace for the top group, to avoid using the same name as * somewhere else in the code. */ namespace top { - /** * @brief Very simple class to hold event data after reading from a file. * @@ -40,32 +46,37 @@ namespace top { * The best way to ensure this is reset every event is probably to make a new * one every event, that way it'll tidy-up after itself. */ -class Event { -public: + class Event { + public: Event() : - m_hashValue(0), // this will be set properly by TopEventMaker - m_ttreeIndex(99999), // this will be set properly by TopEventMaker - m_isLoose(false), // this will be set properly by TopEventMaker - m_saveEvent(false), - m_info(nullptr), - m_primaryVertices(nullptr), - m_electrons(SG::VIEW_ELEMENTS), - m_muons(SG::VIEW_ELEMENTS), - m_jets(SG::VIEW_ELEMENTS), - m_photons(SG::VIEW_ELEMENTS), - m_largeJets(SG::VIEW_ELEMENTS), - m_trackJets(SG::VIEW_ELEMENTS), - m_tauJets(SG::VIEW_ELEMENTS), - m_met(nullptr), - - m_truthEvent(nullptr), - m_truth(nullptr), - m_partonHistory(nullptr), - m_KLFitterResults(nullptr), - m_PseudoTopResult(nullptr) - { + m_hashValue(0), // this will be set properly by TopEventMaker + m_ttreeIndex(99999), // this will be set properly by TopEventMaker + m_isLoose(false), // this will be set properly by TopEventMaker + m_saveEvent(false), + m_info(nullptr), + m_primaryVertices(nullptr), + m_electrons(SG::VIEW_ELEMENTS), + m_fwdElectrons(SG::VIEW_ELEMENTS), + m_muons(SG::VIEW_ELEMENTS), + m_softmuons(SG::VIEW_ELEMENTS), + m_jets(SG::VIEW_ELEMENTS), + m_failJvt_jets(SG::VIEW_ELEMENTS), + m_failFJvt_jets(SG::VIEW_ELEMENTS), + m_photons(SG::VIEW_ELEMENTS), + m_largeJets(SG::VIEW_ELEMENTS), + m_RCJets(SG::VIEW_ELEMENTS), + m_trackJets(SG::VIEW_ELEMENTS), + m_tracks(SG::VIEW_ELEMENTS), + m_tauJets(SG::VIEW_ELEMENTS), + m_met(nullptr), + + m_truthEvent(nullptr), + m_truth(nullptr), + m_partonHistory(nullptr), + m_KLFitterResults(nullptr), + m_PseudoTopResult(nullptr) { } - + ///systematic has value std::size_t m_hashValue; ///TTree index @@ -74,71 +85,97 @@ public: bool m_isLoose; ///save the event? bool m_saveEvent; - + ///Pointer to the event info - nullptr if not loaded, but that's probably a bad idea const xAOD::EventInfo* m_info; - + + ///Pointer to the systematic event info - nullptr if not loaded, but that's probably a bad idea + xAOD::SystematicEvent const* m_systematicEvent; + ///Primary Vertices - const xAOD::VertexContainer* m_primaryVertices; + const xAOD::VertexContainer* m_primaryVertices; ///Container of electrons (can be sorted) xAOD::ElectronContainer m_electrons; + ///Container of forward electrons (can be sorted) + xAOD::ElectronContainer m_fwdElectrons; + ///Container of muons (can be sorted) xAOD::MuonContainer m_muons; + ///Container of soft muons (can be sorted) + xAOD::MuonContainer m_softmuons; + ///Container of jets (can be sorted) xAOD::JetContainer m_jets; - - ///Container of photons (can be sorted) + + ///Container of fail-JVT jets (can be sorted) + xAOD::JetContainer m_failJvt_jets; + + ///Container of fail-FJVT jets (can be sorted) + xAOD::JetContainer m_failFJvt_jets; + + ///Container of photons (can be sorted) xAOD::PhotonContainer m_photons; ///Container of large jets (can be sorted) xAOD::JetContainer m_largeJets; - + + ///Container of recluster jets (can be sorted) + xAOD::JetContainer m_RCJets; + + /// Containers of variable-R reclustered jets (can be sorted) + mutable std::unordered_map< std::string, std::shared_ptr<xAOD::JetContainer> > m_VarRCJets; + ///Container of track jets (can be sorted) - xAOD::JetContainer m_trackJets; + xAOD::JetContainer m_trackJets; + + ///Container of tracks (can be sorted) + xAOD::TrackParticleContainer m_tracks; ///Container of taujets (can be sorted) xAOD::TauJetContainer m_tauJets; ///Pointer to MET if it is loaded const xAOD::MissingET* m_met; - + ///Truth event const xAOD::TruthEventContainer* m_truthEvent; ///Container of truth particles - const xAOD::TruthParticleContainer *m_truth; - + const xAOD::TruthParticleContainer* m_truth; + ///Top Parton TopPartonHistory - const xAOD::PartonHistory* m_partonHistory; - + const xAOD::PartonHistory* m_partonHistory; + ///KLFitter Results mutable const xAOD::KLFitterResultContainer* m_KLFitterResults; ///Pseudo Top Results mutable const xAOD::PseudoTopResultContainer* m_PseudoTopResult; - ///JVT SFs - now needed here because it includes jets that are good jets, + ///JVT and fJVT SFs - now needed here because they include jets that are good jets, ///but which are not in the top::Event::m_jets container float m_jvtSF = 1.; float m_jvtSF_UP = 1.; float m_jvtSF_DOWN = 1.; - -}; - + float m_fjvtSF = 1.; + float m_fjvtSF_UP = 1.; + float m_fjvtSF_DOWN = 1.; + }; } -std::ostream& operator<<(std::ostream& os, const TLorentzVector& v); -std::ostream& operator<<(std::ostream& os, const top::Event& event); -std::ostream& operator<<(std::ostream& os, const xAOD::EventInfo& ei); -std::ostream& operator<<(std::ostream& os, const xAOD::Electron& el); -std::ostream& operator<<(std::ostream& os, const xAOD::Muon& mu); -std::ostream& operator<<(std::ostream& os, const xAOD::Photon& ph); -std::ostream& operator<<(std::ostream& os, const xAOD::Jet& jet); -std::ostream& operator<<(std::ostream& os, const xAOD::TauJet& tau); -std::ostream& operator<<(std::ostream& os, const xAOD::TruthParticle& truth); -std::ostream& operator<<(std::ostream& os, const xAOD::MissingET& met); +std::ostream& operator << (std::ostream& os, const TLorentzVector& v); +std::ostream& operator << (std::ostream& os, const top::Event& event); +std::ostream& operator << (std::ostream& os, const xAOD::EventInfo& ei); +std::ostream& operator << (std::ostream& os, const xAOD::Electron& el); +std::ostream& operator << (std::ostream& os, const xAOD::Muon& mu); +std::ostream& operator << (std::ostream& os, const xAOD::Photon& ph); +std::ostream& operator << (std::ostream& os, const xAOD::Jet& jet); +std::ostream& operator << (std::ostream& os, const xAOD::TauJet& tau); +std::ostream& operator << (std::ostream& os, const xAOD::TruthParticle& truth); +std::ostream& operator << (std::ostream& os, const xAOD::MissingET& met); +std::ostream& operator << (std::ostream& os, const xAOD::TrackParticle& track); #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/EventTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/EventTools.h index b11b64ca534e..45dc2bcbcfad 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/EventTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/EventTools.h @@ -1,11 +1,12 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTTOOLS_H_ #define EVENTTOOLS_H_ #include <string> +#include <vector> #include "xAODMissingET/MissingET.h" @@ -19,11 +20,62 @@ */ namespace xAOD { -class IParticle; + class IParticle; } namespace top { -class Event; + class Event; + + ///this enum defines a flag used to understand the partonic origin of a lepton (tipically a soft muon), i.e. if it is produced by the direct decay of a boson, + ///or, in the case it is from a HF hadron decay, what is the boson/parton that originated the HF hadron. + ///This flag will not work for Sherpa samples given the structure of Sherpa's truth record. + /// note that in case of light-hadrons->muons the muon will always be considered as from "unknown", because often we cannot reconstruct the history when light hadrons are involved... + enum class LepPartonOriginFlag{ + MissingTruthInfo=0, ///< e.g. this can mean the muon is coming from light hadrons and there is no truth history, or anyway it was impossible to reconstruct the history + FromAntiTopViaHadronicBosonToHF=-3, ///< tipically means that the muon is coming from tbar->W->...->muon in some way (or any tbar->W/Z/gamma*/H->...->muon), the "..." must involve HF hadrons + FromAntiTopViaLeptonicBoson=-2, ///< tipically means that the muon is coming from tbar->W->...->muon in some way (or any tbar->W/Z/gamma*/H->...->muon), the "..." cannot involve hadrons + FromAntiTopViaQuarkToHF=-1, ///< tipically means that the muon is coming from tbar->bbar->...->muon in some way (or any tbar->qbar->...->muon), the "..." will for sure involve HF hadrons + FromTopViaQuarkToHF=1, ///< tipically means that the muon is coming from t->b->...->muon in some way (or any t->q->...->muon), the "..." will for sure involve HF hadrons + FromTopViaLeptonicBoson=2, ///< tipically means that the muon is coming from t->W->...->muon in some way (or any t->W/Z/gamma*/H->...->muon), the "..." cannot involve hadrons + FromTopViaHadronicBosonToHF=3, ///< tipically means that the muon is coming from t->W->...->muon in some way (or any t->W/Z/gamma*/H->...->muon), the "..." must involve HF hadrons + FromLeptonicBoson=4, ///< general case of W/Z/gamma*/H->muon or W/Z/gamma*/H->tau->muon + FromHadronicBosonToHF=5, ///< general case of W/Z/gamma*/H->HF hadrons->muon + FromHFHadronOfUnkownOrigin=6, ///< HF hadron->muon or HF hadron->tau->muon, we're not sure where the HF hadron is coming from (maybe a gluon?) + FromHiggsViaLeptonicBosonToHF=7, ///H->VV->muon + FromHiggsViaHadronicBosonToHF=8, ///H->VV->HF->muon + FromHiggsToHF=9, ///H->HF->muon, not sure if this can happen in some generators + FromHiggs=10, ///direct H->muon + FromBSM=1000, /// BSMparticle->muon + FromBSMViaLeptonicBosonToHF=1001, /// BSMparticle->V->muon + FromBSMViaHadronicBosonToHF=1002, /// BSMparticle->V->HF->muon + FromBSMToHF=1003, /// BSMparticle->HF->muon + Unknown=9999, /// we have truth info but we were unable to classify the muon + }; + + ///this enum defines a flag used to understand the particle origin of a lepton (tipically a soft muon), + ///i.e. if it is from a boson decay, from a B-hadron, from a B->D->mu decay, etc... + enum class LepParticleOriginFlag{ + MissingTruthInfo=0, ///< no associated truth muon tipically this happens for muon from light-hadrons + FromPhoton=22, ///gamma*->muonmuon + FromPhotonToTau=2215, ///gamma*->tautau and tau->muon + FromLeptonicZ=23, ///< from Z->tau->lep (note: this will not work for Sherpa) + FromLeptonicZToTau=2315, ///< from Z->tau->lep (note: this will not work for Sherpa) + FromLeptonicW=24, ///< from W with leptonic decay (note: this will not work for Sherpa) + FromLeptonicWToTau=2415, ///< from W->tau->lep (note: this will not work for Sherpa) + FromHiggs=25, ///Higgs->muon + FromHiggsToTau=2515, ///Higgs->tau->mu + FromB=5, ///< from direct B-hadron decay + FromBtoTau=515, ///< from B-hadron to tau to mu decay + FromBtoC=54, ///< from B-hadron to C-hadron to muon decay + FromBtoCtoTau=5415, ///< from B-hadron to C-hadron to tau to muon decay + FromC=4, ///< from direct C-hadron (with no B-hadron parent) decay + FromCtoTau=415, ///< from C-hadron (with no B-hadron parent) to tau to mu decay + FromTau=15, ///< from Tau leptonic (not coming from W or HF-hadron, so not sure this can really happen) + FromLightHadron=100, ///< often these muons are Unknown, but in some cases we have the truth record and we can verify they are from light-hadrons + FromBSM=1000, ///BSMparticle->muon + FromBSMToTau=1001, ///BSMparticle->tau->muon + Unknown=9999, /// we have truth info but we were unable to classify the muon + }; /** * @brief Print an error message and terminate if thingToCheck is false. @@ -31,12 +83,12 @@ class Event; * Lots of the xAOD functions need checking to see if they work or not. I guess * we take the approach that if it didn't work, we should not really try to * recover but just print a message and quit as soon as we can. So, this will - * either return nothing or quit your program. + * either return nothing or quit your program via exception. * * @param thingToCheck The thing to check. If it's false then print the error - * message and quit. + * message via std::runtime_error exception. */ -void check(bool thingToCheck, const std::string& usefulFailureMessage); + void check(bool thingToCheck, const std::string& usefulFailureMessage); /** * @brief Calculate the delta-r distance between two particles (e.g. an Electron @@ -49,7 +101,7 @@ void check(bool thingToCheck, const std::string& usefulFailureMessage); * @param p2 The second particle of the two. * @return delta-R metric. */ -double deltaR(const xAOD::IParticle& p1, const xAOD::IParticle& p2); + double deltaR(const xAOD::IParticle& p1, const xAOD::IParticle& p2); /** * @brief Calculate delta-phi between two particles (e.g. an Electron and a @@ -59,7 +111,7 @@ double deltaR(const xAOD::IParticle& p1, const xAOD::IParticle& p2); * @param p2 The second particle of the two. * @return Signed delta-phi in radians. */ -double deltaPhi(const xAOD::IParticle& p1, const xAOD::IParticle& p2); + double deltaPhi(const xAOD::IParticle& p1, const xAOD::IParticle& p2); /** * @brief Calculate the transverse mass of the W from the charged lepton and @@ -69,7 +121,7 @@ double deltaPhi(const xAOD::IParticle& p1, const xAOD::IParticle& p2); * * @return The calculated value, obviously. */ -double mwt(const xAOD::IParticle& lepton, const xAOD::MissingET& met); + double mwt(const xAOD::IParticle& lepton, const xAOD::MissingET& met); /** * @brief HT calculation. @@ -79,7 +131,7 @@ double mwt(const xAOD::IParticle& lepton, const xAOD::MissingET& met); * * @return The HT value. */ -double ht(const top::Event& event); + double ht(const top::Event& event); /** * @brief Calculate the invariant mass of two particles. @@ -92,14 +144,14 @@ double ht(const top::Event& event); * * @return The invariant mass of the pair. */ -double invariantMass(const xAOD::IParticle& p1, const xAOD::IParticle& p2); + double invariantMass(const xAOD::IParticle& p1, const xAOD::IParticle& p2); /** * @brief Is this event MC simulation (True) or data (False)? * * @return True if the event is MC simulation. */ -bool isSimulation(const top::Event& event); + bool isSimulation(const top::Event& event); /** * @brief Used when sorting the e, mu, jet, tau containers after CP corrections. @@ -111,8 +163,16 @@ bool isSimulation(const top::Event& event); * @param p2 The second particle of the two. * */ -bool descendingPtSorter(const xAOD::IParticle* p0, const xAOD::IParticle* p1); + bool descendingPtSorter(const xAOD::IParticle* p0, const xAOD::IParticle* p1); +/** + * @brief Function used to create poisson weights (mean of 1) for bootstrapping + * + * @param nreplicas The number of replicas to fill (corresponds to size of output vector) + * @param eventNumber The event number used to seed TRandom3 + * @param mcChannelNumber The DSID of MC event used to seed TRandom3 + */ + std::vector<int> calculateBootstrapWeights(int nreplicas, int eventNumber, int mcChannelNumber); } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/KLFitterResult.h b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/KLFitterResult.h index d19b2bdbca6d..e38e742ef615 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/KLFitterResult.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/KLFitterResult.h @@ -1,25 +1,25 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: SystematicEvent.h 661144 2015-04-17 09:09:07Z morrisj $ #ifndef ANALYSISTOP_TOPEVENT_KLFITTERRESULT_H #define ANALYSISTOP_TOPEVENT_KLFITTERRESULT_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief KLFitterResult - * A simple xAOD class which we can persist into a mini-xAOD - * The xAOD EDM is way too complex, so let's simplify it - * It's not like ROOT can do schema evolution...... - * - * This class contains the result of the KLFitter algorithm - * - * $Revision: 661144 $ - * $Date: 2015-04-17 10:09:07 +0100 (Fri, 17 Apr 2015) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief KLFitterResult + * A simple xAOD class which we can persist into a mini-xAOD + * The xAOD EDM is way too complex, so let's simplify it + * It's not like ROOT can do schema evolution...... + * + * This class contains the result of the KLFitter algorithm + * + * $Revision: 661144 $ + * $Date: 2015-04-17 10:09:07 +0100 (Fri, 17 Apr 2015) $ + * + **/ // EDM include(s): #include "AthContainers/DataVector.h" @@ -29,338 +29,594 @@ #include <vector> #include <stdint.h> -namespace xAOD{ - - /// Aux Container - class KLFitterResultAuxContainer : public AuxContainerBase { - public: - KLFitterResultAuxContainer(); - private: - - /// Error flags - std::vector<short> minuitDidNotConverge; - std::vector<short> fitAbortedDueToNaN; - std::vector<short> atLeastOneFitParameterAtItsLimit; - std::vector<short> invalidTransferFunctionAtConvergence; - - /// Global result - std::vector<unsigned int> bestPermutation; - std::vector<float> logLikelihood; - std::vector<float> eventProbability; - std::vector<std::vector<double>> parameters; - std::vector<std::vector<double>> parameterErrors; - - /// Model - std::vector<float> model_bhad_pt; - std::vector<float> model_bhad_eta; - std::vector<float> model_bhad_phi; - std::vector<float> model_bhad_E; - std::vector<unsigned int> model_bhad_jetIndex; - - std::vector<float> model_blep_pt; - std::vector<float> model_blep_eta; - std::vector<float> model_blep_phi; - std::vector<float> model_blep_E; - std::vector<unsigned int> model_blep_jetIndex; - - std::vector<float> model_lq1_pt; - std::vector<float> model_lq1_eta; - std::vector<float> model_lq1_phi; - std::vector<float> model_lq1_E; - std::vector<unsigned int> model_lq1_jetIndex; - - std::vector<float> model_lq2_pt; - std::vector<float> model_lq2_eta; - std::vector<float> model_lq2_phi; - std::vector<float> model_lq2_E; - std::vector<unsigned int> model_lq2_jetIndex; - - - // model particles in case of TTH topology - std::vector<float> model_Higgs_b1_pt; - std::vector<float> model_Higgs_b1_eta; - std::vector<float> model_Higgs_b1_phi; - std::vector<float> model_Higgs_b1_E; - std::vector<unsigned int> model_Higgs_b1_jetIndex; - - std::vector<float> model_Higgs_b2_pt; - std::vector<float> model_Higgs_b2_eta; - std::vector<float> model_Higgs_b2_phi; - std::vector<float> model_Higgs_b2_E; - std::vector<unsigned int> model_Higgs_b2_jetIndex; - - - std::vector<float> model_lep_pt; - std::vector<float> model_lep_eta; - std::vector<float> model_lep_phi; - std::vector<float> model_lep_E; - - std::vector<float> model_nu_pt; - std::vector<float> model_nu_eta; - std::vector<float> model_nu_phi; - std::vector<float> model_nu_E; - - - +namespace xAOD { + /// Aux Container + class KLFitterResultAuxContainer: public AuxContainerBase { + public: + KLFitterResultAuxContainer(); + private: + /// Name of selection run + std::vector<std::size_t> selectionCode; + + /// Error flags + std::vector<short> minuitDidNotConverge; + std::vector<short> fitAbortedDueToNaN; + std::vector<short> atLeastOneFitParameterAtItsLimit; + std::vector<short> invalidTransferFunctionAtConvergence; + + /// Global result + std::vector<unsigned int> bestPermutation; + std::vector<float> logLikelihood; + std::vector<float> eventProbability; + std::vector<std::vector<double> > parameters; + std::vector<std::vector<double> > parameterErrors; + + /// Model + std::vector<float> model_bhad_pt; + std::vector<float> model_bhad_eta; + std::vector<float> model_bhad_phi; + std::vector<float> model_bhad_E; + std::vector<unsigned int> model_bhad_jetIndex; + + std::vector<float> model_blep_pt; + std::vector<float> model_blep_eta; + std::vector<float> model_blep_phi; + std::vector<float> model_blep_E; + std::vector<unsigned int> model_blep_jetIndex; + + std::vector<float> model_lq1_pt; + std::vector<float> model_lq1_eta; + std::vector<float> model_lq1_phi; + std::vector<float> model_lq1_E; + std::vector<unsigned int> model_lq1_jetIndex; + + std::vector<float> model_lq2_pt; + std::vector<float> model_lq2_eta; + std::vector<float> model_lq2_phi; + std::vector<float> model_lq2_E; + std::vector<unsigned int> model_lq2_jetIndex; + + + // model particles in case of TTH topology + std::vector<float> model_Higgs_b1_pt; + std::vector<float> model_Higgs_b1_eta; + std::vector<float> model_Higgs_b1_phi; + std::vector<float> model_Higgs_b1_E; + std::vector<unsigned int> model_Higgs_b1_jetIndex; + + std::vector<float> model_Higgs_b2_pt; + std::vector<float> model_Higgs_b2_eta; + std::vector<float> model_Higgs_b2_phi; + std::vector<float> model_Higgs_b2_E; + std::vector<unsigned int> model_Higgs_b2_jetIndex; + + + std::vector<float> model_lep_pt; + std::vector<float> model_lep_eta; + std::vector<float> model_lep_phi; + std::vector<float> model_lep_E; + std::vector<unsigned int> model_lep_index; + + // model particles for the TTZ trilepton channel + std::vector<float> model_lepZ1_pt; + std::vector<float> model_lepZ1_eta; + std::vector<float> model_lepZ1_phi; + std::vector<float> model_lepZ1_E; + std::vector<unsigned int> model_lepZ1_index; + + std::vector<float> model_lepZ2_pt; + std::vector<float> model_lepZ2_eta; + std::vector<float> model_lepZ2_phi; + std::vector<float> model_lepZ2_E; + std::vector<unsigned int> model_lepZ2_index; + + std::vector<float> model_nu_pt; + std::vector<float> model_nu_eta; + std::vector<float> model_nu_phi; + std::vector<float> model_nu_E; + + // model particles for ttbar allhadronic channel + std::vector<float> model_b_from_top1_pt; + std::vector<float> model_b_from_top1_eta; + std::vector<float> model_b_from_top1_phi; + std::vector<float> model_b_from_top1_E; + std::vector<unsigned int> model_b_from_top1_jetIndex; + + std::vector<float> model_b_from_top2_pt; + std::vector<float> model_b_from_top2_eta; + std::vector<float> model_b_from_top2_phi; + std::vector<float> model_b_from_top2_E; + std::vector<unsigned int> model_b_from_top2_jetIndex; + + std::vector<float> model_lj1_from_top1_pt; + std::vector<float> model_lj1_from_top1_eta; + std::vector<float> model_lj1_from_top1_phi; + std::vector<float> model_lj1_from_top1_E; + std::vector<unsigned int> model_lj1_from_top1_jetIndex; + + std::vector<float> model_lj2_from_top1_pt; + std::vector<float> model_lj2_from_top1_eta; + std::vector<float> model_lj2_from_top1_phi; + std::vector<float> model_lj2_from_top1_E; + std::vector<unsigned int> model_lj2_from_top1_jetIndex; + + std::vector<float> model_lj1_from_top2_pt; + std::vector<float> model_lj1_from_top2_eta; + std::vector<float> model_lj1_from_top2_phi; + std::vector<float> model_lj1_from_top2_E; + std::vector<unsigned int> model_lj1_from_top2_jetIndex; + + std::vector<float> model_lj2_from_top2_pt; + std::vector<float> model_lj2_from_top2_eta; + std::vector<float> model_lj2_from_top2_phi; + std::vector<float> model_lj2_from_top2_E; + std::vector<unsigned int> model_lj2_from_top2_jetIndex; }; - + /// Interface class - class KLFitterResult : public SG::AuxElement { - public: - /// Default constructor - KLFitterResult(); - /// Default destructor - virtual ~KLFitterResult(){} - - /// get minuitDidNotConverge - short minuitDidNotConverge() const; - /// set minuitDidNotConverge - void setMinuitDidNotConverge(short); - - /// get fitAbortedDueToNaN - short fitAbortedDueToNaN() const; - /// set fitAbortedDueToNaN - void setFitAbortedDueToNaN(short); - - /// get atLeastOneFitParameterAtItsLimit - short atLeastOneFitParameterAtItsLimit() const; - /// set atLeastOneFitParameterAtItsLimit - void setAtLeastOneFitParameterAtItsLimit(short); - - /// get invalidTransferFunctionAtConvergence - short invalidTransferFunctionAtConvergence() const; - /// set invalidTransferFunctionAtConvergence - void setInvalidTransferFunctionAtConvergence(short); - - /// get bestPermutation - unsigned int bestPermutation() const; - /// set bestPermutation - void setBestPermutation(unsigned int); - - /// get logLikelihood - float logLikelihood() const; - /// set logLikelihood - void setLogLikelihood(float); - - /// get eventProbability - float eventProbability() const; - /// set eventProbability - void setEventProbability(float); - - /// get parameters - const std::vector<double>& parameters() const; - /// set parameters - void setParameters(const std::vector<double>&); - - /// get parameterErrors - const std::vector<double>& parameterErrors() const; - /// set parameterErrors - void setParameterErrors(const std::vector<double>&); - - - /// get model_bhad_pt - float model_bhad_pt() const; - /// set model_bhad_pt - void setModel_bhad_pt(float); - - /// get model_bhad_eta - float model_bhad_eta() const; - /// set model_bhad_eta - void setModel_bhad_eta(float); - - /// get model_bhad_phi - float model_bhad_phi() const; - /// set model_bhad_phi - void setModel_bhad_phi(float); - - /// get model_bhad_E - float model_bhad_E() const; - /// set model_bhad_E - void setModel_bhad_E(float); - - /// get model_bhad_jetIndex - unsigned int model_bhad_jetIndex() const; - /// set model_bhad_jetIndex - void setModel_bhad_jetIndex(unsigned int); - - - /// get model_blep_pt - float model_blep_pt() const; - /// set model_blep_pt - void setModel_blep_pt(float); - - /// get model_blep_eta - float model_blep_eta() const; - /// set model_blep_eta - void setModel_blep_eta(float); - - /// get model_blep_phi - float model_blep_phi() const; - /// set model_blep_phi - void setModel_blep_phi(float); - - /// get model_blep_E - float model_blep_E() const; - /// set model_blep_E - void setModel_blep_E(float); - - /// get model_blep_jetIndex - unsigned int model_blep_jetIndex() const; - /// set model_blep_jetIndex - void setModel_blep_jetIndex(unsigned int); - - - /// get model_lq1_pt - float model_lq1_pt() const; - /// set model_lq1_pt - void setModel_lq1_pt(float); - - /// get model_lq1_eta - float model_lq1_eta() const; - /// set model_lq1_eta - void setModel_lq1_eta(float); - - /// get model_lq1_phi - float model_lq1_phi() const; - /// set model_lq1_phi - void setModel_lq1_phi(float); - - /// get model_lq1_E - float model_lq1_E() const; - /// set model_lq1_E - void setModel_lq1_E(float); - - /// get model_lq1_jetIndex - unsigned int model_lq1_jetIndex() const; - /// set model_lq1_jetIndex - void setModel_lq1_jetIndex(unsigned int); - - - /// get model_lq2_pt - float model_lq2_pt() const; - /// set model_lq2_pt - void setModel_lq2_pt(float); - - /// get model_lq2_eta - float model_lq2_eta() const; - /// set model_lq2_eta - void setModel_lq2_eta(float); - - /// get model_lq2_phi - float model_lq2_phi() const; - /// set model_lq2_phi - void setModel_lq2_phi(float); - - /// get model_lq2_E - float model_lq2_E() const; - /// set model_lq2_E - void setModel_lq2_E(float); - - /// get model_lq2_jetIndex - unsigned int model_lq2_jetIndex() const; - /// set model_lq2_jetIndex - void setModel_lq2_jetIndex(unsigned int); - - /// get model_Higgs_b1_pt - float model_Higgs_b1_pt() const; - /// set model_Higgs_b1_pt - void setModel_Higgs_b1_pt(float); - - /// get model_Higgs_b1_eta - float model_Higgs_b1_eta() const; - /// set model_Higgs_b1_eta - void setModel_Higgs_b1_eta(float); - - /// get model_Higgs_b1_phi - float model_Higgs_b1_phi() const; - /// set model_Higgs_b1_phi - void setModel_Higgs_b1_phi(float); - - /// get model_Higgs_b1_E - float model_Higgs_b1_E() const; - /// set model_Higgs_b1_E - void setModel_Higgs_b1_E(float); - - /// get model_Higgs_b1_jetIndex - unsigned int model_Higgs_b1_jetIndex() const; - /// set model_Higgs_b1_jetIndex - void setModel_Higgs_b1_jetIndex(unsigned int); - - - /// get model_Higgs_b2_pt - float model_Higgs_b2_pt() const; - /// set model_Higgs_b2_pt - void setModel_Higgs_b2_pt(float); - - /// get model_Higgs_b2_eta - float model_Higgs_b2_eta() const; - /// set model_Higgs_b2_eta - void setModel_Higgs_b2_eta(float); - - /// get model_Higgs_b2_phi - float model_Higgs_b2_phi() const; - /// set model_Higgs_b2_phi - void setModel_Higgs_b2_phi(float); - - /// get model_Higgs_b2_E - float model_Higgs_b2_E() const; - /// set model_Higgs_b2_E - void setModel_Higgs_b2_E(float); - - /// get model_Higgs_b2_jetIndex - unsigned int model_Higgs_b2_jetIndex() const; - /// set model_Higgs_b2_jetIndex - void setModel_Higgs_b2_jetIndex(unsigned int); - - /// get model_lep_pt - float model_lep_pt() const; - /// set model_lep_pt - void setModel_lep_pt(float); - - /// get model_lep_eta - float model_lep_eta() const; - /// set model_lep_eta - void setModel_lep_eta(float); - - /// get model_lep_phi - float model_lep_phi() const; - /// set model_lep_phi - void setModel_lep_phi(float); - - /// get model_lep_E - float model_lep_E() const; - /// set model_lep_E - void setModel_lep_E(float); - - - /// get model_nu_pt - float model_nu_pt() const; - /// set model_nu_pt - void setModel_nu_pt(float); - - /// get model_nu_eta - float model_nu_eta() const; - /// set model_nu_eta - void setModel_nu_eta(float); - - /// get model_nu_phi - float model_nu_phi() const; - /// set model_nu_phi - void setModel_nu_phi(float); - - /// get model_nu_E - float model_nu_E() const; - /// set model_nu_E - void setModel_nu_E(float); - - + class KLFitterResult: public SG::AuxElement { + public: + /// Default constructor + KLFitterResult(); + /// Default destructor + virtual ~KLFitterResult() {} + + /// get selectionName + std::size_t selectionCode() const; + /// set selectionName + void setSelectionCode(std::size_t); + + /// get minuitDidNotConverge + short minuitDidNotConverge() const; + /// set minuitDidNotConverge + void setMinuitDidNotConverge(short); + + /// get fitAbortedDueToNaN + short fitAbortedDueToNaN() const; + /// set fitAbortedDueToNaN + void setFitAbortedDueToNaN(short); + + /// get atLeastOneFitParameterAtItsLimit + short atLeastOneFitParameterAtItsLimit() const; + /// set atLeastOneFitParameterAtItsLimit + void setAtLeastOneFitParameterAtItsLimit(short); + + /// get invalidTransferFunctionAtConvergence + short invalidTransferFunctionAtConvergence() const; + /// set invalidTransferFunctionAtConvergence + void setInvalidTransferFunctionAtConvergence(short); + + /// get bestPermutation + unsigned int bestPermutation() const; + /// set bestPermutation + void setBestPermutation(unsigned int); + + /// get logLikelihood + float logLikelihood() const; + /// set logLikelihood + void setLogLikelihood(float); + + /// get eventProbability + float eventProbability() const; + /// set eventProbability + void setEventProbability(float); + + /// get parameters + const std::vector<double>& parameters() const; + /// set parameters + void setParameters(const std::vector<double>&); + + /// get parameterErrors + const std::vector<double>& parameterErrors() const; + /// set parameterErrors + void setParameterErrors(const std::vector<double>&); + + + /// get model_bhad_pt + float model_bhad_pt() const; + /// set model_bhad_pt + void setModel_bhad_pt(float); + + /// get model_bhad_eta + float model_bhad_eta() const; + /// set model_bhad_eta + void setModel_bhad_eta(float); + + /// get model_bhad_phi + float model_bhad_phi() const; + /// set model_bhad_phi + void setModel_bhad_phi(float); + + /// get model_bhad_E + float model_bhad_E() const; + /// set model_bhad_E + void setModel_bhad_E(float); + + /// get model_bhad_jetIndex + unsigned int model_bhad_jetIndex() const; + /// set model_bhad_jetIndex + void setModel_bhad_jetIndex(unsigned int); + + + /// get model_blep_pt + float model_blep_pt() const; + /// set model_blep_pt + void setModel_blep_pt(float); + + /// get model_blep_eta + float model_blep_eta() const; + /// set model_blep_eta + void setModel_blep_eta(float); + + /// get model_blep_phi + float model_blep_phi() const; + /// set model_blep_phi + void setModel_blep_phi(float); + + /// get model_blep_E + float model_blep_E() const; + /// set model_blep_E + void setModel_blep_E(float); + + /// get model_blep_jetIndex + unsigned int model_blep_jetIndex() const; + /// set model_blep_jetIndex + void setModel_blep_jetIndex(unsigned int); + + + /// get model_lq1_pt + float model_lq1_pt() const; + /// set model_lq1_pt + void setModel_lq1_pt(float); + + /// get model_lq1_eta + float model_lq1_eta() const; + /// set model_lq1_eta + void setModel_lq1_eta(float); + + /// get model_lq1_phi + float model_lq1_phi() const; + /// set model_lq1_phi + void setModel_lq1_phi(float); + + /// get model_lq1_E + float model_lq1_E() const; + /// set model_lq1_E + void setModel_lq1_E(float); + + /// get model_lq1_jetIndex + unsigned int model_lq1_jetIndex() const; + /// set model_lq1_jetIndex + void setModel_lq1_jetIndex(unsigned int); + + + /// get model_lq2_pt + float model_lq2_pt() const; + /// set model_lq2_pt + void setModel_lq2_pt(float); + + /// get model_lq2_eta + float model_lq2_eta() const; + /// set model_lq2_eta + void setModel_lq2_eta(float); + + /// get model_lq2_phi + float model_lq2_phi() const; + /// set model_lq2_phi + void setModel_lq2_phi(float); + + /// get model_lq2_E + float model_lq2_E() const; + /// set model_lq2_E + void setModel_lq2_E(float); + + /// get model_lq2_jetIndex + unsigned int model_lq2_jetIndex() const; + /// set model_lq2_jetIndex + void setModel_lq2_jetIndex(unsigned int); + + /// get model_Higgs_b1_pt + float model_Higgs_b1_pt() const; + /// set model_Higgs_b1_pt + void setModel_Higgs_b1_pt(float); + + /// get model_Higgs_b1_eta + float model_Higgs_b1_eta() const; + /// set model_Higgs_b1_eta + void setModel_Higgs_b1_eta(float); + + /// get model_Higgs_b1_phi + float model_Higgs_b1_phi() const; + /// set model_Higgs_b1_phi + void setModel_Higgs_b1_phi(float); + + /// get model_Higgs_b1_E + float model_Higgs_b1_E() const; + /// set model_Higgs_b1_E + void setModel_Higgs_b1_E(float); + + /// get model_Higgs_b1_jetIndex + unsigned int model_Higgs_b1_jetIndex() const; + /// set model_Higgs_b1_jetIndex + void setModel_Higgs_b1_jetIndex(unsigned int); + + + /// get model_Higgs_b2_pt + float model_Higgs_b2_pt() const; + /// set model_Higgs_b2_pt + void setModel_Higgs_b2_pt(float); + + /// get model_Higgs_b2_eta + float model_Higgs_b2_eta() const; + /// set model_Higgs_b2_eta + void setModel_Higgs_b2_eta(float); + + /// get model_Higgs_b2_phi + float model_Higgs_b2_phi() const; + /// set model_Higgs_b2_phi + void setModel_Higgs_b2_phi(float); + + /// get model_Higgs_b2_E + float model_Higgs_b2_E() const; + /// set model_Higgs_b2_E + void setModel_Higgs_b2_E(float); + + /// get model_Higgs_b2_jetIndex + unsigned int model_Higgs_b2_jetIndex() const; + /// set model_Higgs_b2_jetIndex + void setModel_Higgs_b2_jetIndex(unsigned int); + + /// get model_lep_pt + float model_lep_pt() const; + /// set model_lep_pt + void setModel_lep_pt(float); + + /// get model_lep_eta + float model_lep_eta() const; + /// set model_lep_eta + void setModel_lep_eta(float); + + /// get model_lep_phi + float model_lep_phi() const; + /// set model_lep_phi + void setModel_lep_phi(float); + + /// get model_lep_E + float model_lep_E() const; + /// set model_lep_E + void setModel_lep_E(float); + + /// get model_lep_index + unsigned int model_lep_index() const; + /// set model_lep_index + void setModel_lep_index(unsigned int); + + /// get model_lep_pt + float model_lepZ1_pt() const; + /// set model_lepZ1_pt + void setModel_lepZ1_pt(float); + + /// get model_lepZ1_eta + float model_lepZ1_eta() const; + /// set model_lepZ1_eta + void setModel_lepZ1_eta(float); + + /// get model_lepZ1_phi + float model_lepZ1_phi() const; + /// set model_lepZ1_phi + void setModel_lepZ1_phi(float); + + /// get model_lepZ1_E + float model_lepZ1_E() const; + /// set model_lepZ1_E + void setModel_lepZ1_E(float); + + /// get model_lepZ1_index + unsigned int model_lepZ1_index() const; + /// set model_lepZ1_index + void setModel_lepZ1_index(unsigned int); + + /// get model_lepZ2_pt + float model_lepZ2_pt() const; + /// set model_lepZ2_pt + void setModel_lepZ2_pt(float); + + /// get model_lepZ2_eta + float model_lepZ2_eta() const; + /// set model_lepZ2_eta + void setModel_lepZ2_eta(float); + + /// get model_lepZ2_phi + float model_lepZ2_phi() const; + /// set model_lepZ2_phi + void setModel_lepZ2_phi(float); + + /// get model_lepZ2_E + float model_lepZ2_E() const; + /// set model_lepZ2_E + void setModel_lepZ2_E(float); + + /// get model_lepZ2_index + unsigned int model_lepZ2_index() const; + /// set model_lepZ2_index + void setModel_lepZ2_index(unsigned int); + + /// get model_nu_pt + float model_nu_pt() const; + /// set model_nu_pt + void setModel_nu_pt(float); + + /// get model_nu_eta + float model_nu_eta() const; + /// set model_nu_eta + void setModel_nu_eta(float); + + /// get model_nu_phi + float model_nu_phi() const; + /// set model_nu_phi + void setModel_nu_phi(float); + + /// get model_nu_E + float model_nu_E() const; + /// set model_nu_E + void setModel_nu_E(float); + + /// get model_b_from_top1_pt + float model_b_from_top1_pt() const; + /// set model_b_from_top1_pt + void setModel_b_from_top1_pt(float); + + /// get model_b_from_top1_eta + float model_b_from_top1_eta() const; + /// set model_b_from_top1_eta + void setModel_b_from_top1_eta(float); + + /// get model_b_from_top1_phi + float model_b_from_top1_phi() const; + /// set model_b_from_top1_phi + void setModel_b_from_top1_phi(float); + + /// get model_b_from_top1_E + float model_b_from_top1_E() const; + /// set model_b_from_top1_E + void setModel_b_from_top1_E(float); + + /// get model_b_from_top1_jetIndex + unsigned int model_b_from_top1_jetIndex() const; + /// set model_b_from_top1_jetIndex + void setModel_b_from_top1_jetIndex(unsigned int); + + /// get model_b_from_top2_pt + float model_b_from_top2_pt() const; + /// set model_b_from_top2_pt + void setModel_b_from_top2_pt(float); + + /// get model_b_from_top2_eta + float model_b_from_top2_eta() const; + /// set model_b_from_top2_eta + void setModel_b_from_top2_eta(float); + + /// get model_b_from_top2_phi + float model_b_from_top2_phi() const; + /// set model_b_from_top2_phi + void setModel_b_from_top2_phi(float); + + /// get model_b_from_top2_E + float model_b_from_top2_E() const; + /// set model_b_from_top2_E + void setModel_b_from_top2_E(float); + + /// get model_b_from_top2_jetIndex + unsigned int model_b_from_top2_jetIndex() const; + /// set model_b_from_top2_jetIndex + void setModel_b_from_top2_jetIndex(unsigned int); + + /// get model_lj1_from_top1_pt + float model_lj1_from_top1_pt() const; + /// set model_lj1_from_top1_pt + void setModel_lj1_from_top1_pt(float); + + /// get model_lj1_from_top1_eta + float model_lj1_from_top1_eta() const; + /// set model_lj1_from_top1_eta + void setModel_lj1_from_top1_eta(float); + + /// get model_lj1_from_top1_phi + float model_lj1_from_top1_phi() const; + /// set model_lj1_from_top1_phi + void setModel_lj1_from_top1_phi(float); + + /// get model_lj1_from_top1_E + float model_lj1_from_top1_E() const; + /// set model_lj1_from_top1_E + void setModel_lj1_from_top1_E(float); + + /// get model_lj1_from_top1_jetIndex + unsigned int model_lj1_from_top1_jetIndex() const; + /// set model_lj1_from_top1_jetIndex + void setModel_lj1_from_top1_jetIndex(unsigned int); + + /// get model_lj2_from_top1_pt + float model_lj2_from_top1_pt() const; + /// set model_lj2_from_top1_pt + void setModel_lj2_from_top1_pt(float); + + /// get model_lj2_from_top1_eta + float model_lj2_from_top1_eta() const; + /// set model_lj2_from_top1_eta + void setModel_lj2_from_top1_eta(float); + + /// get model_lj2_from_top1_phi + float model_lj2_from_top1_phi() const; + /// set model_lj2_from_top1_phi + void setModel_lj2_from_top1_phi(float); + + /// get model_lj2_from_top1_E + float model_lj2_from_top1_E() const; + /// set model_lj2_from_top1_E + void setModel_lj2_from_top1_E(float); + + /// get model_lj2_from_top1_jetIndex + unsigned int model_lj2_from_top1_jetIndex() const; + /// set model_lj2_from_top1_jetIndex + void setModel_lj2_from_top1_jetIndex(unsigned int); + + /// get model_lj1_from_top2_pt + float model_lj1_from_top2_pt() const; + /// set model_lj1_from_top2_pt + void setModel_lj1_from_top2_pt(float); + + /// get model_lj1_from_top2_eta + float model_lj1_from_top2_eta() const; + /// set model_lj1_from_top2_eta + void setModel_lj1_from_top2_eta(float); + + /// get model_lj1_from_top2_phi + float model_lj1_from_top2_phi() const; + /// set model_lj1_from_top2_phi + void setModel_lj1_from_top2_phi(float); + + /// get model_lj1_from_top2_E + float model_lj1_from_top2_E() const; + /// set model_lj1_from_top2_E + void setModel_lj1_from_top2_E(float); + + /// get model_lj1_from_top2_jetIndex + unsigned int model_lj1_from_top2_jetIndex() const; + /// set model_lj1_from_top2_jetIndex + void setModel_lj1_from_top2_jetIndex(unsigned int); + + /// get model_lj2_from_top2_pt + float model_lj2_from_top2_pt() const; + /// set model_lj2_from_top2_pt + void setModel_lj2_from_top2_pt(float); + + /// get model_lj2_from_top2_eta + float model_lj2_from_top2_eta() const; + /// set model_lj2_from_top2_eta + void setModel_lj2_from_top2_eta(float); + + /// get model_lj2_from_top2_phi + float model_lj2_from_top2_phi() const; + /// set model_lj2_from_top2_phi + void setModel_lj2_from_top2_phi(float); + + /// get model_lj2_from_top2_E + float model_lj2_from_top2_E() const; + /// set model_lj2_from_top2_E + void setModel_lj2_from_top2_E(float); + + /// get model_lj2_from_top2_jetIndex + unsigned int model_lj2_from_top2_jetIndex() const; + /// set model_lj2_from_top2_jetIndex + void setModel_lj2_from_top2_jetIndex(unsigned int); }; - + typedef DataVector< xAOD::KLFitterResult > KLFitterResultContainer; } // Dictonaries -CLASS_DEF( xAOD::KLFitterResult , 103465656 , 1 ) -CLASS_DEF( xAOD::KLFitterResultContainer , 1116647492 , 1 ) -CLASS_DEF( xAOD::KLFitterResultAuxContainer , 1292529835 , 1 ) +CLASS_DEF(xAOD::KLFitterResult, 103465656, 1) +CLASS_DEF(xAOD::KLFitterResultContainer, 1116647492, 1) +CLASS_DEF(xAOD::KLFitterResultAuxContainer, 1292529835, 1) #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/PseudoTopResult.h b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/PseudoTopResult.h index a30b730c83b0..79fa86f0c319 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/PseudoTopResult.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/PseudoTopResult.h @@ -1,13 +1,13 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOP_TOPEVENT_PSEUDOTOPRESULT_H #define ANALYSISTOP_TOPEVENT_PSEUDOTOPRESULT_H /** - * @author Andrea Knue <aknue@cern.ch> - **/ + * @author Andrea Knue <aknue@cern.ch> + **/ // EDM include(s): #include "AthContainers/DataVector.h" @@ -16,32 +16,30 @@ #include "xAODCore/CLASS_DEF.h" #include <vector> -namespace xAOD{ - - /// Aux Container - class PseudoTopResultAuxContainer : public AuxContainerBase { - public: - /// Default constructor - PseudoTopResultAuxContainer(); +namespace xAOD { + /// Aux Container + class PseudoTopResultAuxContainer: public AuxContainerBase { + public: + /// Default constructor + PseudoTopResultAuxContainer(); }; // end Aux container - + /// Interface class - class PseudoTopResult : public SG::AuxElement { - public: - /// Default constructor - PseudoTopResult(); - /// Default desturctor - virtual ~PseudoTopResult(){} - - void IniVar(bool); - - }; - typedef DataVector < xAOD::PseudoTopResult > PseudoTopResultContainer; + class PseudoTopResult: public SG::AuxElement { + public: + /// Default constructor + PseudoTopResult(); + /// Default desturctor + virtual ~PseudoTopResult() {} + + void IniVar(bool); + }; + typedef DataVector < xAOD::PseudoTopResult > PseudoTopResultContainer; } // Dictonaries -CLASS_DEF( xAOD::PseudoTopResult , 135846343 , 1 ) -CLASS_DEF( xAOD::PseudoTopResultContainer , 1219079565 , 1 ) -CLASS_DEF( xAOD::PseudoTopResultAuxContainer , 1244378748 , 1 ) +CLASS_DEF(xAOD::PseudoTopResult, 135846343, 1) +CLASS_DEF(xAOD::PseudoTopResultContainer, 1219079565, 1) +CLASS_DEF(xAOD::PseudoTopResultAuxContainer, 1244378748, 1) #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/RCJetMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/RCJetMC15.h new file mode 100644 index 000000000000..9b8ad48823aa --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/RCJetMC15.h @@ -0,0 +1,161 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef RCJETMC15_H_ +#define RCJETMC15_H_ + +#include "TopEvent/Event.h" +#include "TopEvent/EventTools.h" +#include "TopEvent/TopEventMaker.h" +#include "TopEvent/SystematicEvent.h" +#include "TopConfiguration/ConfigurationSettings.h" + +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" +#include "xAODRootAccess/TEvent.h" +#include "xAODRootAccess/TStore.h" +#include "xAODRootAccess/TActiveStore.h" +#include "xAODCore/ShallowCopy.h" +#include "xAODJet/JetContainer.h" +#include "xAODJet/JetAuxContainer.h" + +#include "JetReclustering/JetReclusteringTool.h" +#include <unordered_map> +#include <unordered_set> +#include <memory> +#include <set> +#include <list> +#include <vector> + +// Forward declaration(s): +namespace xAOD { + class SystematicEvent; +} + +namespace top { + class TopConfig; + class Event; +} + +namespace fastjet { + class JetDefinition; + namespace contrib { + class Nsubjettiness; + class EnergyCorrelator; + } +} + +namespace JetSubStructureUtils { + class KtSplittingScale; + class Qw; + class EnergyCorrelatorGeneralized; +} + +class RCJetMC15 final: public asg::AsgTool { +public: + //Default - so root can load based on a name + explicit RCJetMC15(const std::string& name); + + //Default - so we can clean up + ~RCJetMC15(); + + // Delete Standard constructors + RCJetMC15(const RCJetMC15& rhs) = delete; + RCJetMC15(RCJetMC15&& rhs) = delete; + RCJetMC15& operator = (const RCJetMC15& rhs) = delete; + + //Run once at the start of the job + StatusCode initialize(); + + //Run for every event (in every systematic) that needs saving + StatusCode execute(const top::Event& event); + + //Clean-up remaining things + StatusCode finalize(); + + //Check if systematic needs a unique container + bool isUniqueSyst(std::string syst_name); + + //Access all of the container names from the Event Saver + std::string inputContainerName(std::size_t hash_value, bool isLooseEvent); + std::string rcjetContainerName(std::size_t hash_value, bool isLooseEvent); + + bool passSelection(const xAOD::Jet& jet) const; + + void getEMTopoClusters(std::vector<fastjet::PseudoJet>& clusters, const xAOD::Jet* rcjet); + void getLCTopoClusters(std::vector<fastjet::PseudoJet>& clusters, const xAOD::Jet* rcjet); + + void getPflowConstituent(std::vector<fastjet::PseudoJet>& clusters, const xAOD::Jet* rcjet, const top::Event& event); +private: + std::string m_name; + + std::shared_ptr<top::TopConfig> m_config; + bool m_VarRCjets; + std::string m_VarRCjets_rho; + std::string m_VarRCjets_mass_scale; + float m_ptcut; // in GeV + float m_etamax; + float m_inputJetPtMin; + float m_inputJetEtaMax; + float m_trim; + float m_radius; + float m_minradius; + float m_massscale; + bool m_useJSS; + bool m_useAdditionalJSS; + + std::string m_egamma; + std::string m_jetsyst; + std::string m_muonsyst; + std::string m_tracksyst; + + std::string m_InJetContainerBase; + std::string m_OutJetContainerBase; + std::string m_InputJetContainer; + std::string m_OutputJetContainer; + int m_loose_hashValue; + + //Substructure tool definitions + std::shared_ptr<fastjet::JetDefinition> m_jet_def_rebuild; + std::shared_ptr<fastjet::contrib::Nsubjettiness> m_nSub1_beta1; + std::shared_ptr<fastjet::contrib::Nsubjettiness> m_nSub2_beta1; + std::shared_ptr<fastjet::contrib::Nsubjettiness> m_nSub3_beta1; + std::shared_ptr<fastjet::contrib::EnergyCorrelator> m_ECF1; + std::shared_ptr<fastjet::contrib::EnergyCorrelator> m_ECF2; + std::shared_ptr<fastjet::contrib::EnergyCorrelator> m_ECF3; + std::shared_ptr<JetSubStructureUtils::KtSplittingScale> m_split12; + std::shared_ptr<JetSubStructureUtils::KtSplittingScale> m_split23; + std::shared_ptr<JetSubStructureUtils::Qw> m_qw; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF332; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF461; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF322; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF331; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF422; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF441; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF212; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF321; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF311; + + bool m_unique_syst; + + typedef std::map<std::size_t, std::string>::iterator m_iterator; + std::map<std::size_t, std::string> m_inputContainerNames; + std::map<std::size_t, std::string> m_outputContainerNames; + + std::map<std::string, float> mass_scales = { + {"m_t", 172500.}, + {"m_w", 80385.}, + {"m_z", 91188.}, + {"m_h", 125090.} + }; + + //re-clustered jets + // -> need unordered map for systematics + std::unordered_map<std::size_t, std::shared_ptr<JetReclusteringTool> > m_jetReclusteringTool; + typedef std::unordered_map<std::size_t, std::shared_ptr<JetReclusteringTool> >::iterator m_tool_iterator; + + ClassDef(RCJetMC15, 0); +}; + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/SystematicEvent.h b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/SystematicEvent.h index 63e466eb1191..62128b5cb9fc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/SystematicEvent.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/SystematicEvent.h @@ -1,26 +1,26 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: SystematicEvent.h 692539 2015-09-02 00:20:52Z morrisj $ #ifndef ANALYSISTOP_TOPEVENT_SYSTEMATICEVENT_H #define ANALYSISTOP_TOPEVENT_SYSTEMATICEVENT_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief SystematicEvent - * A simple xAOD class which we can persist into a mini-xAOD - * The xAOD EDM is way too complex, so let's simplify it - * It's not like ROOT can do schema evolution...... - * - * This class contains only vectors of unsigned int's - * It is very light weight and is used to make top::Event objects - * - * $Revision: 692539 $ - * $Date: 2015-09-02 02:20:52 +0200 (Wed, 02 Sep 2015) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief SystematicEvent + * A simple xAOD class which we can persist into a mini-xAOD + * The xAOD EDM is way too complex, so let's simplify it + * It's not like ROOT can do schema evolution...... + * + * This class contains only vectors of unsigned int's + * It is very light weight and is used to make top::Event objects + * + * $Revision: 692539 $ + * $Date: 2015-09-02 01:20:52 +0100 (Wed, 02 Sep 2015) $ + * + **/ // EDM include(s): #include "AthContainers/DataVector.h" @@ -30,92 +30,109 @@ #include <vector> #include <stdint.h> -namespace xAOD{ - - /// Aux Container - class SystematicEventAuxContainer : public AuxContainerBase { - public: - /// Default constructor - SystematicEventAuxContainer(); - private: - - std::vector<std::size_t> hashValue; - std::vector<unsigned int> ttreeIndex; - std::vector<char> isLooseEvent; - - std::vector<std::vector<unsigned int>> goodPhotons; - std::vector<std::vector<unsigned int>> goodElectrons; - std::vector<std::vector<unsigned int>> goodMuons; - std::vector<std::vector<unsigned int>> goodTaus; - std::vector<std::vector<unsigned int>> goodJets; - std::vector<std::vector<unsigned int>> goodLargeRJets; - std::vector<std::vector<unsigned int>> goodTrackJets; +namespace xAOD { + /// Aux Container + class SystematicEventAuxContainer: public AuxContainerBase { + public: + /// Default constructor + SystematicEventAuxContainer(); + private: + std::vector<std::size_t> hashValue; + std::vector<unsigned int> ttreeIndex; + std::vector<char> isLooseEvent; + + std::vector<std::vector<unsigned int> > goodPhotons; + std::vector<std::vector<unsigned int> > goodElectrons; + std::vector<std::vector<unsigned int> > goodFwdElectrons; + std::vector<std::vector<unsigned int> > goodMuons; + std::vector<std::vector<unsigned int> > goodSoftMuons; + std::vector<std::vector<unsigned int> > goodTaus; + std::vector<std::vector<unsigned int> > goodJets; + std::vector<std::vector<unsigned int> > goodLargeRJets; + std::vector<std::vector<unsigned int> > goodTrackJets; + std::vector<std::vector<unsigned int> > goodTracks; }; - + /// Interface class - class SystematicEvent : public SG::AuxElement { - public: - /// Default constructor - SystematicEvent(); - /// Default destructor - virtual ~SystematicEvent(){} - - /// get hash value - std::size_t hashValue() const; - /// set hash value - void setHashValue(std::size_t); - - /// get ttreeIndex - unsigned int ttreeIndex() const; - /// set ttreeIndex - void setTtreeIndex(unsigned int); - - /// get isLooseEvent - char isLooseEvent() const; - /// set isLooseEvent - void setIsLooseEvent(char); - - /// get Photons - const std::vector<unsigned int>& goodPhotons() const; - /// set Photons - void setGoodPhotons(const std::vector<unsigned int>&); - - /// get Electrons - const std::vector<unsigned int>& goodElectrons() const; - /// set Electrons - void setGoodElectrons(const std::vector<unsigned int>&); - - /// get Muons - const std::vector<unsigned int>& goodMuons() const; - /// set Muons - void setGoodMuons(const std::vector<unsigned int>&); - - /// get Taus - const std::vector<unsigned int>& goodTaus() const; - /// set Taus - void setGoodTaus(const std::vector<unsigned int>&); - - /// get Jets - const std::vector<unsigned int>& goodJets() const; - /// set Jets - void setGoodJets(const std::vector<unsigned int>&); - - /// get LargeRJets - const std::vector<unsigned int>& goodLargeRJets() const; - /// set LargeRJets - void setGoodLargeRJets(const std::vector<unsigned int>&); - - /// get TrackJets - const std::vector<unsigned int>& goodTrackJets() const; - /// set TrackJets - void setGoodTrackJets(const std::vector<unsigned int>&); + class SystematicEvent: public SG::AuxElement { + public: + /// Default constructor + SystematicEvent(); + /// Default destructor + virtual ~SystematicEvent() {} + + /// get hash value + std::size_t hashValue() const; + /// set hash value + void setHashValue(std::size_t); + + /// get ttreeIndex + unsigned int ttreeIndex() const; + /// set ttreeIndex + void setTtreeIndex(unsigned int); + + /// get isLooseEvent + char isLooseEvent() const; + /// set isLooseEvent + void setIsLooseEvent(char); + + /// get Photons + const std::vector<unsigned int>& goodPhotons() const; + /// set Photons + void setGoodPhotons(const std::vector<unsigned int>&); + + /// get Electrons + const std::vector<unsigned int>& goodElectrons() const; + /// set Electrons + void setGoodElectrons(const std::vector<unsigned int>&); + + /// get FWD Electrons + const std::vector<unsigned int>& goodFwdElectrons() const; + /// set FWD Electrons + void setGoodFwdElectrons(const std::vector<unsigned int>&); + + /// get Muons + const std::vector<unsigned int>& goodMuons() const; + /// set Muons + void setGoodMuons(const std::vector<unsigned int>&); + + /// get Soft Muons + const std::vector<unsigned int>& goodSoftMuons() const; + /// set Soft Muons + void setGoodSoftMuons(const std::vector<unsigned int>&); + + /// get Taus + const std::vector<unsigned int>& goodTaus() const; + /// set Taus + void setGoodTaus(const std::vector<unsigned int>&); + + /// get Jets + const std::vector<unsigned int>& goodJets() const; + /// set Jets + void setGoodJets(const std::vector<unsigned int>&); + + /// get LargeRJets + const std::vector<unsigned int>& goodLargeRJets() const; + /// set LargeRJets + void setGoodLargeRJets(const std::vector<unsigned int>&); + + /// get TrackJets + const std::vector<unsigned int>& goodTrackJets() const; + /// set TrackJets + void setGoodTrackJets(const std::vector<unsigned int>&); + + /// get Tracks + const std::vector<unsigned int>& goodTracks() const; + /// set Tracks + void setGoodTracks(const std::vector<unsigned int>&); + }; - + typedef DataVector< xAOD::SystematicEvent > SystematicEventContainer; } // Dictonaries -CLASS_DEF( xAOD::SystematicEvent , 173054021 , 1 ) -CLASS_DEF( xAOD::SystematicEventContainer , 1133646307 , 1 ) -CLASS_DEF( xAOD::SystematicEventAuxContainer , 1283481454 , 1 ) +CLASS_DEF(xAOD::SystematicEvent, 173054021, 1) +CLASS_DEF(xAOD::SystematicEventContainer, 1133646307, 1) +CLASS_DEF(xAOD::SystematicEventAuxContainer, 1283481454, 1) #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/TopEventMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/TopEventMaker.h index 1f56a1dc51d1..25c46a20029c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/TopEventMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/TopEvent/TopEventMaker.h @@ -1,22 +1,22 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: TopEventMaker.h 661108 2015-04-17 00:01:16Z morrisj $ #ifndef ANALYSISTOP_TOPEVENT_TOPEVENTMAKER_H #define ANALYSISTOP_TOPEVENT_TOPEVENTMAKER_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief TopEventMaker - * produce top::Event objects from xAOD::SystematicEvent objects - * - * - * $Revision: 661108 $ - * $Date: 2015-04-17 02:01:16 +0200 (Fri, 17 Apr 2015) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief TopEventMaker + * produce top::Event objects from xAOD::SystematicEvent objects + * + * + * $Revision: 661108 $ + * $Date: 2015-04-17 01:01:16 +0100 (Fri, 17 Apr 2015) $ + * + **/ // system include(s): #include <memory> @@ -27,45 +27,59 @@ #include "TopEvent/Event.h" #include "TopEvent/SystematicEvent.h" +#include "TopEvent/RCJetMC15.h" -namespace top { +class RCJetMC15; + +namespace top { class TopConfig; - class TopEventMaker final : public asg::AsgTool { - public: - explicit TopEventMaker( const std::string& name ); - virtual ~TopEventMaker(){} - - // Delete Standard constructors - TopEventMaker(const TopEventMaker& rhs) = delete; - TopEventMaker(TopEventMaker&& rhs) = delete; - TopEventMaker& operator=(const TopEventMaker& rhs) = delete; - /** - * @brief Make a top::Event from a xAOD::SystematicEvent - * - * A SingleSystEvent contains only access to calibrated/systematic - * StoreGate keys and vectors telling it which objects in a collection - * are good - * - * You want to do physics on a top::Event - * - * @param systEvent Essentially this make an analysis friendly version of - * the information in systEvent - * - * @return A top::Event that you can do analysis on containing the good - * objects, which you can then perform selection based on event-level info - * with. Such as object multiplicity. Fun times are ahead. - */ - top::Event makeTopEvent(const xAOD::SystematicEvent& currentSystematic); - - /// As top-xaod isn't an asg::AsgTool, it doesn't have access to all the information - /// Very annoying - const xAOD::SystematicEventContainer* systematicEvents(const std::string& sgKey) const; + class TopEventMaker final: public asg::AsgTool { + public: + explicit TopEventMaker(const std::string& name); + virtual ~TopEventMaker() {} + StatusCode initialize(); + + // Delete Standard constructors + TopEventMaker(const TopEventMaker& rhs) = delete; + TopEventMaker(TopEventMaker&& rhs) = delete; + TopEventMaker& operator = (const TopEventMaker& rhs) = delete; + + /** + * @brief Make a top::Event from a xAOD::SystematicEvent + * + * A SingleSystEvent contains only access to calibrated/systematic + * StoreGate keys and vectors telling it which objects in a collection + * are good + * + * You want to do physics on a top::Event + * + * @param systEvent Essentially this make an analysis friendly version of + * the information in systEvent + * + * @return A top::Event that you can do analysis on containing the good + * objects, which you can then perform selection based on event-level info + * with. Such as object multiplicity. Fun times are ahead. + */ + top::Event makeTopEvent(const xAOD::SystematicEvent* currentSystematic); + + /// As top-xaod isn't an asg::AsgTool, it doesn't have access to all the information + /// Very annoying + const xAOD::SystematicEventContainer* systematicEvents(const std::string& sgKey) const; + private: + + void decorateTopEvent(top::Event &event); + void decorateTopEventSoftMuons(top::Event &event); + + std::shared_ptr<top::TopConfig> m_config; + std::unique_ptr<RCJetMC15> m_rc; + std::map<std::string, std::unique_ptr<RCJetMC15> > m_VarRC; + std::vector<std::string> m_VarRCJetRho; + std::vector<std::string> m_VarRCJetMassScale; - private: - std::shared_ptr<top::TopConfig> m_config; + static bool s_hasTruthEvent; // one-time check at first event we loop over }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/CMakeLists.txt index c3017dfafd18..aba16f9cc601 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/CMakeLists.txt @@ -1,6 +1,7 @@ +# Auto-generated on: 2017-03-08 14:47:36.489231 # Declare the name of this package: -atlas_subdir( TopEventReconstructionTools ) +atlas_subdir( TopEventReconstructionTools None ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -20,9 +21,8 @@ find_package( KLFitter ) # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopEventReconstructionTools _cintDictSource - ROOT_HEADERS TopEventReconstructionTools/TopEventReconstructionToolsLoader.h - Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) # Build a library that other components can link against: atlas_add_library( TopEventReconstructionTools Root/*.cxx Root/*.h Root/*.icc @@ -41,18 +41,3 @@ atlas_add_library( TopEventReconstructionTools Root/*.cxx Root/*.h Root/*.icc # Install data files from the package: atlas_install_data( share/* ) - -# Build the executables of the package: -atlas_add_executable( topreco_test_mt2 - util/topreco_test_mt2.cxx - LINK_LIBRARIES xAODCore - AthContainers - AsgTools - TopEvent - TopEventSelectionTools - TopAnalysis - ${KLFITTER_LIBRARIES} - ${ROOT_LIBRARIES} - TopEventReconstructionTools - INCLUDE_DIRS ${KLFITTER_INCLUDE_DIRS} ) - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/Chi2LJets.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/Chi2LJets.cxx index c19f4c80636a..803f7518b8e0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/Chi2LJets.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/Chi2LJets.cxx @@ -1,37 +1,34 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/Chi2LJets.h" #include "TMinuit.h" namespace top { + const double Chi2LJets::input_topmass = 172500; + const double Chi2LJets::input_wmass = 80300; -const double Chi2LJets::input_topmass = 172500; -const double Chi2LJets::input_wmass = 80300; + const double Chi2LJets::input_topsigma = 13000; + const double Chi2LJets::input_wsigma = 7000; -const double Chi2LJets::input_topsigma = 13000; -const double Chi2LJets::input_wsigma = 7000; - -Chi2LJets::Chi2LJets() { + Chi2LJets::Chi2LJets() { min = new TMinuit(2); min->SetPrintLevel(-1); min->SetObjectFit(¶ms); min->SetFCN(fcn); -} + } -Chi2LJets::~Chi2LJets() { + Chi2LJets::~Chi2LJets() { delete min; -} + } -bool Chi2LJets::apply(const top::Event& event) const { + bool Chi2LJets::apply(const top::Event& event) const { //set lepton - if (event.m_electrons.size() == 1) - params.lepton = event.m_electrons.at(0)->p4(); + if (event.m_electrons.size() == 1) params.lepton = event.m_electrons.at(0)->p4(); - if (event.m_muons.size() == 1) - params.lepton = event.m_muons.at(0)->p4(); + if (event.m_muons.size() == 1) params.lepton = event.m_muons.at(0)->p4(); //and met params.neutrino_px = event.m_met->mpx(); @@ -44,52 +41,49 @@ bool Chi2LJets::apply(const top::Event& event) const { //First loop is for the leptonic b quark for (xAOD::JetContainer::const_iterator j1 = event.m_jets.begin(); j1 != event.m_jets.end(); ++j1) { - params.leptonic_b = (*j1)->p4(); - - //Second loop is for one of the jets that makes a W - for (xAOD::JetContainer::const_iterator j2 = event.m_jets.begin(); j2 != event.m_jets.end(); ++j2) { - if (j1 == j2) - continue; - - ///The other jet in the W - for (xAOD::JetContainer::const_iterator j3 = event.m_jets.begin(); j3 != event.m_jets.end(); ++j3) { - if (j1 == j3 || j2 == j3) - continue; - - params.hadronic_w_mass = ((*j2)->p4() + (*j3)->p4()).M(); - - ///The hadronic b quark - for (xAOD::JetContainer::const_iterator j4 = event.m_jets.begin(); j4 != event.m_jets.end(); ++j4) { - if (j1 == j4 || j2 == j4 || j3 == j4) - continue; - - params.hadronic_t_mass = ((*j1)->p4() + (*j2)->p4() + (*j3)->p4()).M(); - - //Set input parameters to something reasonable (a guess) - min->DefineParameter(0, "top_mass", 172500., 10000., 0, 500000); //starting guess, step, min, max - min->DefineParameter(1, "neutrino_pz", 10000, 10000, -1000000, 1000000); - - //Perform the minimisation - int status = min->Migrad(); - - double chi2 = 0; - double edm = 0; - double errdef = 0; - int nvpar = 0; - int nparx = 0; - int icstat = 0; - - min->mnstat(chi2, edm, errdef, nvpar, nparx, icstat); - - if (status == 0 && chi2 < chi2min) { - double error = 0; - chi2min = chi2; - min->GetParameter(0, topmass, error); - //wmass = params.hadronic_w_mass; - } //min chi2 - } //j4 = hadronic b - } //j3 = j3 + j2 = hadronic W - } //j2 + params.leptonic_b = (*j1)->p4(); + + //Second loop is for one of the jets that makes a W + for (xAOD::JetContainer::const_iterator j2 = event.m_jets.begin(); j2 != event.m_jets.end(); ++j2) { + if (j1 == j2) continue; + + ///The other jet in the W + for (xAOD::JetContainer::const_iterator j3 = event.m_jets.begin(); j3 != event.m_jets.end(); ++j3) { + if (j1 == j3 || j2 == j3) continue; + + params.hadronic_w_mass = ((*j2)->p4() + (*j3)->p4()).M(); + + ///The hadronic b quark + for (xAOD::JetContainer::const_iterator j4 = event.m_jets.begin(); j4 != event.m_jets.end(); ++j4) { + if (j1 == j4 || j2 == j4 || j3 == j4) continue; + + params.hadronic_t_mass = ((*j1)->p4() + (*j2)->p4() + (*j3)->p4()).M(); + + //Set input parameters to something reasonable (a guess) + min->DefineParameter(0, "top_mass", 172500., 10000., 0, 500000); //starting guess, step, min, max + min->DefineParameter(1, "neutrino_pz", 10000, 10000, -1000000, 1000000); + + //Perform the minimisation + int status = min->Migrad(); + + double chi2 = 0; + double edm = 0; + double errdef = 0; + int nvpar = 0; + int nparx = 0; + int icstat = 0; + + min->mnstat(chi2, edm, errdef, nvpar, nparx, icstat); + + if (status == 0 && chi2 < chi2min) { + double error = 0; + chi2min = chi2; + min->GetParameter(0, topmass, error); + //wmass = params.hadronic_w_mass; + } //min chi2 + } //j4 = hadronic b + } //j3 = j3 + j2 = hadronic W + } //j2 } //j1 = leptonic b @@ -98,7 +92,8 @@ bool Chi2LJets::apply(const top::Event& event) const { // // 577 MiniElectronContainer electrons = event.electrons(); // 578 if (electrons.size() == 1) - // 579 params.lepton.SetPtEtaPhiE(electrons[0]->pt(), electrons[0]->eta(), electrons[0]->phi(), electrons[0]->E()); + // 579 params.lepton.SetPtEtaPhiE(electrons[0]->pt(), electrons[0]->eta(), electrons[0]->phi(), + // electrons[0]->E()); // 580 // 581 MiniMuonContainer muons = event.muons(); // 582 if (muons.size() == 1) @@ -157,7 +152,8 @@ bool Chi2LJets::apply(const top::Event& event) const { // 635 params.hadronic_t_mass = (a + b + c).M(); // 636 // 637 //Set input parameters to something reasonable (a guess) - // 638 min->DefineParameter(0, "top_mass", 172500., 10000., 0, 500000); //starting guess, step, min, max + // 638 min->DefineParameter(0, "top_mass", 172500., 10000., 0, 500000); //starting + // guess, step, min, max // 639 min->DefineParameter(1, "neutrino_pz", 10000, 10000, -1000000, 1000000); // 640 // 641 //Perform the minimisation @@ -177,32 +173,35 @@ bool Chi2LJets::apply(const top::Event& event) const { // 655 } //j1 = leptonic b return true; -} - + } } - /** - * @brief this is where we write out chi2 - */ +/** + * @brief this is where we write out chi2 + */ void fcn(int& /*npar*/, double* /*deriv*/, double& result, double par[], int /*flag*/) { - const top::FitInfo* params = (top::FitInfo*) gMinuit->GetObjectFit(); + const top::FitInfo* params = (top::FitInfo*) gMinuit->GetObjectFit(); - double mytopmass = par[0]; - double pz = par[1]; + double mytopmass = par[0]; + double pz = par[1]; - TLorentzVector neutrino(params->neutrino_px, params->neutrino_py, pz, sqrt(params->neutrino_px * params->neutrino_px + params->neutrino_py * params->neutrino_py + pz * pz)); - double w_lep_term = ((params->lepton + neutrino).M() - top::Chi2LJets::input_wmass) / top::Chi2LJets::input_wsigma; - double t_lep_term = ((params->lepton + neutrino + params->leptonic_b).M() - mytopmass) / top::Chi2LJets::input_topsigma; + TLorentzVector neutrino(params->neutrino_px, params->neutrino_py, pz, sqrt( + params->neutrino_px* params->neutrino_px + params->neutrino_py* params->neutrino_py + + pz* pz)); + double w_lep_term = ((params->lepton + neutrino).M() - top::Chi2LJets::input_wmass) / top::Chi2LJets::input_wsigma; + double t_lep_term = ((params->lepton + neutrino + params->leptonic_b).M() - mytopmass) / + top::Chi2LJets::input_topsigma; - double w_term = (params->hadronic_w_mass - top::Chi2LJets::input_wmass) / top::Chi2LJets::input_wsigma; - double t_term = (params->hadronic_t_mass - mytopmass) / top::Chi2LJets::input_topsigma; + double w_term = (params->hadronic_w_mass - top::Chi2LJets::input_wmass) / top::Chi2LJets::input_wsigma; + double t_term = (params->hadronic_t_mass - mytopmass) / top::Chi2LJets::input_topsigma; - result = w_lep_term * w_lep_term + - t_lep_term * t_lep_term + - w_term * w_term + - t_term * t_term; + result = w_lep_term * w_lep_term + + t_lep_term * t_lep_term + + w_term * w_term + + t_term * t_term; - // cout << "SJH fcn hadw " << fit->hadronicW << " " << TopWidth::input_wmass << " " << TopWidth::input_wsigma << endl; - // cout << "SJH fcn hadt " << fit->hadronicTop << " " << mytopmass << " " << TopWidth::input_topsigma << endl; + // cout << "SJH fcn hadw " << fit->hadronicW << " " << TopWidth::input_wmass << " " << TopWidth::input_wsigma << + // endl; + // cout << "SJH fcn hadt " << fit->hadronicTop << " " << mytopmass << " " << TopWidth::input_topsigma << endl; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/KLFitterRun.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/KLFitterRun.cxx index f93519feacd8..c4a045b48052 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/KLFitterRun.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/KLFitterRun.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/KLFitterRun.h" @@ -13,27 +13,32 @@ #include <cmath> #include <fstream> -namespace top{ - - KLFitterRun::KLFitterRun(const std::string& kLeptonType,std::shared_ptr<top::TopConfig> config) : - m_name("RECO::KLFitterRun_" + kLeptonType), - m_myFitter(nullptr) - { - - m_myFitter = std::unique_ptr<top::KLFitterTool> ( new top::KLFitterTool( m_name ) ); - top::check( m_myFitter->setProperty("config", config ), "Failed to setProperty of KLFitterTool" ); - top::check( m_myFitter->setProperty("LeptonType",kLeptonType), "Failed to setProperty of KLFitterTool" ); - top::check( m_myFitter->initialize() , "Failed to initialize KLFitterTool" ); +namespace top { + KLFitterRun::KLFitterRun(const std::string& kSelectionName, const std::string& kParameters, + std::shared_ptr<top::TopConfig> config) : + m_name(""), + m_myFitter(nullptr) { + std::string kLeptonType = ""; + std::string kCustomParameters = ""; + if (kParameters.find(" ") != std::string::npos) { + kLeptonType = kParameters.substr(0, kParameters.find(" ")); + kCustomParameters = kParameters.substr(kParameters.find(" ") + 1); + } else kLeptonType = kParameters; + m_name = "RECO::KLFitterRun_" + kLeptonType; + m_myFitter = std::unique_ptr<top::KLFitterTool> (new top::KLFitterTool(m_name)); + top::check(m_myFitter->setProperty("config", config), "Failed to setProperty of KLFitterTool"); + top::check(m_myFitter->setProperty("LeptonType", kLeptonType), "Failed to setProperty of KLFitterTool"); + top::check(m_myFitter->setProperty("CustomParameters", kCustomParameters), "Failed to setProperty of KLFitterTool"); + top::check(m_myFitter->setProperty("SelectionName", kSelectionName), "Failed to setProperty of KLFitterTool"); + top::check(m_myFitter->initialize(), "Failed to initialize KLFitterTool"); } - - bool KLFitterRun::apply(const top::Event& event) const - { - top::check( m_myFitter->execute(event) , "Failed to run KLFitterTool" ); + + bool KLFitterRun::apply(const top::Event& event) const { + top::check(m_myFitter->execute(event), "Failed to run KLFitterTool"); return true; } - + std::string KLFitterRun::name() const { return m_name; - } - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/KLFitterTool.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/KLFitterTool.cxx index 9d09da9de623..a607cbb6941c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/KLFitterTool.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/KLFitterTool.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ // $Id: KLFitterTool.cxx 790035 2016-12-15 19:47:38Z aknue $ @@ -14,194 +14,336 @@ #include <algorithm> -namespace top{ - - KLFitterTool::KLFitterTool( const std::string& name) : - asg::AsgTool( name ), +namespace top { + KLFitterTool::KLFitterTool(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), - m_massTop(172.5), // This is the MC top mass in GeV - only change if you change the MC mass - m_bTagCutValue(9999.9), + m_massTop(172.5), // This is the MC top mass in GeV - only change if you change the MC mass + m_bTagCutValue(9999.9), + m_isWorkingPoint(false), m_transferFunctionsPathPrefix("SetMe"), m_transferFunctionsPath("SetMe"), + m_selectionName("SetMe"), m_leptonType("SetMe"), + m_customParameters("SetMe"), m_LHType("SetMe"), - m_myFitter(nullptr) - { - declareProperty( "config" , m_config , "Set the configuration" ); - declareProperty( "LeptonType", m_leptonType = "kUndefined" , "Define the lepton type" ); - declareProperty( "LHType", m_LHType = "kUndefined" , "Define the Likelihood type" ); + m_myFitter(nullptr) { + declareProperty("config", m_config, "Set the configuration"); + declareProperty("LeptonType", m_leptonType = "kUndefined", "Define the lepton type"); + declareProperty("CustomParameters", m_customParameters = "", "Define the custom parameters"); + declareProperty("SelectionName", m_selectionName = "kUndefined", "Define the name of the selection"); + declareProperty("LHType", m_LHType = "kUndefined", "Define the Likelihood type"); } - + /// Function initialising the tool - StatusCode KLFitterTool::initialize() - { + StatusCode KLFitterTool::initialize() { // Have you set the config?? if (m_config == nullptr) { ATH_MSG_ERROR("Please set the top::TopConfig"); return StatusCode::FAILURE; } + //Retrieving configuration from TopConfig m_config->setKLFitter(); - m_LHType = m_config -> KLFitterLH(); - + //Setting configuration, giving priority to the ones passed inside the selection + std::vector<std::string> custom_tokens; + tokenize(m_customParameters, custom_tokens, " "); + std::string temp_option = ""; + // Setting event topology + if (findOption(custom_tokens, "KLFitterLH", temp_option)) m_LHType = temp_option; + else m_LHType = m_config->KLFitterLH(); // Find KLFitter ATLAS transfer functions. As of May '18, stored in // AnalysisTop group data area on cvmfs. - m_transferFunctionsPathPrefix = PathResolverFindCalibDirectory( "dev/AnalysisTop/KLFitterTFs/" ); - m_transferFunctionsPath = m_config->KLFitterTransferFunctionsPath(); - + m_transferFunctionsPathPrefix = PathResolverFindCalibDirectory("dev/AnalysisTop/KLFitterTFs/"); + if (findOption(custom_tokens, "KLFitterTransferFunctionsPath", temp_option)) m_transferFunctionsPath = temp_option; + else m_transferFunctionsPath = m_config->KLFitterTransferFunctionsPath(); std::string transferFunctionAbsPath = m_transferFunctionsPathPrefix + m_transferFunctionsPath + "/"; - + // 1) create an instance of the fitter - m_myFitter = std::unique_ptr<KLFitter::Fitter>( new KLFitter::Fitter{} ); - + m_myFitter = std::unique_ptr<KLFitter::Fitter>(new KLFitter::Fitter {}); + // 2) create an instance of the detector, which holds the information on the resolutions (transfer functions); // it takes as an argument the folder which contains the parameter files for the transfer functions - KLFitter::DetectorBase * myDetector = new KLFitter::DetectorAtlas_8TeV( transferFunctionAbsPath ); - + m_myDetector = std::make_unique<KLFitter::DetectorAtlas_8TeV>(transferFunctionAbsPath); + // 3) tell the fitter which detector to use - if (!m_myFitter->SetDetector(myDetector)) { - ATH_MSG_ERROR( "ERROR setting detector to fitter" ); - return StatusCode::FAILURE; - } - + top::check(m_myFitter->SetDetector( + m_myDetector.get()), "KLFitterTool::initialize() ERROR setting detector to fitter"); + // 4) create an instance of the likelihood for ttbar->l+jets channel and customize it according to your needs - KLFitter::LikelihoodTopLeptonJets * myLikelihood = new KLFitter::LikelihoodTopLeptonJets{}; - + m_myLikelihood = std::make_unique<KLFitter::LikelihoodTopLeptonJets>(); + // 4) create an instance of the likelihood for ttH -> l+jets channel and customize it according to your needs - KLFitter::LikelihoodTTHLeptonJets * myLikelihood_TTH = new KLFitter::LikelihoodTTHLeptonJets{}; + m_myLikelihood_TTH = std::make_unique<KLFitter::LikelihoodTTHLeptonJets>(); + + // 4) create an instance of the likelihood for ttbar->l+jets channel using jet angles channel and customize it + // according to your needs + m_myLikelihood_JetAngles = std::make_unique<KLFitter::LikelihoodTopLeptonJets_JetAngles>(); + + // 4) create an instance of the likelihood for ttZ -> trilepton channel and customize it according to your needs + m_myLikelihood_TTZ = std::make_unique<KLFitter::LikelihoodTTZTrilepton>(); + + // 4) create an instance of the likelihood for ttbar -> allhadronic channel and customize it according to your needs + m_myLikelihood_AllHadronic = std::make_unique<KLFitter::LikelihoodTopAllHadronic>(); + + // 4) create an instance of the likelihood for ttbar -> boosted ljets and customize it according to your needs + m_myLikelihood_BoostedLJets = std::make_unique<KLFitter::BoostedLikelihoodTopLeptonJets>(); // 4.a) SetleptonType - if (m_leptonType == "kElectron") { - m_leptonTypeKLFitterEnum = KLFitter::LikelihoodTopLeptonJets::LeptonType::kElectron; - m_leptonTypeKLFitterEnum_TTH = KLFitter::LikelihoodTTHLeptonJets::LeptonType::kElectron; - } - else if (m_leptonType == "kMuon") { - m_leptonTypeKLFitterEnum = KLFitter::LikelihoodTopLeptonJets::LeptonType::kMuon; - m_leptonTypeKLFitterEnum_TTH = KLFitter::LikelihoodTTHLeptonJets::LeptonType::kMuon; - } - else { - ATH_MSG_ERROR(" Please supply a valid LeptonType : kElectron or kMuon"); - return StatusCode::FAILURE; - } - - myLikelihood -> SetLeptonType( m_leptonTypeKLFitterEnum ); - myLikelihood_TTH -> SetLeptonType( m_leptonTypeKLFitterEnum_TTH ); + if (m_LHType != "ttbar_AllHadronic") { // no lepton type for all hadronic + if (m_leptonType == "kElectron") { + m_leptonTypeKLFitterEnum = KLFitter::LikelihoodTopLeptonJets::LeptonType::kElectron; + m_leptonTypeKLFitterEnum_TTH = KLFitter::LikelihoodTTHLeptonJets::LeptonType::kElectron; + m_leptonTypeKLFitterEnum_JetAngles = KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType::kElectron; + m_leptonTypeKLFitterEnum_TTZ = KLFitter::LikelihoodTTZTrilepton::LeptonType::kElectron; + m_leptonTypeKLFitterEnum_BoostedLJets = KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType::kElectron; + } else if (m_leptonType == "kMuon") { + m_leptonTypeKLFitterEnum = KLFitter::LikelihoodTopLeptonJets::LeptonType::kMuon; + m_leptonTypeKLFitterEnum_TTH = KLFitter::LikelihoodTTHLeptonJets::LeptonType::kMuon; + m_leptonTypeKLFitterEnum_JetAngles = KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType::kMuon; + m_leptonTypeKLFitterEnum_TTZ = KLFitter::LikelihoodTTZTrilepton::LeptonType::kMuon; + m_leptonTypeKLFitterEnum_BoostedLJets = KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType::kMuon; + } else if (m_leptonType == "kTriElectron") { + if (m_LHType != "ttZTrilepton") { + ATH_MSG_ERROR(" LeptonType kTriElectron is only defined for the ttZTrilepton likelihood"); + return StatusCode::FAILURE; + } + m_leptonTypeKLFitterEnum = KLFitter::LikelihoodTopLeptonJets::LeptonType::kElectron; + m_leptonTypeKLFitterEnum_TTH = KLFitter::LikelihoodTTHLeptonJets::LeptonType::kElectron; + m_leptonTypeKLFitterEnum_JetAngles = KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType::kElectron; + m_leptonTypeKLFitterEnum_TTZ = KLFitter::LikelihoodTTZTrilepton::LeptonType::kElectron; + m_leptonTypeKLFitterEnum_BoostedLJets = KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType::kElectron; + } else if (m_leptonType == "kTriMuon") { + if (m_LHType != "ttZTrilepton") { + ATH_MSG_ERROR(" LeptonType kTriMuon is only defined for the ttZTrilepton likelihood"); + return StatusCode::FAILURE; + } + m_leptonTypeKLFitterEnum = KLFitter::LikelihoodTopLeptonJets::LeptonType::kMuon; + m_leptonTypeKLFitterEnum_TTH = KLFitter::LikelihoodTTHLeptonJets::LeptonType::kMuon; + m_leptonTypeKLFitterEnum_JetAngles = KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType::kMuon; + m_leptonTypeKLFitterEnum_TTZ = KLFitter::LikelihoodTTZTrilepton::LeptonType::kMuon; + m_leptonTypeKLFitterEnum_BoostedLJets = KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType::kMuon; + } else { + ATH_MSG_ERROR(" Please supply a valid LeptonType : kElectron or kMuon"); + return StatusCode::FAILURE; + } - // 4.b) Jet Selection Mode - if (m_config->KLFitterJetSelectionMode() == "kLeadingFour" ){ - m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingFour; - } - else if (m_config->KLFitterJetSelectionMode() == "kLeadingFive") { - m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingFive; - } - else if (m_config->KLFitterJetSelectionMode() == "kLeadingSix") { - m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingSix; - } - else if (m_config->KLFitterJetSelectionMode() == "kBtagPriorityFourJets") { - m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kBtagPriorityFourJets; - } - else if (m_config->KLFitterJetSelectionMode() == "kBtagPriorityFiveJets") { - m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kBtagPriorityFiveJets; - } - else if (m_config->KLFitterJetSelectionMode() == "kBtagPrioritySixJets") { - m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kBtagPrioritySixJets; + m_myLikelihood->SetLeptonType(m_leptonTypeKLFitterEnum); + m_myLikelihood_TTH->SetLeptonType(m_leptonTypeKLFitterEnum_TTH); + m_myLikelihood_JetAngles->SetLeptonType(m_leptonTypeKLFitterEnum_JetAngles); + m_myLikelihood_TTZ->SetLeptonType(m_leptonTypeKLFitterEnum_TTZ); + m_myLikelihood_BoostedLJets->SetLeptonType(m_leptonTypeKLFitterEnum_BoostedLJets); } + // 4.b) Jet Selection Mode + std::string JetSelectionMode = ""; + if (findOption(custom_tokens, "KLFitterJetSelectionMode", temp_option)) JetSelectionMode = temp_option; + else JetSelectionMode = m_config->KLFitterJetSelectionMode(); + + if (JetSelectionMode == "kLeadingThree") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingThree; + else if (JetSelectionMode == + "kLeadingFour") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingFour; + else if (JetSelectionMode == + "kLeadingFive") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingFive; + else if (JetSelectionMode == "kLeadingSix") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingSix; + + else if (JetSelectionMode == + "kLeadingSeven") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingSeven; + else if (JetSelectionMode == + "kLeadingEight") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kLeadingEight; + else if (JetSelectionMode == + "kBtagPriorityThreeJets") m_jetSelectionModeKLFitterEnum = + top::KLFitterJetSelection::kBtagPriorityThreeJets; + else if (JetSelectionMode == + "kBtagPriorityFourJets") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kBtagPriorityFourJets; + + else if (JetSelectionMode == + "kBtagPriorityFiveJets") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kBtagPriorityFiveJets; + + else if (JetSelectionMode == + "kBtagPrioritySixJets") m_jetSelectionModeKLFitterEnum = top::KLFitterJetSelection::kBtagPrioritySixJets; + else if (JetSelectionMode == + "kBtagPrioritySevenJets") m_jetSelectionModeKLFitterEnum = + top::KLFitterJetSelection::kBtagPrioritySevenJets; + else if (JetSelectionMode == + "kBtagPriorityEightJets") m_jetSelectionModeKLFitterEnum = + top::KLFitterJetSelection::kBtagPriorityEightJets; else { - ATH_MSG_ERROR("Please supply a valid JetSelectionMode : kLeadingFour , kLeadingFive , kLeadingSix, kBtagPriorityFourJets , kBtagPriorityFiveJets kBtagPrioritySixJets" ); - return StatusCode::FAILURE; + ATH_MSG_ERROR( + "Please supply a valid JetSelectionMode : kLeadingFour , kLeadingFive , kLeadingSix , kLeadingSeven , kLeadingEight , kBtagPriorityFourJets , kBtagPriorityFiveJets , kBtagPrioritySixJets , kBtagPrioritySevenJets , kBtagPriorityEightJets"); + return StatusCode::FAILURE; } - - if(m_jetSelectionModeKLFitterEnum != top::KLFitterJetSelection::kLeadingSix && m_jetSelectionModeKLFitterEnum != top::KLFitterJetSelection::kBtagPrioritySixJets){ - if(m_LHType == "ttH"){ - ATH_MSG_ERROR("You want to run the ttH Likelihood, you need to use either : kLeadingSix or kBtagPrioritySixJets" ); - return StatusCode::FAILURE; - + if (m_jetSelectionModeKLFitterEnum != top::KLFitterJetSelection::kLeadingSix && + m_jetSelectionModeKLFitterEnum != top::KLFitterJetSelection::kBtagPrioritySixJets && + m_jetSelectionModeKLFitterEnum != top::KLFitterJetSelection::kLeadingSeven && + m_jetSelectionModeKLFitterEnum != top::KLFitterJetSelection::kBtagPrioritySevenJets && + m_jetSelectionModeKLFitterEnum != top::KLFitterJetSelection::kLeadingEight && + m_jetSelectionModeKLFitterEnum != top::KLFitterJetSelection::kBtagPriorityEightJets) { + if (m_LHType == "ttH" || m_LHType == "ttbar_AllHadronic") { + ATH_MSG_ERROR( + "You want to run the ttH or ttbar_AllHadronic Likelihood, you need to use either : kLeadingSix , kBtagPrioritySixJets , kLeadingSeven , kBtagPrioritySevenJets , kLeadingEight , kBtagPriorityEightJets"); + return StatusCode::FAILURE; } - } + } // 4.c) SetBTagging method - if (m_config->KLFitterBTaggingMethod() == "kNotag") { - m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kNotag; - } - else if (m_config->KLFitterBTaggingMethod() == "kVetoNoFit" ){ - m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFit; - } - else if (m_config->KLFitterBTaggingMethod() == "kVetoNoFitLight" ){ - m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFitLight; - } - else if (m_config->KLFitterBTaggingMethod() == "kVetoNoFitBoth" ){ - m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFitBoth; - } - else if (m_config->KLFitterBTaggingMethod() == "kWorkingPoint" ){ + std::string BTaggingMethod = ""; + if (findOption(custom_tokens, "KLFitterBTaggingMethod", temp_option)) BTaggingMethod = temp_option; + else BTaggingMethod = m_config->KLFitterBTaggingMethod(); + + if (BTaggingMethod == "kNotag") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kNotag; + else if (BTaggingMethod == + "kVetoNoFit") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFit; + else if (BTaggingMethod == + "kVetoNoFitLight") m_bTaggingMethodKLFitterEnum = + KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFitLight; + else if (BTaggingMethod == + "kVetoNoFitBoth") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFitBoth; + else if (BTaggingMethod == + "kVetoHybridNoFit") m_bTaggingMethodKLFitterEnum = + KLFitter::LikelihoodBase::BtaggingMethod::kVetoHybridNoFit; + else if (BTaggingMethod == "kWorkingPoint") { m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kWorkingPoint; - } - else if (m_config->KLFitterBTaggingMethod() == "kVeto" ){ - m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVeto; - } - else if (m_config->KLFitterBTaggingMethod() == "kVetoLight" ){ - m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoLight; - } - else if (m_config->KLFitterBTaggingMethod() == "kVetoBoth" ){ - m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoBoth; - } + m_isWorkingPoint = true; + } else if (BTaggingMethod == + "kVeto") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVeto; + else if (BTaggingMethod == + "kVetoLight") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoLight; + else if (BTaggingMethod == + "kVetoBoth") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoBoth; else { - ATH_MSG_ERROR("Please supply a valid BTaggingMethod : kNotag,kVetoNoFit,kVetoNoFitLight,kVetoNoFitBoth,kWorkingPoint,kVeto,kVetoLight or kVetoBoth" ); + ATH_MSG_ERROR( + "Please supply a valid BTaggingMethod : kNotag,kVetoNoFit,kVetoNoFitLight,kVetoNoFitBoth,kVetoHybridNoFit,kWorkingPoint,kVeto,kVetoLight or kVetoBoth"); return StatusCode::FAILURE; } - myLikelihood -> SetBTagging( m_bTaggingMethodKLFitterEnum ); - myLikelihood_TTH -> SetBTagging( m_bTaggingMethodKLFitterEnum ); + m_myLikelihood->SetBTagging(m_bTaggingMethodKLFitterEnum); + m_myLikelihood_TTH->SetBTagging(m_bTaggingMethodKLFitterEnum); + m_myLikelihood_JetAngles->SetBTagging(m_bTaggingMethodKLFitterEnum); + m_myLikelihood_TTZ->SetBTagging(m_bTaggingMethodKLFitterEnum); + m_myLikelihood_AllHadronic->SetBTagging(m_bTaggingMethodKLFitterEnum); + m_myLikelihood_BoostedLJets->SetBTagging(m_bTaggingMethodKLFitterEnum); // 4.d) SetTopMass - myLikelihood -> PhysicsConstants()->SetMassTop( m_massTop ); - myLikelihood_TTH -> PhysicsConstants()->SetMassTop( m_massTop ); + m_myLikelihood->PhysicsConstants()->SetMassTop(m_massTop); + m_myLikelihood_TTH->PhysicsConstants()->SetMassTop(m_massTop); + m_myLikelihood_JetAngles->PhysicsConstants()->SetMassTop(m_massTop); + m_myLikelihood_TTZ->PhysicsConstants()->SetMassTop(m_massTop); + m_myLikelihood_AllHadronic->PhysicsConstants()->SetMassTop(m_massTop); + m_myLikelihood_BoostedLJets->PhysicsConstants()->SetMassTop(m_massTop); // 4.e) TopMassFixed - myLikelihood -> SetFlagTopMassFixed( m_config->KLFitterTopMassFixed() ); - myLikelihood_TTH -> SetFlagTopMassFixed( m_config->KLFitterTopMassFixed() ); + bool FixTopMass = true; + if (findOption(custom_tokens, "KLFitterTopMassFixed", temp_option)) { + if (temp_option.compare("True") == 0) FixTopMass = true; + else if (temp_option.compare("False") == 0) FixTopMass = false; + else { + ATH_MSG_ERROR("Invalid KLFitterTopMassFixed custom option! Exiting."); + return StatusCode::FAILURE; + } + } else FixTopMass = m_config->KLFitterTopMassFixed(); + + m_myLikelihood->SetFlagTopMassFixed(FixTopMass); + m_myLikelihood_TTH->SetFlagTopMassFixed(FixTopMass); + m_myLikelihood_JetAngles->SetFlagTopMassFixed(FixTopMass); + m_myLikelihood_TTZ->SetFlagTopMassFixed(FixTopMass); + m_myLikelihood_AllHadronic->SetFlagTopMassFixed(FixTopMass); + m_myLikelihood_BoostedLJets->SetFlagTopMassFixed(FixTopMass); // 5) tell the fitter which likelihood to use - if(m_LHType == "ttbar") - m_myFitter->SetLikelihood(myLikelihood); - else if (m_LHType == "ttH") - m_myFitter->SetLikelihood(myLikelihood_TTH); - else{ + if (m_LHType == "ttbar") top::check(m_myFitter->SetLikelihood( + m_myLikelihood.get()), + "KLFitterTool::initialize() ERROR setting likelihood for KLFitter"); + else if (m_LHType == "ttH") top::check(m_myFitter->SetLikelihood( + m_myLikelihood_TTH.get()), + "KLFitterTool::initialize() ERROR setting likelihood for KLFitter"); + else if (m_LHType == "ttbar_JetAngles") top::check(m_myFitter->SetLikelihood( + m_myLikelihood_JetAngles.get()), + "KLFitterTool::initialize() ERROR setting likelihood for KLFitter"); - ATH_MSG_ERROR( "KLFitter: This likelihood is not defined..." ); + else if (m_LHType == "ttZTrilepton" && (m_leptonType == "kTriElectron" || m_leptonType == "kTriMuon")) { + // For ttZ->trilepton, we can have difficult combinations of leptons in the + // final state (3x same flavour, or mixed case). The latter is trivial, for + // which we can default back to the ljets likelihood. So we distinguish here: + // - kTriMuon, kTriElectron: dedicated TTZ->trilepton likelihood, + // - kMuon, kElectron: standard ttbar->l+jets likelihood. + top::check(m_myFitter->SetLikelihood( + m_myLikelihood_TTZ.get()), "KLFitterTool::initialize() ERROR setting likelihood for KLFitter"); + } else if (m_LHType == "ttZTrilepton") { + top::check(m_myFitter->SetLikelihood( + m_myLikelihood.get()), "KLFitterTool::initialize() ERROR setting likelihood for KLFitter"); + } else if (m_LHType == "ttbar_AllHadronic") { + top::check(m_myFitter->SetLikelihood( + m_myLikelihood_AllHadronic.get()), + "KLFitterTool::initialize() ERROR setting likelihood for KLFitter"); + } else if (m_LHType == "ttbar_BoostedLJets") { + top::check(m_myFitter->SetLikelihood( + m_myLikelihood_BoostedLJets.get()), + "KLFitterTool::initialize() ERROR setting likelihood for KLFitter"); + } else { + ATH_MSG_ERROR("KLFitter: This likelihood is not defined..."); return StatusCode::FAILURE; - } - + // 6) Figure out the b tagging working point // All the blame for this horrible code rests with the b-tagging people - if (m_config->bTagWP_available().size() != 1) { - ATH_MSG_INFO(m_config->bTagWP_available().size()<<" b-tagging WP - cannot pick b-jets. Please select only 1 WP if you are using KLFitter"); + std::string btagWP = ""; + if (findOption(custom_tokens, "KLFitterBTaggingWP", temp_option)) btagWP = temp_option; + else { + if (m_config->bTagWP_available().size() != 1) { + ATH_MSG_ERROR( + m_config->bTagWP_available().size() << + " b-tagging WP - cannot pick b-jets. Please select only 1 WP or specify the desired one in your selection!"); + return StatusCode::FAILURE; + } + btagWP = m_config->bTagWP_available()[0]; + } + if (btagWP.find("Continuous") != std::string::npos) { + ATH_MSG_ERROR( + "KLFitter is not able to run with (pseudo)continuous b-tagging! Please specify a different WP either in your configuration file or in your selection!"); + return StatusCode::FAILURE; } - - const auto btagWP = m_config->bTagWP_available()[0]; - m_btagging_eff_tool = "BTaggingEfficiencyTool_"+btagWP+"_"+m_config->sgKeyJets(); - top::check( m_btagging_eff_tool.retrieve(), "Failed to retrieve b-tagging Efficiency tool" ); - + + if (m_isWorkingPoint) { + m_btagging_eff_tool = "BTaggingEfficiencyTool_" + btagWP + "_" + m_config->sgKeyJets(); + top::check(m_btagging_eff_tool.retrieve(), "KLFitterTool:: Failed to retrieve b-tagging Efficiency tool"); + } + ATH_MSG_INFO("++++++++++++++++++++++++++++++"); - ATH_MSG_INFO("Configured KLFitter with name "<<name()); - ATH_MSG_INFO(" Using " << "BTaggingEfficiencyTool_"+btagWP+"_"+m_config->sgKeyJets()); + ATH_MSG_INFO("Configured KLFitter with name " << name()); + ATH_MSG_INFO(" For selection " << m_selectionName); + ATH_MSG_INFO(" Using " << m_btagging_eff_tool); ATH_MSG_INFO(" Using transfer functions with full path " << transferFunctionAbsPath); - ATH_MSG_INFO(" Using Lepton \t\t" << m_leptonType); - ATH_MSG_INFO(" Using JetSelectionMode \t" << m_config->KLFitterJetSelectionMode()); - ATH_MSG_INFO(" Using BTaggingMethod \t" << m_config->KLFitterBTaggingMethod()); - ATH_MSG_INFO(" Using TopMassFixed \t" << m_config->KLFitterTopMassFixed()); - - if (m_config->KLFitterSaveAllPermutations()) - ATH_MSG_INFO(" Saving All permutations"); - if (!m_config->KLFitterSaveAllPermutations()) - ATH_MSG_INFO(" Saving only the permutation with the highest event probability"); - ATH_MSG_INFO("++++++++++++++++++++++++++++++"); - + ATH_MSG_INFO(" Using Lepton \t\t" << m_leptonType); + ATH_MSG_INFO(" Using JetSelectionMode \t" << JetSelectionMode); + ATH_MSG_INFO(" Using BTaggingMethod \t" << BTaggingMethod); + ATH_MSG_INFO(" Using TopMassFixed \t" << FixTopMass); + + if (m_config->KLFitterSaveAllPermutations()) ATH_MSG_INFO(" Saving All permutations"); + else ATH_MSG_INFO(" Saving only the permutation with the highest event probability"); + ATH_MSG_INFO("++++++++++++++++++++++++++++++"); + /// Return gracefully: - return StatusCode::SUCCESS; + return StatusCode::SUCCESS; } - + + /// Config helpers + bool KLFitterTool::findOption(std::vector<std::string> full_options, std::string option, std::string& op_value) { + //Find option in full_options and put in op_value, then return true. Otherwise return false + for (unsigned int t = 0; t < full_options.size(); ++t) { + if (full_options.at(t).compare("") == 0) continue; //Skip void strings + top::check((full_options.at(t).find( + ":") != std::string::npos), + "KLFitterTool::findOption Error! You specified an invalid option: " + full_options.at( + t) + ". Expected format is A:a B:b C:c..."); + std::string key = full_options.at(t).substr(0, full_options.at(t).find(":")); + std::string value = full_options.at(t).substr(full_options.at(t).find(":") + 1); + if (key.compare(option) == 0) { + op_value = value; + return true; + } + } + return false; + } + /// Function executing the tool - StatusCode KLFitterTool::execute(const top::Event& event) - { - + StatusCode KLFitterTool::execute(const top::Event& event) { // run KLFitter // create an instance of the particles class filled with the particles to be fitted; // here, you need to make sure that @@ -219,390 +361,656 @@ namespace top{ // - index of the particle in your original collection (for convenience) // - for jets: // * bool isBtagged : mandatory only if you want to use b-tagging in the fit - - KLFitter::Particles * myParticles = new KLFitter::Particles{}; - if(m_LHType == "ttbar"){ +/* + FIXME: this may be useful to cache results, that's why I am not deleting this piece of commented code + maybe we could concatenate the full KLFitter selection and then calculate an hash... + if( (event.m_info->isAvailable< int >( "KLFitterHasRun" ) ) ) + if( ( event.m_info->auxdata< int >("KLFitterHasRun") )!=0 ) return StatusCode::SUCCESS; + */ + KLFitter::Particles* myParticles = new KLFitter::Particles {}; + if (m_LHType == "ttbar") { if (m_leptonTypeKLFitterEnum == KLFitter::LikelihoodTopLeptonJets::LeptonType::kElectron) { - TLorentzVector el; - el.SetPtEtaPhiE( event.m_electrons.at(0)->pt()/1.e3 , event.m_electrons.at(0)->eta() , event.m_electrons.at(0)->phi(), event.m_electrons.at(0)->e() / 1.e3); - myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2) , KLFitter::Particles::kElectron); + TLorentzVector el; + el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at( + 0)->phi(), event.m_electrons.at(0)->e() / 1.e3); + myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron); } if (m_leptonTypeKLFitterEnum == KLFitter::LikelihoodTopLeptonJets::LeptonType::kMuon) { - TLorentzVector mu; - mu.SetPtEtaPhiE( event.m_muons.at(0)->pt()/1.e3 , event.m_muons.at(0)->eta() , event.m_muons.at(0)->phi(), event.m_muons.at(0)->e() / 1.e3); - myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon); + TLorentzVector mu; + mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at( + 0)->phi(), event.m_muons.at(0)->e() / 1.e3); + myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon); } } - if(m_LHType == "ttH"){ - + if (m_LHType == "ttH") { if (m_leptonTypeKLFitterEnum_TTH == KLFitter::LikelihoodTTHLeptonJets::LeptonType::kElectron) { TLorentzVector el; - el.SetPtEtaPhiE( event.m_electrons.at(0)->pt()/1.e3 , event.m_electrons.at(0)->eta() , event.m_electrons.at(0)->phi(), event.m_electrons.at(0)->e() / 1.e3); - myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2) , KLFitter::Particles::kElectron); + el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at( + 0)->phi(), event.m_electrons.at(0)->e() / 1.e3); + myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron); } if (m_leptonTypeKLFitterEnum_TTH == KLFitter::LikelihoodTTHLeptonJets::LeptonType::kMuon) { TLorentzVector mu; - mu.SetPtEtaPhiE( event.m_muons.at(0)->pt()/1.e3 , event.m_muons.at(0)->eta() , event.m_muons.at(0)->phi(), event.m_muons.at(0)->e() / 1.e3); + mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at( + 0)->phi(), event.m_muons.at(0)->e() / 1.e3); + myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon); + } + } + if (m_LHType == "ttbar_JetAngles") { + if (m_leptonTypeKLFitterEnum_JetAngles == KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType::kElectron) { + TLorentzVector el; + el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at( + 0)->phi(), event.m_electrons.at(0)->e() / 1.e3); + myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron); + } + if (m_leptonTypeKLFitterEnum_JetAngles == KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType::kMuon) { + TLorentzVector mu; + mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at( + 0)->phi(), event.m_muons.at(0)->e() / 1.e3); myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon); } } - + + if (m_LHType == "ttZTrilepton") { + if (m_leptonTypeKLFitterEnum_TTZ == KLFitter::LikelihoodTTZTrilepton::LeptonType::kElectron) { + if (m_leptonType == "kTriElectron") { + // This is the "true" trilepton case with three leptons of the same flavour. + if (event.m_electrons.size() < 3) { + ATH_MSG_ERROR("KLFitter: kTriElectron requires three electrons..."); + return StatusCode::FAILURE; + } + TLorentzVector el; + for (unsigned int i = 0; i < 3; ++i) { + const auto& electron = event.m_electrons.at(i); + el.SetPtEtaPhiE(electron->pt() / 1.e3, electron->eta(), electron->phi(), electron->e() / 1.e3); + myParticles->AddParticle(&el, electron->caloCluster()->etaBE(2), KLFitter::Particles::kElectron, "", i); + } + } else { + // Trivial case of mixed lepton flavours. Use ttbar->l+jets likelihood and only add the single lepton. + TLorentzVector el; + el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at( + 0)->phi(), event.m_electrons.at(0)->e() / 1.e3); + myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), + KLFitter::Particles::kElectron); + } + } + + if (m_leptonTypeKLFitterEnum_TTZ == KLFitter::LikelihoodTTZTrilepton::LeptonType::kMuon) { + if (m_leptonType == "kTriMuon") { + // This is the "true" trilepton case with three leptons of the same flavour. + if (event.m_muons.size() < 3) { + ATH_MSG_ERROR("KLFitter: kTriMuon requires three muons..."); + return StatusCode::FAILURE; + } + TLorentzVector mu; + for (unsigned int i = 0; i < 3; ++i) { + const auto& muon = event.m_muons.at(i); + mu.SetPtEtaPhiE(muon->pt() / 1.e3, muon->eta(), muon->phi(), muon->e() / 1.e3); + myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon, "", i); + } + } else { + // Trivial case of mixed lepton flavours. Use ttbar->l+jets likelihood and only add the single lepton. + TLorentzVector mu; + mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at( + 0)->phi(), event.m_muons.at(0)->e() / 1.e3); + myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon); + } + } + } + if (m_LHType == "ttbar_BoostedLJets") { + if (m_leptonTypeKLFitterEnum_BoostedLJets == KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType::kElectron) { + TLorentzVector el; + el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at( + 0)->phi(), event.m_electrons.at(0)->e() / 1.e3); + myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron); + } + if (m_leptonTypeKLFitterEnum_BoostedLJets == KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType::kMuon) { + TLorentzVector mu; + mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at( + 0)->phi(), event.m_muons.at(0)->e() / 1.e3); + myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon); + } + } + // set the jets, depending on the Jet Selection Mode - setJets(event, myParticles); - + if (!setJets(event, myParticles)) { + ATH_MSG_INFO( + "KLFitterTool::execute: error at event " << event.m_info->eventNumber() << + ". It was not possible to properly fill the jets. Are you trying to use a KLeadingX Jet Selection mode with a signal region with less than X jets? Please check your configuration!"); + return StatusCode::FAILURE; + } + // add the particles to the fitter if (!m_myFitter->SetParticles(myParticles)) { - ATH_MSG_ERROR( "KLFitter: Error adding particles to fitter..." ); + ATH_MSG_ERROR("KLFitter: Error adding particles to fitter..."); return StatusCode::FAILURE; - } - + } + // add the MET x and y components as well as the SumET to the fitter const double met_ex = event.m_met->mpx() / 1.e3; const double met_ey = event.m_met->mpy() / 1.e3; const double met_sumet = event.m_met->sumet() / 1.e3; if (!m_myFitter->SetET_miss_XY_SumET(met_ex, met_ey, met_sumet)) { - ATH_MSG_ERROR( "KLFitter: Error adding MET to fitter..." ); + ATH_MSG_ERROR("KLFitter: Error adding MET to fitter..."); return StatusCode::FAILURE; - } - - // create the xAOD::KLFitterResultContainer - xAOD::KLFitterResultAuxContainer* resultAuxContainer = new xAOD::KLFitterResultAuxContainer{}; - xAOD::KLFitterResultContainer* resultContainer = new xAOD::KLFitterResultContainer{}; - resultContainer->setStore( resultAuxContainer ); - - + } + // define StoreGate names + std::string outputSGKey("SetMe"); + if (!event.m_isLoose) { + outputSGKey = m_config->sgKeyKLFitter(event.m_hashValue); + } + if (event.m_isLoose) { + outputSGKey = m_config->sgKeyKLFitterLoose(event.m_hashValue); + } + std::string outputSGKeyAux = outputSGKey + "Aux."; + // create or retrieve (if existent) the xAOD::KLFitterResultContainer + xAOD::KLFitterResultAuxContainer* resultAuxContainer = nullptr; + xAOD::KLFitterResultContainer* resultContainer = nullptr; + if ((!m_config->KLFitterSaveAllPermutations()) || + ((m_config->KLFitterSaveAllPermutations()) && + (!evtStore()->tds()->contains<xAOD::KLFitterResultContainer>(outputSGKey)))) { + resultAuxContainer = new xAOD::KLFitterResultAuxContainer {}; + resultContainer = new xAOD::KLFitterResultContainer {}; + resultContainer->setStore(resultAuxContainer); + } else top::check(evtStore()->tds()->retrieve(resultContainer, + outputSGKey), + "KLFitterTools::execute(): can not retrieve xAOD::KLFitterResultContainer from evtStore()"); + // loop over all permutations const int nperm = m_myFitter->Permutations()->NPermutations(); - for (int iperm = 0; iperm < nperm; ++iperm) { + for (int iperm = 0; iperm < nperm; ++iperm) { // Perform the fit - m_myFitter->Fit(iperm); - - // create a result - xAOD::KLFitterResult* result = new xAOD::KLFitterResult{}; - resultContainer->push_back( result ); - + m_myFitter->Fit(iperm); + // create a result + xAOD::KLFitterResult* result = new xAOD::KLFitterResult {}; + resultContainer->push_back(result); + + //Set name hash. This is because it seems std::string is not supported by AuxContainers... + std::hash<std::string> hash_string; + result->setSelectionCode(hash_string(m_selectionName)); + unsigned int ConvergenceStatusBitWord = m_myFitter->ConvergenceStatus(); bool MinuitDidNotConverge = (ConvergenceStatusBitWord & m_myFitter->MinuitDidNotConvergeMask) != 0; bool FitAbortedDueToNaN = (ConvergenceStatusBitWord & m_myFitter->FitAbortedDueToNaNMask) != 0; - bool AtLeastOneFitParameterAtItsLimit = (ConvergenceStatusBitWord & m_myFitter->AtLeastOneFitParameterAtItsLimitMask) != 0; - bool InvalidTransferFunctionAtConvergence = (ConvergenceStatusBitWord & m_myFitter->InvalidTransferFunctionAtConvergenceMask) != 0; - - result->setMinuitDidNotConverge( ((MinuitDidNotConverge) ? 1 : 0) ); - result->setFitAbortedDueToNaN( ((FitAbortedDueToNaN) ? 1 : 0) ); - result->setAtLeastOneFitParameterAtItsLimit( ((AtLeastOneFitParameterAtItsLimit) ? 1 : 0 ) ); - result->setInvalidTransferFunctionAtConvergence( ((InvalidTransferFunctionAtConvergence) ? 1 : 0) ); - - result->setLogLikelihood( m_myFitter->Likelihood()->LogLikelihood(m_myFitter->Likelihood()->GetBestFitParameters()) ); - result->setEventProbability( std::exp(m_myFitter->Likelihood()->LogEventProbability()) ); - result->setParameters( m_myFitter->Likelihood()->GetBestFitParameters() ); - result->setParameterErrors( m_myFitter->Likelihood()->GetBestFitParameterErrors() ); - - KLFitter::Particles * myModelParticles = m_myFitter->Likelihood()->ParticlesModel(); - KLFitter::Particles ** myPermutedParticles = m_myFitter->Likelihood()->PParticlesPermuted(); - - result->setModel_bhad_pt( myModelParticles->Parton(0)->Pt() ); - result->setModel_bhad_eta( myModelParticles->Parton(0)->Eta() ); - result->setModel_bhad_phi( myModelParticles->Parton(0)->Phi() ); - result->setModel_bhad_E( myModelParticles->Parton(0)->E() ); - result->setModel_bhad_jetIndex( (*myPermutedParticles)->JetIndex(0) ); - - result->setModel_blep_pt( myModelParticles->Parton(1)->Pt() ); - result->setModel_blep_eta( myModelParticles->Parton(1)->Eta() ); - result->setModel_blep_phi( myModelParticles->Parton(1)->Phi() ); - result->setModel_blep_E( myModelParticles->Parton(1)->E() ); - result->setModel_blep_jetIndex( (*myPermutedParticles)->JetIndex(1) ); - - result->setModel_lq1_pt( myModelParticles->Parton(2)->Pt() ); - result->setModel_lq1_eta( myModelParticles->Parton(2)->Eta() ); - result->setModel_lq1_phi( myModelParticles->Parton(2)->Phi() ); - result->setModel_lq1_E( myModelParticles->Parton(2)->E() ); - result->setModel_lq1_jetIndex( (*myPermutedParticles)->JetIndex(2) ); - - result->setModel_lq2_pt( myModelParticles->Parton(3)->Pt() ); - result->setModel_lq2_eta( myModelParticles->Parton(3)->Eta() ); - result->setModel_lq2_phi( myModelParticles->Parton(3)->Phi() ); - result->setModel_lq2_E( myModelParticles->Parton(3)->E() ); - result->setModel_lq2_jetIndex( (*myPermutedParticles)->JetIndex(3) ); - - if(m_LHType == "ttH"){ - - result->setModel_Higgs_b1_pt( myModelParticles->Parton(4)->Pt() ); - result->setModel_Higgs_b1_eta( myModelParticles->Parton(4)->Eta() ); - result->setModel_Higgs_b1_phi( myModelParticles->Parton(4)->Phi() ); - result->setModel_Higgs_b1_E( myModelParticles->Parton(4)->E() ); - result->setModel_Higgs_b1_jetIndex( (*myPermutedParticles)->JetIndex(4) ); - - result->setModel_Higgs_b2_pt( myModelParticles->Parton(5)->Pt() ); - result->setModel_Higgs_b2_eta( myModelParticles->Parton(5)->Eta() ); - result->setModel_Higgs_b2_phi( myModelParticles->Parton(5)->Phi() ); - result->setModel_Higgs_b2_E( myModelParticles->Parton(5)->E() ); - result->setModel_Higgs_b2_jetIndex( (*myPermutedParticles)->JetIndex(5) ); - - } - - if (m_leptonTypeKLFitterEnum == KLFitter::LikelihoodTopLeptonJets::LeptonType::kElectron || m_leptonTypeKLFitterEnum_TTH == KLFitter::LikelihoodTTHLeptonJets::LeptonType::kElectron) { - result->setModel_lep_pt( myModelParticles->Electron(0)->Pt() ); - result->setModel_lep_eta( myModelParticles->Electron(0)->Eta() ); - result->setModel_lep_phi( myModelParticles->Electron(0)->Phi() ); - result->setModel_lep_E( myModelParticles->Electron(0)->E() ); - } - - if (m_leptonTypeKLFitterEnum == KLFitter::LikelihoodTopLeptonJets::LeptonType::kMuon || m_leptonTypeKLFitterEnum_TTH == KLFitter::LikelihoodTTHLeptonJets::LeptonType::kMuon) { - result->setModel_lep_pt( myModelParticles->Muon(0)->Pt() ); - result->setModel_lep_eta( myModelParticles->Muon(0)->Eta() ); - result->setModel_lep_phi( myModelParticles->Muon(0)->Phi() ); - result->setModel_lep_E( myModelParticles->Muon(0)->E() ); - } + bool AtLeastOneFitParameterAtItsLimit = + (ConvergenceStatusBitWord & m_myFitter->AtLeastOneFitParameterAtItsLimitMask) != 0; + bool InvalidTransferFunctionAtConvergence = + (ConvergenceStatusBitWord & m_myFitter->InvalidTransferFunctionAtConvergenceMask) != 0; + + result->setMinuitDidNotConverge(((MinuitDidNotConverge) ? 1 : 0)); + result->setFitAbortedDueToNaN(((FitAbortedDueToNaN) ? 1 : 0)); + result->setAtLeastOneFitParameterAtItsLimit(((AtLeastOneFitParameterAtItsLimit) ? 1 : 0)); + result->setInvalidTransferFunctionAtConvergence(((InvalidTransferFunctionAtConvergence) ? 1 : 0)); + + result->setLogLikelihood(m_myFitter->Likelihood()->LogLikelihood(m_myFitter->Likelihood()->GetBestFitParameters())); + result->setEventProbability(std::exp(m_myFitter->Likelihood()->LogEventProbability())); + result->setParameters(m_myFitter->Likelihood()->GetBestFitParameters()); + result->setParameterErrors(m_myFitter->Likelihood()->GetBestFitParameterErrors()); + + KLFitter::Particles* myModelParticles = m_myFitter->Likelihood()->ParticlesModel(); + KLFitter::Particles** myPermutedParticles = m_myFitter->Likelihood()->PParticlesPermuted(); + + + if (m_LHType == "ttbar" || m_LHType == "ttH" || m_LHType == "ttbar_JetAngles" || m_LHType == "ttZTrilepton" || + m_LHType == "ttbar_BoostedLJets") { + result->setModel_bhad_pt(myModelParticles->Parton(0)->Pt()); + result->setModel_bhad_eta(myModelParticles->Parton(0)->Eta()); + result->setModel_bhad_phi(myModelParticles->Parton(0)->Phi()); + result->setModel_bhad_E(myModelParticles->Parton(0)->E()); + result->setModel_bhad_jetIndex((*myPermutedParticles)->JetIndex(0)); + + result->setModel_blep_pt(myModelParticles->Parton(1)->Pt()); + result->setModel_blep_eta(myModelParticles->Parton(1)->Eta()); + result->setModel_blep_phi(myModelParticles->Parton(1)->Phi()); + result->setModel_blep_E(myModelParticles->Parton(1)->E()); + result->setModel_blep_jetIndex((*myPermutedParticles)->JetIndex(1)); + + result->setModel_lq1_pt(myModelParticles->Parton(2)->Pt()); + result->setModel_lq1_eta(myModelParticles->Parton(2)->Eta()); + result->setModel_lq1_phi(myModelParticles->Parton(2)->Phi()); + result->setModel_lq1_E(myModelParticles->Parton(2)->E()); + result->setModel_lq1_jetIndex((*myPermutedParticles)->JetIndex(2)); + + // boosted likelihood has only one light jet + if (m_LHType != "ttbar_BoostedLJets") { + result->setModel_lq2_pt(myModelParticles->Parton(3)->Pt()); + result->setModel_lq2_eta(myModelParticles->Parton(3)->Eta()); + result->setModel_lq2_phi(myModelParticles->Parton(3)->Phi()); + result->setModel_lq2_E(myModelParticles->Parton(3)->E()); + result->setModel_lq2_jetIndex((*myPermutedParticles)->JetIndex(3)); - result->setModel_nu_pt( myModelParticles->Neutrino(0)->Pt() ); - result->setModel_nu_eta( myModelParticles->Neutrino(0)->Eta() ); - result->setModel_nu_phi( myModelParticles->Neutrino(0)->Phi() ); - result->setModel_nu_E( myModelParticles->Neutrino(0)->E() ); - - + if (m_LHType == "ttH") { + result->setModel_Higgs_b1_pt(myModelParticles->Parton(4)->Pt()); + result->setModel_Higgs_b1_eta(myModelParticles->Parton(4)->Eta()); + result->setModel_Higgs_b1_phi(myModelParticles->Parton(4)->Phi()); + result->setModel_Higgs_b1_E(myModelParticles->Parton(4)->E()); + result->setModel_Higgs_b1_jetIndex((*myPermutedParticles)->JetIndex(4)); + + result->setModel_Higgs_b2_pt(myModelParticles->Parton(5)->Pt()); + result->setModel_Higgs_b2_eta(myModelParticles->Parton(5)->Eta()); + result->setModel_Higgs_b2_phi(myModelParticles->Parton(5)->Phi()); + result->setModel_Higgs_b2_E(myModelParticles->Parton(5)->E()); + result->setModel_Higgs_b2_jetIndex((*myPermutedParticles)->JetIndex(5)); + } + } + + if (m_leptonTypeKLFitterEnum == KLFitter::LikelihoodTopLeptonJets::LeptonType::kElectron || + m_leptonTypeKLFitterEnum_TTH == KLFitter::LikelihoodTTHLeptonJets::LeptonType::kElectron || + m_leptonTypeKLFitterEnum_TTZ == KLFitter::LikelihoodTTZTrilepton::LeptonType::kElectron || + m_leptonTypeKLFitterEnum_BoostedLJets == KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType::kElectron || + m_leptonTypeKLFitterEnum_JetAngles == KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType::kElectron) { + result->setModel_lep_pt(myModelParticles->Electron(0)->Pt()); + result->setModel_lep_eta(myModelParticles->Electron(0)->Eta()); + result->setModel_lep_phi(myModelParticles->Electron(0)->Phi()); + result->setModel_lep_E(myModelParticles->Electron(0)->E()); + + if (m_leptonType == "kTriElectron") { + result->setModel_lep_index((*myPermutedParticles)->ElectronIndex(0)); + + result->setModel_lepZ1_pt(myModelParticles->Electron(1)->Pt()); + result->setModel_lepZ1_eta(myModelParticles->Electron(1)->Eta()); + result->setModel_lepZ1_phi(myModelParticles->Electron(1)->Phi()); + result->setModel_lepZ1_E(myModelParticles->Electron(1)->E()); + result->setModel_lepZ1_index((*myPermutedParticles)->ElectronIndex(1)); + + result->setModel_lepZ2_pt(myModelParticles->Electron(2)->Pt()); + result->setModel_lepZ2_eta(myModelParticles->Electron(2)->Eta()); + result->setModel_lepZ2_phi(myModelParticles->Electron(2)->Phi()); + result->setModel_lepZ2_E(myModelParticles->Electron(2)->E()); + result->setModel_lepZ2_index((*myPermutedParticles)->ElectronIndex(2)); + } + } + + if (m_leptonTypeKLFitterEnum == KLFitter::LikelihoodTopLeptonJets::LeptonType::kMuon || + m_leptonTypeKLFitterEnum_TTH == KLFitter::LikelihoodTTHLeptonJets::LeptonType::kMuon || + m_leptonTypeKLFitterEnum_TTZ == KLFitter::LikelihoodTTZTrilepton::LeptonType::kMuon || + m_leptonTypeKLFitterEnum_BoostedLJets == KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType::kMuon || + m_leptonTypeKLFitterEnum_JetAngles == KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType::kMuon) { + result->setModel_lep_pt(myModelParticles->Muon(0)->Pt()); + result->setModel_lep_eta(myModelParticles->Muon(0)->Eta()); + result->setModel_lep_phi(myModelParticles->Muon(0)->Phi()); + result->setModel_lep_E(myModelParticles->Muon(0)->E()); + + if (m_leptonType == "kTriMuon") { + result->setModel_lep_index((*myPermutedParticles)->MuonIndex(0)); + + result->setModel_lepZ1_pt(myModelParticles->Muon(1)->Pt()); + result->setModel_lepZ1_eta(myModelParticles->Muon(1)->Eta()); + result->setModel_lepZ1_phi(myModelParticles->Muon(1)->Phi()); + result->setModel_lepZ1_E(myModelParticles->Muon(1)->E()); + result->setModel_lepZ1_index((*myPermutedParticles)->MuonIndex(1)); + + result->setModel_lepZ2_pt(myModelParticles->Muon(2)->Pt()); + result->setModel_lepZ2_eta(myModelParticles->Muon(2)->Eta()); + result->setModel_lepZ2_phi(myModelParticles->Muon(2)->Phi()); + result->setModel_lepZ2_E(myModelParticles->Muon(2)->E()); + result->setModel_lepZ2_index((*myPermutedParticles)->MuonIndex(2)); + } + } + + result->setModel_nu_pt(myModelParticles->Neutrino(0)->Pt()); + result->setModel_nu_eta(myModelParticles->Neutrino(0)->Eta()); + result->setModel_nu_phi(myModelParticles->Neutrino(0)->Phi()); + result->setModel_nu_E(myModelParticles->Neutrino(0)->E()); + } else if (m_LHType == "ttbar_AllHadronic") { + result->setModel_b_from_top1_pt(myModelParticles->Parton(0)->Pt()); + result->setModel_b_from_top1_eta(myModelParticles->Parton(0)->Eta()); + result->setModel_b_from_top1_phi(myModelParticles->Parton(0)->Phi()); + result->setModel_b_from_top1_E(myModelParticles->Parton(0)->E()); + result->setModel_b_from_top1_jetIndex((*myPermutedParticles)->JetIndex(0)); + + result->setModel_b_from_top2_pt(myModelParticles->Parton(1)->Pt()); + result->setModel_b_from_top2_eta(myModelParticles->Parton(1)->Eta()); + result->setModel_b_from_top2_phi(myModelParticles->Parton(1)->Phi()); + result->setModel_b_from_top2_E(myModelParticles->Parton(1)->E()); + result->setModel_b_from_top2_jetIndex((*myPermutedParticles)->JetIndex(1)); + + result->setModel_lj1_from_top1_pt(myModelParticles->Parton(2)->Pt()); + result->setModel_lj1_from_top1_eta(myModelParticles->Parton(2)->Eta()); + result->setModel_lj1_from_top1_phi(myModelParticles->Parton(2)->Phi()); + result->setModel_lj1_from_top1_E(myModelParticles->Parton(2)->E()); + result->setModel_lj1_from_top1_jetIndex((*myPermutedParticles)->JetIndex(2)); + + result->setModel_lj2_from_top1_pt(myModelParticles->Parton(3)->Pt()); + result->setModel_lj2_from_top1_eta(myModelParticles->Parton(3)->Eta()); + result->setModel_lj2_from_top1_phi(myModelParticles->Parton(3)->Phi()); + result->setModel_lj2_from_top1_E(myModelParticles->Parton(3)->E()); + result->setModel_lj2_from_top1_jetIndex((*myPermutedParticles)->JetIndex(3)); + + result->setModel_lj1_from_top2_pt(myModelParticles->Parton(4)->Pt()); + result->setModel_lj1_from_top2_eta(myModelParticles->Parton(4)->Eta()); + result->setModel_lj1_from_top2_phi(myModelParticles->Parton(4)->Phi()); + result->setModel_lj1_from_top2_E(myModelParticles->Parton(4)->E()); + result->setModel_lj1_from_top2_jetIndex((*myPermutedParticles)->JetIndex(4)); + + result->setModel_lj2_from_top2_pt(myModelParticles->Parton(5)->Pt()); + result->setModel_lj2_from_top2_eta(myModelParticles->Parton(5)->Eta()); + result->setModel_lj2_from_top2_phi(myModelParticles->Parton(5)->Phi()); + result->setModel_lj2_from_top2_E(myModelParticles->Parton(5)->E()); + result->setModel_lj2_from_top2_jetIndex((*myPermutedParticles)->JetIndex(5)); + } } // Loop over permutations - + // Normalize event probability to unity // work out best permutation - float sumEventProbability(0.),bestEventProbability(0.); - unsigned int bestPermutation(999),iPerm(0); - + float sumEventProbability(0.), bestEventProbability(0.); + unsigned int bestPermutation(999), iPerm(0); + // First loop for (auto x : *resultContainer) { float prob = x->eventProbability(); + short minuitDidNotConverge = x->minuitDidNotConverge(); + short fitAbortedDueToNaN = x->fitAbortedDueToNaN(); + short atLeastOneFitParameterAtItsLimit = x->atLeastOneFitParameterAtItsLimit(); + short invalidTransferFunctionAtConvergence = x->invalidTransferFunctionAtConvergence(); sumEventProbability += prob; - + ++iPerm; + + // check if the best value has the highest event probability AND converged + if (minuitDidNotConverge) continue; + if (fitAbortedDueToNaN) continue; + if (atLeastOneFitParameterAtItsLimit) continue; + if (invalidTransferFunctionAtConvergence) continue; + if (prob > bestEventProbability) { bestEventProbability = prob; - bestPermutation = iPerm; + // Using iPerm -1 because it has already been incremented before + bestPermutation = iPerm - 1; } - ++iPerm; } - + // Second loop iPerm = 0; for (auto x : *resultContainer) { - x->setEventProbability( x->eventProbability() / sumEventProbability ); + x->setEventProbability(x->eventProbability() / sumEventProbability); if (iPerm == bestPermutation) { x->setBestPermutation(1); - } - else{ + } else { x->setBestPermutation(0); } ++iPerm; } - - // Save to StoreGate / TStore - std::string outputSGKey("SetMe"); - if (!event.m_isLoose) { - outputSGKey = m_config->sgKeyKLFitter( event.m_hashValue ); - } - if (event.m_isLoose) { - outputSGKey = m_config->sgKeyKLFitterLoose( event.m_hashValue ); - } - - std::string outputSGKeyAux = outputSGKey + "Aux."; - + // Save all permutations or only the highest event probability? - + // Save all - if (m_config->KLFitterSaveAllPermutations()) { - xAOD::TReturnCode save = evtStore()->tds()->record( resultContainer ,outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( resultAuxContainer , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } + if (m_config->KLFitterSaveAllPermutations()) { + if (!evtStore()->tds()->contains<xAOD::KLFitterResultContainer>(outputSGKey)) { + top::check(evtStore()->tds()->record(resultContainer, + outputSGKey), + "KLFitterTools: ERROR! Was not able to write KLFitterResultContainer"); + top::check(evtStore()->tds()->record(resultAuxContainer, + outputSGKeyAux), + "KLFitterTools: ERROR! Was not able to write KLFitterResultAuxContainer"); + } } - // Save only the best - if (!m_config->KLFitterSaveAllPermutations()) { - // create the xAOD::KLFitterResultContainer - xAOD::KLFitterResultAuxContainer* bestAuxContainer = new xAOD::KLFitterResultAuxContainer{}; - xAOD::KLFitterResultContainer* bestContainer = new xAOD::KLFitterResultContainer{}; - bestContainer->setStore( bestAuxContainer ); - + else { + // create ore retrieve the xAOD::KLFitterResultContainer + xAOD::KLFitterResultAuxContainer* bestAuxContainer = nullptr; + xAOD::KLFitterResultContainer* bestContainer = nullptr; + if (!evtStore()->tds()->contains<xAOD::KLFitterResultContainer>(outputSGKey)) { + bestAuxContainer = new xAOD::KLFitterResultAuxContainer {}; + bestContainer = new xAOD::KLFitterResultContainer {}; + bestContainer->setStore(bestAuxContainer); + } else top::check(evtStore()->tds()->retrieve(bestContainer, + outputSGKey), + "KLFitterTools::execute(): can not retrieve xAOD::KLFitterResultContainer from evtStore()"); + for (auto x : *resultContainer) { if (x->bestPermutation() == 1) { - xAOD::KLFitterResult* result = new xAOD::KLFitterResult{}; - result->makePrivateStore( *x ); - bestContainer->push_back( result ); + xAOD::KLFitterResult* result = new xAOD::KLFitterResult {}; + result->makePrivateStore(*x); + bestContainer->push_back(result); } } - - xAOD::TReturnCode save = evtStore()->tds()->record( bestContainer ,outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( bestAuxContainer , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } - + if (!evtStore()->tds()->contains<xAOD::KLFitterResultContainer>(outputSGKey)) { + top::check(evtStore()->tds()->record(bestContainer, + outputSGKey), + "KLFitterTools: ERROR! Was not able to write KLFitterResultContainer with best permutation"); + top::check(evtStore()->tds()->record(bestAuxContainer, + outputSGKeyAux), + "KLFitterTools: ERROR! Was not able to write KLFitterResultAuxContainer with best permutation"); + } // watch out for memory leaks! // raw pointers have not been put into a DataVector // we still actually own them - // AnalysisTop will actually do some memory management (which is very wierd and we don't like it) + // AnalysisTop will actually do some memory management (which is very wierd and we don't like it) delete resultContainer; delete resultAuxContainer; } - + // Pull the const result back out of StoreGate and attach to top::Event - top::check(evtStore()->retrieve(event.m_KLFitterResults,outputSGKey),"Failed to add KLFitterResults to top::Event"); + top::check(evtStore()->retrieve(event.m_KLFitterResults, outputSGKey), + "Failed to add KLFitterResults to top::Event"); delete myParticles; - + /// Return gracefully: - return StatusCode::SUCCESS; + return StatusCode::SUCCESS; } - + bool KLFitterTool::HasTag(const xAOD::Jet& jet, double& weight) const { weight = -99.; - const auto& btag_object = jet.btagging(); - const auto& tagger_name = m_btagging_eff_tool->getTaggerName(); - if (!btag_object || !btag_object->MVx_discriminant(tagger_name, weight)) { - ATH_MSG_ERROR("Failed to retrieve "+tagger_name+" weight!"); - } - for(const auto& tagWP : m_config->bTagWP_available()){ - if(!jet.isAvailable<char>("isbtagged_"+tagWP)) { - ATH_MSG_ERROR("Failed to retrieve jet decoration isbtagged_"+tagWP); + for (const auto& tagWP : m_config->bTagWP_available()) { + if (tagWP == "DL1_Continuous") continue; + if (!jet.isAvailable<char>("isbtagged_" + tagWP)) { + ATH_MSG_ERROR("Failed to retrieve jet decoration isbtagged_" + tagWP); break; } - return jet.auxdataConst<char>("isbtagged_"+tagWP); + return jet.auxdataConst<char>("isbtagged_" + tagWP); } return false; } - - + void KLFitterTool::retrieveEfficiencies(const xAOD::Jet& jet, float* efficiency, float* inefficiency) { *efficiency = .7725; // dummy values - *inefficiency = 1./125.93; // dummy values - - auto pretend_to_be_b = new xAOD::Jet(jet); - auto pretend_to_be_light = new xAOD::Jet(jet); - - pretend_to_be_b->setAttribute("HadronConeExclTruthLabelID", 5); - pretend_to_be_light->setAttribute("HadronConeExclTruthLabelID", 0); - - top::check(m_btagging_eff_tool->getMCEfficiency(*pretend_to_be_b, *efficiency), + *inefficiency = 1. / 125.93; // dummy values + //copy jet + xAOD::JetContainer jets; + xAOD::JetAuxContainer jetsAux; + jets.setStore(&jetsAux); + xAOD::Jet* jet_copy = new xAOD::Jet(); + jets.push_back(jet_copy); + *jet_copy = jet; + jet_copy->setJetP4(jet.jetP4()); + //treat jet as b-tagged + jet_copy->setAttribute("HadronConeExclTruthLabelID", 5); + top::check(m_btagging_eff_tool->getMCEfficiency(*jet_copy, *efficiency), "Could not retrieve tagging efficiency for b-jet"); - top::check(m_btagging_eff_tool->getMCEfficiency(*pretend_to_be_light, *inefficiency), + //treat jet as light + jet_copy->setAttribute("HadronConeExclTruthLabelID", 0); + top::check(m_btagging_eff_tool->getMCEfficiency(*jet_copy, *inefficiency), "Could not retrieve tagging efficiency for light jet"); + } - delete pretend_to_be_b; - delete pretend_to_be_light; + bool KLFitterTool::setJets(const top::Event& event, KLFitter::Particles* inputParticles) { + if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingThree) return setJetskLeadingThree(event, + inputParticles); - } + if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingFour) return setJetskLeadingFour(event, + inputParticles); + + + + if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingFive) return setJetskLeadingFive(event, + inputParticles); - void KLFitterTool::setJets(const top::Event& event,KLFitter::Particles* inputParticles) - { - if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingFour) { - setJetskLeadingFour( event , inputParticles ); - } - if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingFive) { - setJetskLeadingFive( event , inputParticles ); - } - if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingSix) { - setJetskLeadingSix( event , inputParticles ); - } - if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kBtagPriorityFourJets) { - setJetskBtagPriorityFourJets( event , inputParticles ); - } - if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kBtagPriorityFiveJets) { - setJetskBtagPriorityFiveJets( event , inputParticles ); - } - if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kBtagPrioritySixJets) { - setJetskBtagPrioritySixJets( event , inputParticles ); - } + if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingSix) return setJetskLeadingSix(event, + inputParticles); + + + + if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingSeven) return setJetskLeadingSeven(event, + inputParticles); + + + + if (m_jetSelectionModeKLFitterEnum == top::KLFitterJetSelection::kLeadingEight) return setJetskLeadingEight(event, + inputParticles); + + + + if (m_jetSelectionModeKLFitterEnum == + top::KLFitterJetSelection::kBtagPriorityThreeJets) return setJetskBtagPriorityThreeJets(event, inputParticles); + + if (m_jetSelectionModeKLFitterEnum == + top::KLFitterJetSelection::kBtagPriorityFourJets) return setJetskBtagPriorityFourJets(event, inputParticles); + + if (m_jetSelectionModeKLFitterEnum == + top::KLFitterJetSelection::kBtagPriorityFiveJets) return setJetskBtagPriorityFiveJets(event, inputParticles); + + if (m_jetSelectionModeKLFitterEnum == + top::KLFitterJetSelection::kBtagPrioritySixJets) return setJetskBtagPrioritySixJets(event, inputParticles); + + if (m_jetSelectionModeKLFitterEnum == + top::KLFitterJetSelection::kBtagPrioritySevenJets) return setJetskBtagPrioritySevenJets(event, inputParticles); + + if (m_jetSelectionModeKLFitterEnum == + top::KLFitterJetSelection::kBtagPriorityEightJets) return setJetskBtagPriorityEightJets(event, inputParticles); + + return false; + } + + bool KLFitterTool::setJetskLeadingThree(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskLeadingX(event, inputParticles, 3); + } + + bool KLFitterTool::setJetskLeadingFour(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskLeadingX(event, inputParticles, 4); + } + + bool KLFitterTool::setJetskLeadingFive(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskLeadingX(event, inputParticles, 5); } - - void KLFitterTool::setJetskLeadingFour(const top::Event& event,KLFitter::Particles* inputParticles) - { - setJetskLeadingX(event, inputParticles, 4); + + bool KLFitterTool::setJetskLeadingSix(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskLeadingX(event, inputParticles, 6); } - void KLFitterTool::setJetskLeadingFive(const top::Event& event,KLFitter::Particles* inputParticles) - { - setJetskLeadingX(event, inputParticles, 5); + bool KLFitterTool::setJetskLeadingSeven(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskLeadingX(event, inputParticles, 7); } - void KLFitterTool::setJetskLeadingSix(const top::Event& event,KLFitter::Particles* inputParticles) - { - setJetskLeadingX(event, inputParticles, 6); + bool KLFitterTool::setJetskLeadingEight(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskLeadingX(event, inputParticles, 8); } - void KLFitterTool::setJetskLeadingX(const top::Event& event,KLFitter::Particles* inputParticles, int njets) - { - int index(0); + bool KLFitterTool::setJetskLeadingX(const top::Event& event, KLFitter::Particles* inputParticles, + const unsigned int njets) { + unsigned int index(0); + + //If container has less jets than required, raise error + if (m_config->KLFitterFailOnLessThanXJets()) { + if (event.m_jets.size() < njets) { + ATH_MSG_INFO( + "KLFitterTool::setJetskLeadingX: You required " << njets << " jets. Event has " << event.m_jets.size() << + " jets!"); + return false; + } + } for (const auto& jet : event.m_jets) { - if (index > njets-1) break; + if (index > njets - 1) break; TLorentzVector jet_p4; jet_p4.SetPtEtaPhiE(jet->pt() / 1.e3, jet->eta(), jet->phi(), jet->e() / 1.e3); double weight(-99.); + float eff(0), ineff(0); + const bool isTagged = HasTag(*jet, weight); - float eff(0), ineff(0); - retrieveEfficiencies(*jet, &eff, &ineff); + if (m_isWorkingPoint) { + retrieveEfficiencies(*jet, &eff, &ineff); - inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, - isTagged, eff, 1./ineff, KLFitter::Particles::kNone, weight); + inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, + isTagged, eff, 1. / ineff, KLFitter::Particles::kNone, weight); + } else { + inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, isTagged); + } ++index; } + return true; + } + + bool KLFitterTool::setJetskBtagPriorityThreeJets(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskBtagPriority(event, inputParticles, 3); } - - void KLFitterTool::setJetskBtagPriorityFourJets(const top::Event& event,KLFitter::Particles* inputParticles) - { - setJetskBtagPriority( event , inputParticles , 4 ); + bool KLFitterTool::setJetskBtagPriorityFourJets(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskBtagPriority(event, inputParticles, 4); } - - void KLFitterTool::setJetskBtagPriorityFiveJets(const top::Event& event,KLFitter::Particles* inputParticles) - { - setJetskBtagPriority( event , inputParticles , 5 ); - } - - void KLFitterTool::setJetskBtagPrioritySixJets(const top::Event& event,KLFitter::Particles* inputParticles) - { - setJetskBtagPriority( event , inputParticles , 6 ); + + bool KLFitterTool::setJetskBtagPriorityFiveJets(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskBtagPriority(event, inputParticles, 5); + } + + bool KLFitterTool::setJetskBtagPrioritySixJets(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskBtagPriority(event, inputParticles, 6); + } + + bool KLFitterTool::setJetskBtagPrioritySevenJets(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskBtagPriority(event, inputParticles, 7); + } + + bool KLFitterTool::setJetskBtagPriorityEightJets(const top::Event& event, KLFitter::Particles* inputParticles) { + return setJetskBtagPriority(event, inputParticles, 8); } - - void KLFitterTool::setJetskBtagPriority(const top::Event& event,KLFitter::Particles* inputParticles,const unsigned int maxJets) - { - // kBtagPriority mode first adds the b jets, then the light jets - // If your 6th or 7th jet is a b jet, then you probably want this option + + bool KLFitterTool::setJetskBtagPriority(const top::Event& event, KLFitter::Particles* inputParticles, + const unsigned int maxJets) { + // kBtagPriority mode first adds the b jets, then the light jets + // If your 6th or 7th jet is a b jet, then you probably want this option + + //If container has less jets than required, raise error + if (m_config->KLFitterFailOnLessThanXJets()) { + if (event.m_jets.size() < maxJets) { + ATH_MSG_INFO( + "KLFitterTool::setJetskBtagPriority: You required " << maxJets << " jets. Event has " << event.m_jets.size() << + " jets!"); + return false; + } + } unsigned int totalJets(0); - // First find the b-jets + // First find the b-jets unsigned int index(0); double weight(0); for (const auto& jet : event.m_jets) { if (totalJets >= maxJets) break; if (HasTag(*jet, weight)) { - TLorentzVector jet_p4; + TLorentzVector jet_p4; jet_p4.SetPtEtaPhiE(jet->pt() / 1.e3, jet->eta(), jet->phi(), jet->e() / 1.e3); - float eff(0), ineff(0); - retrieveEfficiencies(*jet, &eff, &ineff); + if (m_isWorkingPoint) { + float eff(0), ineff(0); + retrieveEfficiencies(*jet, &eff, &ineff); - inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, - true, eff, 1./ineff, KLFitter::Particles::kNone, weight); + inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, + true, eff, 1. / ineff, KLFitter::Particles::kNone, weight); + } else { + inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, + true); + } ++totalJets; - } // HasTag - + } // HasTag + ++index; - } // for (jet) - + } // for (jet) + - // Second, find the light jets + // Second, find the light jets index = 0; for (const auto& jet : event.m_jets) { if (totalJets >= maxJets) break; @@ -610,24 +1018,27 @@ namespace top{ TLorentzVector jet_p4; jet_p4.SetPtEtaPhiE(jet->pt() / 1.e3, jet->eta(), jet->phi(), jet->e() / 1.e3); - float eff(0), ineff(0); - retrieveEfficiencies(*jet, &eff, &ineff); + if (m_isWorkingPoint) { + float eff(0), ineff(0); + retrieveEfficiencies(*jet, &eff, &ineff); - inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, - false, eff, 1./ineff, KLFitter::Particles::kNone, weight); + inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, + false, eff, 1. / ineff, KLFitter::Particles::kNone, weight); + } else { + inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, + false); + } ++totalJets; - } // !HasTag - + } // !HasTag + ++index; - } // for (jet) - + } // for (jet) + return true; } - /// Function finalizing the tool - StatusCode KLFitterTool::finalize() - { + StatusCode KLFitterTool::finalize() { /// Return gracefully: - return StatusCode::SUCCESS; + return StatusCode::SUCCESS; } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/LinkDef.h index dbc94fd06e17..a81a3c2f51e3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/LinkDef.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/LinkDef.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/TopEventReconstructionToolsLoader.h" diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/MT2Reco.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/MT2Reco.cxx index dcbe8c0e0001..7aa6718b2e14 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/MT2Reco.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/MT2Reco.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/MT2Reco.h" @@ -9,17 +9,15 @@ #ifdef ROOTCORE_PACKAGE_Oxbridgekinetics namespace top { + MT2Reco::MT2Reco() { + } -MT2Reco::MT2Reco() { -} - -MT2Reco::~MT2Reco() { -} + MT2Reco::~MT2Reco() { + } -bool MT2Reco::apply(const top::Event& /*event*/) const { + bool MT2Reco::apply(const top::Event& /*event*/) const { return true; -} - + } } #endif //ROOTCORE_PACKAGE_Oxbridgekinetics diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/NeutrinoWeighting.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/NeutrinoWeighting.cxx index f0807169e4d9..54a50b4e490b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/NeutrinoWeighting.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/NeutrinoWeighting.cxx @@ -1,37 +1,39 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/NeutrinoWeighting.h" #include "TopEvent/Event.h" -namespace top { +#include <cmath> -NeutrinoWeighting::NeutrinoWeighting() : sigmax(10), sigmay(10) { +namespace top { + NeutrinoWeighting::NeutrinoWeighting() : sigmax(10), sigmay(10) { double etaStep = 0.2; //construct the array of eta values to use (cosh and sinh them) int index = 0; + for (double eta = -5.0; eta < 5.0001; eta += etaStep) { - neutrinos[index][0] = eta; - neutrinos[index][1] = sinh(eta); - neutrinos[index][2] = cosh(eta); - ++index; + neutrinos[index][0] = eta; + neutrinos[index][1] = std::sinh(eta); + neutrinos[index][2] = std::cosh(eta); + ++index; } etaSize = index; if (etaSize > 2000) { - std::cout << "ERROR TOO MANY SAMPLING POINT FOR neutrinos ARRAY" << std::endl; - exit(1); + std::cout << "ERROR TOO MANY SAMPLING POINT FOR neutrinos ARRAY" << std::endl; + exit(1); } -} + } -NeutrinoWeighting::~NeutrinoWeighting() { -} + NeutrinoWeighting::~NeutrinoWeighting() { + } -bool NeutrinoWeighting::apply(const top::Event& event) const { + bool NeutrinoWeighting::apply(const top::Event& event) const { TLorentzVector l1; TLorentzVector l2; TLorentzVector b1; @@ -42,41 +44,42 @@ bool NeutrinoWeighting::apply(const top::Event& event) const { const double met_ey = event.m_met->mpy(); for (int i = 0; i < etaSize; ++i) { - for (int j = 0; j < etaSize; ++j) { - NWSolution ans1 = solveForNeutrinoEta(l1, b1, topMass, i); - NWSolution ans2 = solveForNeutrinoEta(l2, b2, topMass, j); - - if (ans1.getNumSolutions() > 0 && ans2.getNumSolutions() > 0) { - const double sol1 = neutrino_weight(ans1.getv1(), ans2.getv1(), met_ex, met_ey); - const double sol2 = neutrino_weight(ans1.getv1(), ans2.getv2(), met_ex, met_ey); - const double sol3 = neutrino_weight(ans1.getv2(), ans2.getv1(), met_ex, met_ey); - const double sol4 = neutrino_weight(ans1.getv2(), ans2.getv2(), met_ex, met_ey); - - if (isnan(sol1) || isnan(sol2) || isnan(sol3) || isnan(sol4)) - std::cout << "One of the quadratic ans is NaN!" << std::endl; - } - - ans1 = solveForNeutrinoEta(l1, b2, topMass, i); - ans2 = solveForNeutrinoEta(l2, b1, topMass, j); - - if (ans1.getNumSolutions() > 0 && ans2.getNumSolutions() > 0) { - const double sol1 = neutrino_weight(ans1.getv1(), ans2.getv1(), met_ex, met_ey); - const double sol2 = neutrino_weight(ans1.getv1(), ans2.getv2(), met_ex, met_ey); - const double sol3 = neutrino_weight(ans1.getv2(), ans2.getv1(), met_ex, met_ey); - const double sol4 = neutrino_weight(ans1.getv2(), ans2.getv2(), met_ex, met_ey); - - if (isnan(sol1) || isnan(sol2) || isnan(sol3) || isnan(sol4)) - std::cout << "One of the quadratic ans is NaN!" << std::endl; - } - } - } + for (int j = 0; j < etaSize; ++j) { + NWSolution ans1 = solveForNeutrinoEta(l1, b1, topMass, i); + NWSolution ans2 = solveForNeutrinoEta(l2, b2, topMass, j); + + if (ans1.getNumSolutions() > 0 && ans2.getNumSolutions() > 0) { + const double sol1 = neutrino_weight(ans1.getv1(), ans2.getv1(), met_ex, met_ey); + const double sol2 = neutrino_weight(ans1.getv1(), ans2.getv2(), met_ex, met_ey); + const double sol3 = neutrino_weight(ans1.getv2(), ans2.getv1(), met_ex, met_ey); + const double sol4 = neutrino_weight(ans1.getv2(), ans2.getv2(), met_ex, met_ey); + + if (std::isnan(sol1) || std::isnan(sol2) || std::isnan(sol3) || + std::isnan(sol4)) std::cout << "One of the quadratic ans is NaN!" << std::endl; + } + + ans1 = solveForNeutrinoEta(l1, b2, topMass, i); + ans2 = solveForNeutrinoEta(l2, b1, topMass, j); + + if (ans1.getNumSolutions() > 0 && ans2.getNumSolutions() > 0) { + const double sol1 = neutrino_weight(ans1.getv1(), ans2.getv1(), met_ex, met_ey); + const double sol2 = neutrino_weight(ans1.getv1(), ans2.getv2(), met_ex, met_ey); + const double sol3 = neutrino_weight(ans1.getv2(), ans2.getv1(), met_ex, met_ey); + const double sol4 = neutrino_weight(ans1.getv2(), ans2.getv2(), met_ex, met_ey); + + if (std::isnan(sol1) || std::isnan(sol2) || std::isnan(sol3) || + std::isnan(sol4)) std::cout << "One of the quadratic ans is NaN!" << std::endl; + } + } + } //normalise? return true; -} + } -NWSolution NeutrinoWeighting::solveForNeutrinoEta(const TLorentzVector& lepton, const TLorentzVector& bJet, double topMass, int index) const { + NWSolution NeutrinoWeighting::solveForNeutrinoEta(const TLorentzVector& lepton, const TLorentzVector& bJet, + double topMass, int index) const { double Wmass2 = m_wmass * m_wmass; double bmass = m_bmass; @@ -84,7 +87,8 @@ NWSolution NeutrinoWeighting::solveForNeutrinoEta(const TLorentzVector& lepton, double Ebprime = bJet.E() * neutrinos[index][2] - bJet.Pz() * neutrinos[index][1]; double A = (lepton.Py() * Ebprime - bJet.Py() * Elprime) / (bJet.Px() * Elprime - lepton.Px() * Ebprime); - double B = (Elprime * (topMass * topMass - Wmass2 - bmass * bmass - 2. * lepton * bJet) - Ebprime * Wmass2) / (2. * (lepton.Px() * Ebprime - bJet.Px() * Elprime)); + double B = (Elprime * (topMass * topMass - Wmass2 - bmass * bmass - 2. * lepton * bJet) - Ebprime * Wmass2) / + (2. * (lepton.Px() * Ebprime - bJet.Px() * Elprime)); double par1 = (lepton.Px() * A + lepton.Py()) / Elprime; double C = A * A + 1. - par1 * par1; @@ -94,33 +98,34 @@ NWSolution NeutrinoWeighting::solveForNeutrinoEta(const TLorentzVector& lepton, double det = D * D - 4. * C * F; NWSolution sol; + sol.setSolutions(0); if (det > 0.) { - double tmp = sqrt(det) / (2. * C); - double py1 = -D / (2. * C) + tmp; - double py2 = -D / (2. * C) - tmp; - double px1 = A * py1 + B; - double px2 = A * py2 + B; - double pT2_1 = px1 * px1 + py1 * py1; - double pT2_2 = px2 * px2 + py2 * py2; - double pz1 = sqrt(pT2_1) * neutrinos[index][1]; - double pz2 = sqrt(pT2_2) * neutrinos[index][1]; - - TLorentzVector a1(px1, py1, pz1, sqrt(pT2_1 + pz1 * pz1)); - TLorentzVector a2(px2, py2, pz2, sqrt(pT2_2 + pz2 * pz2)); - - sol.setSolutions(2, a1, a2); + double tmp = std::sqrt(det) / (2. * C); + double py1 = -D / (2. * C) + tmp; + double py2 = -D / (2. * C) - tmp; + double px1 = A * py1 + B; + double px2 = A * py2 + B; + double pT2_1 = px1 * px1 + py1 * py1; + double pT2_2 = px2 * px2 + py2 * py2; + double pz1 = std::sqrt(pT2_1) * neutrinos[index][1]; + double pz2 = std::sqrt(pT2_2) * neutrinos[index][1]; + + TLorentzVector a1(px1, py1, pz1, sqrt(pT2_1 + pz1* pz1)); + TLorentzVector a2(px2, py2, pz2, sqrt(pT2_2 + pz2* pz2)); + + sol.setSolutions(2, a1, a2); } return sol; -} + } -double NeutrinoWeighting::neutrino_weight(const TLorentzVector& neutrino1, const TLorentzVector& neutrino2, double met_ex, double met_ey) const { + double NeutrinoWeighting::neutrino_weight(const TLorentzVector& neutrino1, const TLorentzVector& neutrino2, + double met_ex, double met_ey) const { const double dx = met_ex - neutrino1.Px() - neutrino2.Px(); const double dy = met_ey - neutrino1.Py() - neutrino2.Py(); - return exp(- dx * dx / (2. * sigmax * sigmax) - dy * dy / (2. * sigmay * sigmay)); -} - + return exp(-dx * dx / (2. * sigmax * sigmax) - dy * dy / (2. * sigmay * sigmay)); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PTMaxReco.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PTMaxReco.cxx index 9fc9fd90a016..466683dfce36 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PTMaxReco.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PTMaxReco.cxx @@ -1,20 +1,19 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/PTMaxReco.h" #include "TopEvent/Event.h" namespace top { + PTMaxReco::PTMaxReco() : m_wmass(80400.), m_topmass(172500.) { + } -PTMaxReco::PTMaxReco() : m_wmass(80400.), m_topmass(172500.) { -} - -PTMaxReco::~PTMaxReco() { -} + PTMaxReco::~PTMaxReco() { + } -bool PTMaxReco::apply(const top::Event& event) const { + bool PTMaxReco::apply(const top::Event& event) const { //get the hadronic top //jets that make-up the hadronic top quark @@ -23,93 +22,87 @@ bool PTMaxReco::apply(const top::Event& event) const { const xAOD::Jet* jet3 = nullptr; double maxptsq = 0.; + for (xAOD::JetContainer::const_iterator j1 = event.m_jets.begin(); j1 != event.m_jets.end(); ++j1) { - for (xAOD::JetContainer::const_iterator j2 = j1 + 1; j2 != event.m_jets.end(); ++j2) { - for (xAOD::JetContainer::const_iterator j3 = j2 + 1; j3 != event.m_jets.end(); ++j3) { - const double px = (*j1)->px() + (*j2)->px() + (*j3)->px(); - const double py = (*j1)->py() + (*j2)->py() + (*j3)->py(); - - //pt2 to avoid the slow sqrt - const double ptsq = px * px + py * py; - - if (ptsq > maxptsq) { - jet1 = (*j1); - jet2 = (*j2); - jet3 = (*j3); - } - } + for (xAOD::JetContainer::const_iterator j2 = j1 + 1; j2 != event.m_jets.end(); ++j2) { + for (xAOD::JetContainer::const_iterator j3 = j2 + 1; j3 != event.m_jets.end(); ++j3) { + const double px = (*j1)->px() + (*j2)->px() + (*j3)->px(); + const double py = (*j1)->py() + (*j2)->py() + (*j3)->py(); + + //pt2 to avoid the slow sqrt + const double ptsq = px * px + py * py; + + if (ptsq > maxptsq) { + jet1 = (*j1); + jet2 = (*j2); + jet3 = (*j3); + } } + } } //get the leptonic top //e+jets TLorentzVector lepton; - if (event.m_electrons.size() == 1) - lepton = event.m_electrons.at(0)->p4(); + if (event.m_electrons.size() == 1) lepton = event.m_electrons.at(0)->p4(); //mu+jets - if (event.m_muons.size() == 1) - lepton = event.m_muons.at(0)->p4(); + if (event.m_muons.size() == 1) lepton = event.m_muons.at(0)->p4(); TLorentzVector nu = neutrinoCandidate(lepton, *event.m_met, true); const xAOD::Jet* lepb = nullptr; double topdiff = 1000000.; for (xAOD::JetContainer::const_iterator j1 = event.m_jets.begin(); j1 != event.m_jets.end(); ++j1) { - //ignore the three jets that make-up the hadronic top quark - if (*j1 == jet1 || *j1 == jet2 || *j1 == jet3) - continue; + //ignore the three jets that make-up the hadronic top quark + if (*j1 == jet1 || *j1 == jet2 || *j1 == jet3) continue; - //pick the jet which makes a leptonic top closest to the true top mass - const double tempdiff = fabs((lepton + nu + (*j1)->p4()).M()); + //pick the jet which makes a leptonic top closest to the true top mass + const double tempdiff = fabs((lepton + nu + (*j1)->p4()).M()); - if ((tempdiff - m_topmass) < topdiff) { - lepb = *j1; - topdiff = tempdiff; - } + if ((tempdiff - m_topmass) < topdiff) { + lepb = *j1; + topdiff = tempdiff; + } } std::cout << lepb->pt() << std::endl; return true; -} + } -TLorentzVector PTMaxReco::neutrinoCandidate(const TLorentzVector& lep, const xAOD::MissingET& met, bool dealWithNegative_nu) const { + TLorentzVector PTMaxReco::neutrinoCandidate(const TLorentzVector& lep, const xAOD::MissingET& met, + bool dealWithNegative_nu) const { const double px = met.mpx(); const double py = met.mpy(); // solve quadratic to find neutrino four vector - double alpha = pow(m_wmass,2) + pow((px+lep.Px()),2)+pow((py+lep.Py()),2) -pow(lep.E(),2); - double beta = 0.5 * ( alpha-pow(met.met(),2) + pow(lep.Pz(), 2) ); - double gamma = -( beta*beta - ( pow(lep.E(),2)*pow(met.met(), 2) ) ) / ( pow(lep.E(),2)-pow(lep.Pz(), 2) ); - double lambda = 2. * beta * lep.Pz() / (pow(lep.E(), 2)-pow(lep.Pz(), 2)); - double delta = pow(lambda,2) - 4 * gamma; + double alpha = pow(m_wmass, 2) + pow((px + lep.Px()), 2) + pow((py + lep.Py()), 2) - pow(lep.E(), 2); + double beta = 0.5 * (alpha - pow(met.met(), 2) + pow(lep.Pz(), 2)); + double gamma = -(beta * beta - (pow(lep.E(), 2) * pow(met.met(), 2))) / (pow(lep.E(), 2) - pow(lep.Pz(), 2)); + double lambda = 2. * beta * lep.Pz() / (pow(lep.E(), 2) - pow(lep.Pz(), 2)); + double delta = pow(lambda, 2) - 4 * gamma; if (delta < 0) { // ignore non real solutions - if (dealWithNegative_nu) - delta = 0; - else - return TLorentzVector(); + if (dealWithNegative_nu) delta = 0; + else return TLorentzVector(); } delta = sqrt(delta); - double pz_pos = (lambda+delta) / 2.; - double pz_neg = (lambda-delta) / 2.; + double pz_pos = (lambda + delta) / 2.; + double pz_neg = (lambda - delta) / 2.; double pz = 0.0; - if (fabs(pz_pos) > fabs(pz_neg)) - pz = pz_neg; - else - pz = pz_pos; + if (fabs(pz_pos) > fabs(pz_neg)) pz = pz_neg; + else pz = pz_pos; - double e = sqrt(px*px + py*py + pz*pz); + double e = sqrt(px * px + py * py + pz * pz); TLorentzVector neutrino; neutrino.SetPxPyPzE(px, py, pz, e); return neutrino; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PseudoTopReco.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PseudoTopReco.cxx index d3895c0fd436..7545b624d716 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PseudoTopReco.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PseudoTopReco.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // definitions taken from the MAMbo code here: https://twiki.cern.ch/twiki/bin/view/Main/MAMbo @@ -13,21 +13,18 @@ #include <algorithm> -namespace top{ - - PseudoTopReco::PseudoTopReco( const std::string& name) : - asg::AsgTool( name ), +namespace top { + PseudoTopReco::PseudoTopReco(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), - m_bTagCutValue(9999.9), - m_leptonType("SetMe") - { - declareProperty( "config" , m_config , "Set the configuration" ); - declareProperty( "LeptonType", m_leptonType = "kUndefined" , "Define the lepton type" ); + m_bTagCutValue(9999.9), + m_leptonType("SetMe") { + declareProperty("config", m_config, "Set the configuration"); + declareProperty("LeptonType", m_leptonType = "kUndefined", "Define the lepton type"); } - + /// Function initialising the tool - StatusCode PseudoTopReco::initialize() - { + StatusCode PseudoTopReco::initialize() { // Have you set the config?? if (m_config == nullptr) { ATH_MSG_ERROR("Please set the top::TopConfig"); @@ -35,354 +32,324 @@ namespace top{ } m_config->setPseudoTop(); - + // Figure out the b tagging working point if (m_config->bTagWP_available().size() != 1) { - ATH_MSG_INFO(m_config->bTagWP_available().size()<<" b-tagging WP - cannot pick b-jets. Please select only 1 WP if you want to use the PseudoTop reconstruction"); + ATH_MSG_INFO( + m_config->bTagWP_available().size() << + " b-tagging WP - cannot pick b-jets. Please select only 1 WP if you want to use the PseudoTop reconstruction"); } - - + + ATH_MSG_INFO("++++++++++++++++++++++++++++++"); ATH_MSG_INFO(" Using Lepton \t" << m_leptonType); - ATH_MSG_INFO("++++++++++++++++++++++++++++++"); - + ATH_MSG_INFO("++++++++++++++++++++++++++++++"); + /// Return gracefully: - return StatusCode::SUCCESS; + return StatusCode::SUCCESS; } - + /// Function executing the tool - StatusCode PseudoTopReco::execute(const top::Event& event) - { + StatusCode PseudoTopReco::execute(const top::Event& event) { + if ((!event.m_isLoose && + evtStore()->contains<xAOD::PseudoTopResultContainer>(m_config->sgKeyPseudoTop(event.m_hashValue))) || + (event.m_isLoose && + evtStore()->contains<xAOD::PseudoTopResultContainer>(m_config->sgKeyPseudoTopLoose(event.m_hashValue)))) { + return StatusCode::SUCCESS; + } - // Create the partonHistory xAOD object - xAOD::PseudoTopResultAuxContainer* pseudoTopAuxCont = new xAOD::PseudoTopResultAuxContainer{}; - xAOD::PseudoTopResultContainer* pseudoTop = new xAOD::PseudoTopResultContainer{}; - pseudoTop->setStore( pseudoTopAuxCont ); + // Create the partonHistory xAOD object + xAOD::PseudoTopResultAuxContainer* pseudoTopAuxCont = new xAOD::PseudoTopResultAuxContainer {}; + xAOD::PseudoTopResultContainer* pseudoTop = new xAOD::PseudoTopResultContainer {}; + pseudoTop->setStore(pseudoTopAuxCont); - xAOD::PseudoTopResult* PseudoTopResult = new xAOD::PseudoTopResult{}; - pseudoTop -> push_back( PseudoTopResult ); + xAOD::PseudoTopResult* PseudoTopResult = new xAOD::PseudoTopResult {}; + pseudoTop->push_back(PseudoTopResult); - PseudoTopResult -> IniVar(true); + PseudoTopResult->IniVar(true); // fill either reco particles or truth particles into four vectors // store them in GeV // check if particle/jet is b-tagged // check if electron or muon channel // store output so that it can be written later to the event saver - + m_bJets.clear(); m_lightJets.clear(); - + // get the MET x and y components for the reconstruction - m_nu_px = event.m_met->mpx() / 1.e3; - m_nu_py = event.m_met->mpy() / 1.e3; - m_met_et = sqrt(m_nu_px*m_nu_px + m_nu_py*m_nu_py); + m_nu_px = event.m_met->mpx() / 1.e3; + m_nu_py = event.m_met->mpy() / 1.e3; + m_met_et = sqrt(m_nu_px * m_nu_px + m_nu_py * m_nu_py); SetJetInfo(event); SetChargedLeptonInfo(event); - if(m_bJets.size() == 2 && m_lightJets.size() >= 2){ - + if (m_bJets.size() == 2 && m_lightJets.size() >= 2) { ReconstructLeptonicW(); RunReconstruction(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_top_lep_pt" ) = m_top_lep.Pt(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_top_lep_eta" ) = m_top_lep.Eta(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_top_lep_phi" ) = m_top_lep.Phi(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_top_lep_m" ) = m_top_lep.M(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_top_lep_pt") = m_top_lep.Pt(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_top_lep_eta") = m_top_lep.Eta(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_top_lep_phi") = m_top_lep.Phi(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_top_lep_m") = m_top_lep.M(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_top_had_pt" ) = m_top_had.Pt(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_top_had_eta" ) = m_top_had.Eta(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_top_had_phi" ) = m_top_had.Phi(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_top_had_m" ) = m_top_had.M(); - - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_ttbar_pt" ) = m_ttbar.Pt(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_ttbar_eta" ) = m_ttbar.Eta(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_ttbar_phi" ) = m_ttbar.Phi(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Reco_ttbar_m" ) = m_ttbar.M(); - - } - else{ + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_top_had_pt") = m_top_had.Pt(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_top_had_eta") = m_top_had.Eta(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_top_had_phi") = m_top_had.Phi(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_top_had_m") = m_top_had.M(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_ttbar_pt") = m_ttbar.Pt(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_ttbar_eta") = m_ttbar.Eta(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_ttbar_phi") = m_ttbar.Phi(); + PseudoTopResult->auxdecor< float >("PseudoTop_Reco_ttbar_m") = m_ttbar.M(); + } else { // std::cout<< "NOT ENOUGH BJETS!!!" << std::endl; - } - // Save to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyPseudoTop(event.m_hashValue); + // Save to StoreGate / TStore + std::string outputSGKey("SetMe"); + if (!event.m_isLoose) { + outputSGKey = m_config->sgKeyPseudoTop(event.m_hashValue); + } else { + outputSGKey = m_config->sgKeyPseudoTopLoose(event.m_hashValue); + } std::string outputSGKeyAux = outputSGKey + "Aux."; - xAOD::TReturnCode save = evtStore()->tds()->record( pseudoTop , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( pseudoTopAuxCont , outputSGKeyAux ); - if( !save || !saveAux ){ + xAOD::TReturnCode save = evtStore()->tds()->record(pseudoTop, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(pseudoTopAuxCont, outputSGKeyAux); + if (!save || !saveAux) { return StatusCode::FAILURE; - } - + } + /// Return gracefully: - return StatusCode::SUCCESS; + return StatusCode::SUCCESS; } - StatusCode PseudoTopReco::execute(const top::ParticleLevelEvent& plEvent) - { + StatusCode PseudoTopReco::execute(const top::ParticleLevelEvent& plEvent) { + if (evtStore()->contains<xAOD::PseudoTopResultContainer>(m_config->sgKeyPseudoTop(0))) { + return StatusCode::SUCCESS; + } - // Create the pseudoTopHistory xAOD object - xAOD::PseudoTopResultAuxContainer* pseudoTopAuxCont = new xAOD::PseudoTopResultAuxContainer{}; - xAOD::PseudoTopResultContainer* pseudoTop = new xAOD::PseudoTopResultContainer{}; - pseudoTop->setStore( pseudoTopAuxCont ); + // Create the pseudoTopHistory xAOD object + xAOD::PseudoTopResultAuxContainer* pseudoTopAuxCont = new xAOD::PseudoTopResultAuxContainer {}; + xAOD::PseudoTopResultContainer* pseudoTop = new xAOD::PseudoTopResultContainer {}; + pseudoTop->setStore(pseudoTopAuxCont); - xAOD::PseudoTopResult* PseudoTopResult = new xAOD::PseudoTopResult{}; - pseudoTop->push_back( PseudoTopResult ); + xAOD::PseudoTopResult* PseudoTopResult = new xAOD::PseudoTopResult {}; + pseudoTop->push_back(PseudoTopResult); - PseudoTopResult -> IniVar(false); + PseudoTopResult->IniVar(false); m_bJets.clear(); m_lightJets.clear(); - // get the MET x and y components for the reconstruction - m_nu_px = plEvent.m_met->mpx() / 1.e3; - m_nu_py = plEvent.m_met->mpy() / 1.e3; - m_met_et = sqrt(m_nu_px*m_nu_px + m_nu_py*m_nu_py); - + // get the MET x and y components for the reconstruction + m_nu_px = plEvent.m_met->mpx() / 1.e3; + m_nu_py = plEvent.m_met->mpy() / 1.e3; + m_met_et = sqrt(m_nu_px * m_nu_px + m_nu_py * m_nu_py); + SetJetInfo(plEvent); SetChargedLeptonInfo(plEvent); - if(m_bJets.size() == 2 && m_lightJets.size() >= 2){ - + if (m_bJets.size() == 2 && m_lightJets.size() >= 2) { ReconstructLeptonicW(); RunReconstruction(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_top_lep_pt" ) = m_top_lep.Pt(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_top_lep_eta" ) = m_top_lep.Eta(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_top_lep_phi" ) = m_top_lep.Phi(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_top_lep_m" ) = m_top_lep.M(); - - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_top_had_pt" ) = m_top_had.Pt(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_top_had_eta" ) = m_top_had.Eta(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_top_had_phi" ) = m_top_had.Phi(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_top_had_m" ) = m_top_had.M(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_top_lep_pt") = m_top_lep.Pt(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_top_lep_eta") = m_top_lep.Eta(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_top_lep_phi") = m_top_lep.Phi(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_top_lep_m") = m_top_lep.M(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_ttbar_pt" ) = m_ttbar.Pt(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_ttbar_eta" ) = m_ttbar.Eta(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_ttbar_phi" ) = m_ttbar.Phi(); - PseudoTopResult->auxdecor< float >( "PseudoTop_Particle_ttbar_m" ) = m_ttbar.M(); - - - - } - else{ + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_top_had_pt") = m_top_had.Pt(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_top_had_eta") = m_top_had.Eta(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_top_had_phi") = m_top_had.Phi(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_top_had_m") = m_top_had.M(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_ttbar_pt") = m_ttbar.Pt(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_ttbar_eta") = m_ttbar.Eta(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_ttbar_phi") = m_ttbar.Phi(); + PseudoTopResult->auxdecor< float >("PseudoTop_Particle_ttbar_m") = m_ttbar.M(); + } else { // std::cout << "NOT ENOUGH BJETS!!!" << std::endl; - } - // Save to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyPseudoTop(0); + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyPseudoTop(0); std::string outputSGKeyAux = outputSGKey + "Aux."; - xAOD::TReturnCode save = evtStore()->tds()->record( pseudoTop , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( pseudoTopAuxCont , outputSGKeyAux ); - if( !save || !saveAux ){ + xAOD::TReturnCode save = evtStore()->tds()->record(pseudoTop, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(pseudoTopAuxCont, outputSGKeyAux); + if (!save || !saveAux) { return StatusCode::FAILURE; } - /// Return gracefully: + /// Return gracefully: return StatusCode::SUCCESS; } - - - bool PseudoTopReco::SetChargedLeptonInfo(const top::Event& event){ + bool PseudoTopReco::SetChargedLeptonInfo(const top::Event& event) { if (m_leptonType == "kElectron") { - m_lepton.SetPtEtaPhiE(event.m_electrons.at(0)->pt()/1.e3 , event.m_electrons.at(0)->eta(), event.m_electrons.at(0)->phi(), event.m_electrons.at(0) ->e() / 1.e3 ); - } - else if (m_leptonType == "kMuon") { - m_lepton.SetPtEtaPhiE( event.m_muons.at(0)->pt()/1.e3 , event.m_muons.at(0)->eta() , event.m_muons.at(0)->phi(), event.m_muons.at(0)->e() / 1.e3); - } - else { + m_lepton.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at( + 0)->phi(), event.m_electrons.at(0)->e() / 1.e3); + } else if (m_leptonType == "kMuon") { + m_lepton.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at( + 0)->phi(), event.m_muons.at(0)->e() / 1.e3); + } else { ATH_MSG_ERROR(" Please supply a valid LeptonType : kElectron or kMuon"); return false; } return true; - } - bool PseudoTopReco::SetChargedLeptonInfo(const top::ParticleLevelEvent& plEvent){ - + bool PseudoTopReco::SetChargedLeptonInfo(const top::ParticleLevelEvent& plEvent) { if (m_leptonType == "kElectron") { - m_lepton.SetPtEtaPhiE( plEvent.m_electrons->at(0)->pt()/1.e3 , plEvent.m_electrons->at(0)->eta(), plEvent.m_electrons->at(0)->phi(), plEvent.m_electrons->at(0)->e() / 1.e3 ); - } - else if (m_leptonType == "kMuon") { - m_lepton.SetPtEtaPhiE( plEvent.m_muons->at(0)->pt()/1.e3 , plEvent.m_muons->at(0)->eta(), plEvent.m_muons->at(0)->phi(), plEvent.m_muons->at(0)->e() / 1.e3 ); - } - else { + m_lepton.SetPtEtaPhiE(plEvent.m_electrons->at(0)->pt() / 1.e3, plEvent.m_electrons->at( + 0)->eta(), plEvent.m_electrons->at(0)->phi(), plEvent.m_electrons->at(0)->e() / 1.e3); + } else if (m_leptonType == "kMuon") { + m_lepton.SetPtEtaPhiE(plEvent.m_muons->at(0)->pt() / 1.e3, plEvent.m_muons->at(0)->eta(), plEvent.m_muons->at( + 0)->phi(), plEvent.m_muons->at(0)->e() / 1.e3); + } else { ATH_MSG_ERROR(" Please supply a valid LeptonType : kElectron or kMuon"); return false; } - + return true; - } - - bool PseudoTopReco::SetJetInfo(const top::Event& event){ - + bool PseudoTopReco::SetJetInfo(const top::Event& event) { int bCounter = 0; for (const auto* const jetPtr : event.m_jets) { - TLorentzVector helpVec(0, 0, 0, 0); - helpVec.SetPtEtaPhiE( jetPtr->pt() / 1.e3 , jetPtr->eta() , jetPtr->phi() , jetPtr->e() / 1.e3); - + helpVec.SetPtEtaPhiE(jetPtr->pt() / 1.e3, jetPtr->eta(), jetPtr->phi(), jetPtr->e() / 1.e3); + // if more than two b-jets are available, consider third leading b-tagged jet as light jet! std::string out = m_config->bTagWP_available()[0]; - const bool hasbTagFlag = jetPtr->isAvailable<char>("isbtagged_"+out); + const bool hasbTagFlag = jetPtr->isAvailable<char>("isbtagged_" + out); if (hasbTagFlag) { - if (jetPtr->auxdataConst<char>("isbtagged_"+out) && bCounter < 2) { - m_bJets.push_back(helpVec); - - bCounter++; - } - else{ - m_lightJets.push_back(helpVec); - } + if (jetPtr->auxdataConst<char>("isbtagged_" + out) && bCounter < 2) { + m_bJets.push_back(helpVec); + + bCounter++; + } else { + m_lightJets.push_back(helpVec); + } } } // end loop over jets - + return true; - } - - - bool PseudoTopReco::SetJetInfo(const top::ParticleLevelEvent& plEvent){ - + + bool PseudoTopReco::SetJetInfo(const top::ParticleLevelEvent& plEvent) { // if more than two b-jets are available, consider third leading b-tagged jet as light jet! int bCounter = 0; - for (const auto & jetPtr : * plEvent.m_jets) { - + for (const auto& jetPtr : *plEvent.m_jets) { TLorentzVector helpVec(0, 0, 0, 0); - helpVec.SetPtEtaPhiE( jetPtr->pt() / 1.e3 , jetPtr->eta() , jetPtr->phi() , jetPtr->e() / 1.e3); - - int nGhosts = jetPtr->auxdata<int>( "GhostBHadronsFinalCount" ); - - if(nGhosts >= 1 && bCounter < 2){ - m_bJets.push_back(helpVec); - bCounter++; - } - else - m_lightJets.push_back(helpVec); + helpVec.SetPtEtaPhiE(jetPtr->pt() / 1.e3, jetPtr->eta(), jetPtr->phi(), jetPtr->e() / 1.e3); + + int nGhosts = jetPtr->auxdata<int>("GhostBHadronsFinalCount"); + + if (nGhosts >= 1 && bCounter < 2) { + m_bJets.push_back(helpVec); + bCounter++; + } else m_lightJets.push_back(helpVec); } - + return true; - } - - bool PseudoTopReco::RunReconstruction(){ - + bool PseudoTopReco::RunReconstruction() { double bestwmass = 999.e9; TLorentzVector Whelp(0, 0, 0, 0); // get first the b-jet closest to the lepton in dR // define this as TLorentzVector m_b_lep; - // take now remaining b-jet as m_b_had + // take now remaining b-jet as m_b_had double dRb1 = m_bJets[0].DeltaR(m_lepton); double dRb2 = m_bJets[1].DeltaR(m_lepton); - if(dRb1 < dRb2){ + if (dRb1 < dRb2) { m_b_lep = m_bJets[0]; m_b_had = m_bJets[1]; - } - else{ + } else { m_b_lep = m_bJets[1]; m_b_had = m_bJets[0]; } - // then loop over all light jets - // take combination which is closest to mW (PDG) - for(unsigned int iJet = 0; iJet < m_lightJets.size(); ++iJet){ - for(unsigned int kJet = 0; kJet < m_lightJets.size(); ++kJet){ - - if(iJet == kJet) - continue; - - Whelp = m_lightJets[iJet] + m_lightJets[kJet]; - - if(fabs(mWPDG - Whelp.M()) < fabs(mWPDG - bestwmass)){ - - m_W_had = Whelp; - bestwmass = Whelp.M(); - - } + // then loop over all light jets + // take combination which is closest to mW (PDG) + for (unsigned int iJet = 0; iJet < m_lightJets.size(); ++iJet) { + for (unsigned int kJet = 0; kJet < m_lightJets.size(); ++kJet) { + if (iJet == kJet) continue; + Whelp = m_lightJets[iJet] + m_lightJets[kJet]; + + if (fabs(mWPDG - Whelp.M()) < fabs(mWPDG - bestwmass)) { + m_W_had = Whelp; + bestwmass = Whelp.M(); + } } - } - + } + // define now the top and ttbar four-vectors m_top_lep = m_W_lep + m_b_lep; m_top_had = m_W_had + m_b_had; - m_ttbar = m_top_lep + m_top_had; - + m_ttbar = m_top_lep + m_top_had; + return true; - } - - bool PseudoTopReco::ReconstructLeptonicW() - { - double v_pz = -KinemEdge; + bool PseudoTopReco::ReconstructLeptonicW() { + double v_pz = -KinemEdge; double delta = -KinemEdge; - - // lepton already made by reco or particle levels: - double l_px = m_lepton.Px(); double l_py = m_lepton.Py(); double l_pz = m_lepton.Pz(); - double l_m = m_lepton.M(); double l_E = m_lepton.E(); - double mdiff = 0.5 * ( mWPDG*mWPDG - l_m*l_m ); - double pT_vl = m_nu_px*l_px + m_nu_py*l_py; + // lepton already made by reco or particle levels: + double l_px = m_lepton.Px(); + double l_py = m_lepton.Py(); + double l_pz = m_lepton.Pz(); + double l_m = m_lepton.M(); + double l_E = m_lepton.E(); - double a = l_E*l_E - l_pz*l_pz; - double b = -2. * l_pz * ( mdiff + pT_vl ); - double c = m_met_et*m_met_et*l_E*l_E - mdiff*mdiff - pT_vl*pT_vl - 2.*mdiff*pT_vl; + double mdiff = 0.5 * (mWPDG * mWPDG - l_m * l_m); + double pT_vl = m_nu_px * l_px + m_nu_py * l_py; - delta = b*b - 4.*a*c; + double a = l_E * l_E - l_pz * l_pz; + double b = -2. * l_pz * (mdiff + pT_vl); + double c = m_met_et * m_met_et * l_E * l_E - mdiff * mdiff - pT_vl * pT_vl - 2. * mdiff * pT_vl; - if( delta <= 0. ) { + delta = b * b - 4. * a * c; + + if (delta <= 0.) { // take only the real part - v_pz = -0.5*b/a; + v_pz = -0.5 * b / a; } else { - double v_pz_1 = 0.5 * ( -b - sqrt(delta) ) / a; - double v_pz_2 = 0.5 * ( -b + sqrt(delta) ) / a; - - v_pz = ( fabs(v_pz_1) > fabs(v_pz_2) ) ? v_pz_2 : v_pz_1; - + double v_pz_1 = 0.5 * (-b - sqrt(delta)) / a; + double v_pz_2 = 0.5 * (-b + sqrt(delta)) / a; + + v_pz = (fabs(v_pz_1) > fabs(v_pz_2)) ? v_pz_2 : v_pz_1; } - - double v_E = sqrt( m_met_et*m_met_et + v_pz*v_pz ); - m_neutrino.SetPxPyPzE( m_nu_px, m_nu_py, v_pz, v_E ); - + double v_E = sqrt(m_met_et * m_met_et + v_pz * v_pz); + + m_neutrino.SetPxPyPzE(m_nu_px, m_nu_py, v_pz, v_E); + m_W_lep = m_neutrino + m_lepton; return true; - } - /// Function finalizing the tool - StatusCode PseudoTopReco::finalize() - { + StatusCode PseudoTopReco::finalize() { /// Return gracefully: - return StatusCode::SUCCESS; + return StatusCode::SUCCESS; } - - - - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PseudoTopRecoRun.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PseudoTopRecoRun.cxx index f12493ee40f0..9155eda8cabc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PseudoTopRecoRun.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/PseudoTopRecoRun.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/PseudoTopRecoRun.h" @@ -13,35 +13,28 @@ #include <cmath> #include <fstream> -namespace top{ - +namespace top { PseudoTopRecoRun::PseudoTopRecoRun(const std::string& kLeptonType, std::shared_ptr<top::TopConfig> config) : m_name("RECO::PseudoTopRecoRun_" + kLeptonType), - m_PseudoTopReco(nullptr) - { - - m_PseudoTopReco = std::unique_ptr<top::PseudoTopReco> ( new top::PseudoTopReco( m_name ) ); - top::check( m_PseudoTopReco->setProperty("config", config ), "Failed to setProperty of PseudoTopReco" ); - top::check( m_PseudoTopReco->setProperty("LeptonType", kLeptonType), "Failed to setProperty of PseudoTopReco" ); + m_PseudoTopReco(nullptr) { + m_PseudoTopReco = std::unique_ptr<top::PseudoTopReco> (new top::PseudoTopReco(m_name)); + top::check(m_PseudoTopReco->setProperty("config", config), "Failed to setProperty of PseudoTopReco"); + top::check(m_PseudoTopReco->setProperty("LeptonType", kLeptonType), "Failed to setProperty of PseudoTopReco"); //top::check( m_PseudoTopReco->setProperty("RecoType", kRecoType), "Failed to setProperty of PseudoTopReco" ); - top::check( m_PseudoTopReco->initialize() , "Failed to initialize PseudoTopRecoTool" ); - + top::check(m_PseudoTopReco->initialize(), "Failed to initialize PseudoTopRecoTool"); } - - bool PseudoTopRecoRun::apply(const top::Event& event) const - { - top::check( m_PseudoTopReco->execute(event) , "Failed to run PseudoTopReco" ); + + bool PseudoTopRecoRun::apply(const top::Event& event) const { + top::check(m_PseudoTopReco->execute(event), "Failed to run PseudoTopReco"); return true; } - bool PseudoTopRecoRun::applyParticleLevel(const top::ParticleLevelEvent& plEvent) const - { - top::check( m_PseudoTopReco->execute(plEvent) , "Failed to run PseudoTopReco" ); + bool PseudoTopRecoRun::applyParticleLevel(const top::ParticleLevelEvent& plEvent) const { + top::check(m_PseudoTopReco->execute(plEvent), "Failed to run PseudoTopReco"); return true; } - + std::string PseudoTopRecoRun::name() const { return m_name; - } - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/Sonnenschein.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/Sonnenschein.cxx index 2c774ba9c53c..783e9ba33c65 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/Sonnenschein.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/Sonnenschein.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/Sonnenschein.h" #include "TopEvent/Event.h" @@ -11,63 +11,64 @@ #include <iostream> namespace top { + Sonnenschein::Sonnenschein() { + } -Sonnenschein::Sonnenschein() { -} - -Sonnenschein::~Sonnenschein() { -} + Sonnenschein::~Sonnenschein() { + } -bool Sonnenschein::tWb(const top::Event& event, int start, TLorentzVector& t, TLorentzVector& W, TLorentzVector& b, TLorentzVector& l, TLorentzVector& nu) const { + bool Sonnenschein::tWb(const top::Event& event, int start, TLorentzVector& t, TLorentzVector& W, TLorentzVector& b, + TLorentzVector& l, TLorentzVector& nu) const { bool hasT = false; bool hasB = false; bool hasL = false; bool hasNu = false; for (const xAOD::TruthParticle* particle : *event.m_truth) { - if (particle->pdgId() == start) { - //std::cout << *particle << std::endl; - t = particle->p4(); - hasT = true; - - if (particle->hasDecayVtx()) { - const xAOD::TruthVertex* vtx = particle->decayVtx(); - for (size_t i = 0; i < vtx->nOutgoingParticles(); ++i) { - const xAOD::TruthParticle* tDecayProduct = vtx->outgoingParticle(i); - //std::cout << " " << *tDecayProduct << std::endl; - - if (abs(tDecayProduct->pdgId()) == 24 && tDecayProduct->hasDecayVtx()) { - W = tDecayProduct->p4(); - - const xAOD::TruthVertex* wDecayVtx = tDecayProduct->decayVtx(); - for (size_t j = 0; j < wDecayVtx->nOutgoingParticles(); ++j) { - const xAOD::TruthParticle* wDecayProduct = wDecayVtx->outgoingParticle(j); - //std::cout << " " << *wDecayProduct << std::endl; - - if (abs(wDecayProduct->pdgId()) == 11 || abs(wDecayProduct->pdgId()) == 13 || abs(wDecayProduct->pdgId()) == 15) { - l = wDecayProduct->p4(); - hasL = true; - } - - if (abs(wDecayProduct->pdgId()) == 12 || abs(wDecayProduct->pdgId()) == 14 || abs(wDecayProduct->pdgId()) == 16) { - nu = wDecayProduct->p4(); - hasNu = true; - } - - } - } else if (abs(tDecayProduct->pdgId()) == 5) { - b = tDecayProduct->p4(); - hasB = true; - } + if (particle->pdgId() == start) { + //std::cout << *particle << std::endl; + t = particle->p4(); + hasT = true; + + if (particle->hasDecayVtx()) { + const xAOD::TruthVertex* vtx = particle->decayVtx(); + for (size_t i = 0; i < vtx->nOutgoingParticles(); ++i) { + const xAOD::TruthParticle* tDecayProduct = vtx->outgoingParticle(i); + //std::cout << " " << *tDecayProduct << std::endl; + + if (abs(tDecayProduct->pdgId()) == 24 && tDecayProduct->hasDecayVtx()) { + W = tDecayProduct->p4(); + + const xAOD::TruthVertex* wDecayVtx = tDecayProduct->decayVtx(); + for (size_t j = 0; j < wDecayVtx->nOutgoingParticles(); ++j) { + const xAOD::TruthParticle* wDecayProduct = wDecayVtx->outgoingParticle(j); + //std::cout << " " << *wDecayProduct << std::endl; + + if (abs(wDecayProduct->pdgId()) == 11 || abs(wDecayProduct->pdgId()) == 13 || + abs(wDecayProduct->pdgId()) == 15) { + l = wDecayProduct->p4(); + hasL = true; + } + + if (abs(wDecayProduct->pdgId()) == 12 || abs(wDecayProduct->pdgId()) == 14 || + abs(wDecayProduct->pdgId()) == 16) { + nu = wDecayProduct->p4(); + hasNu = true; } + } + } else if (abs(tDecayProduct->pdgId()) == 5) { + b = tDecayProduct->p4(); + hasB = true; } + } } + } } return hasT && hasB && hasL && hasNu; -} + } -bool Sonnenschein::apply(const top::Event& event) const { + bool Sonnenschein::apply(const top::Event& event) const { TLorentzVector t; TLorentzVector Wp; TLorentzVector b; @@ -83,25 +84,26 @@ bool Sonnenschein::apply(const top::Event& event) const { bool cando2 = tWb(event, -6, tbar, Wm, bbar, lm, nubar); //isn't dilepton at truth level, so return - if (!cando1 || !cando2) - return true; + if (!cando1 || !cando2) return true; const double met_ex = nu.Px() + nubar.Px(); const double met_ey = nu.Py() + nubar.Py(); //solve - std::vector<std::pair<TLorentzVector, TLorentzVector>> allSolutions = m_sonn.solve(lp, b, t.M(), Wp.M(), lm, bbar, tbar.M(), Wm.M(), met_ex, met_ey); + std::vector<std::pair<TLorentzVector, TLorentzVector> > allSolutions = m_sonn.solve(lp, b, t.M(), + Wp.M(), lm, bbar, + tbar.M(), Wm.M(), met_ex, + met_ey); std::cout << "EVENT" << std::endl; unsigned int counter = 0; for (const auto& possible : allSolutions) { - std::cout << "Possible solution number " << counter << "\n"; - std::cout << " first neutrino : " << possible.first << "\n"; - std::cout << " second neutrino: " << possible.second << "\n"; - ++counter; + std::cout << "Possible solution number " << counter << "\n"; + std::cout << " first neutrino : " << possible.first << "\n"; + std::cout << " second neutrino: " << possible.second << "\n"; + ++counter; } return true; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/SonnenscheinEngine.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/SonnenscheinEngine.cxx index aaa2683543a2..7bc789d0bec0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/SonnenscheinEngine.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/SonnenscheinEngine.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/SonnenscheinEngine.h" @@ -11,28 +11,34 @@ #include <cmath> namespace top { - -SonnenscheinEngine::SonnenscheinEngine() : m_debug(false) { -} - -SonnenscheinEngine::~SonnenscheinEngine() { -} - -std::vector<std::pair<TLorentzVector, TLorentzVector> > SonnenscheinEngine::solve(const TLorentzVector& me_t_lp, const TLorentzVector& me_t_b, double mass_t, double mass_wp, const TLorentzVector& me_tbar_lm, const TLorentzVector& me_tbar_bbar, double mass_tbar, double mass_wm, double me_mex, double me_mey) const { + SonnenscheinEngine::SonnenscheinEngine() : m_debug(false) { + } + + SonnenscheinEngine::~SonnenscheinEngine() { + } + + std::vector<std::pair<TLorentzVector, TLorentzVector> > SonnenscheinEngine::solve(const TLorentzVector& me_t_lp, + const TLorentzVector& me_t_b, + double mass_t, double mass_wp, + const TLorentzVector& me_tbar_lm, + const TLorentzVector& me_tbar_bbar, + double mass_tbar, double mass_wm, + double me_mex, + double me_mey) const { std::vector<std::pair<TLorentzVector, TLorentzVector> > lvs; if (m_debug) { - std::cout << "Starting SOLVE\n"; - std::cout << "lp " << me_t_lp << "\n"; - std::cout << "lm " << me_tbar_lm << "\n"; - std::cout << "b " << me_t_b << "\n"; - std::cout << "bbar " << me_tbar_bbar << "\n"; - std::cout << "met_ex " << me_mex << "\n"; - std::cout << "met_ey " << me_mey << "\n"; - std::cout << "mt " << mass_t << "\n"; - std::cout << "mtbar " << mass_tbar << "\n"; - std::cout << "mWp " << mass_wp << "\n"; - std::cout << "mWm " << mass_wm << "\n"; + std::cout << "Starting SOLVE\n"; + std::cout << "lp " << me_t_lp << "\n"; + std::cout << "lm " << me_tbar_lm << "\n"; + std::cout << "b " << me_t_b << "\n"; + std::cout << "bbar " << me_tbar_bbar << "\n"; + std::cout << "met_ex " << me_mex << "\n"; + std::cout << "met_ey " << me_mey << "\n"; + std::cout << "mt " << mass_t << "\n"; + std::cout << "mtbar " << mass_tbar << "\n"; + std::cout << "mWp " << mass_wp << "\n"; + std::cout << "mWm " << mass_wm << "\n"; } const double Elp = me_t_lp.E(); @@ -65,85 +71,85 @@ std::vector<std::pair<TLorentzVector, TLorentzVector> > SonnenscheinEngine::solv const TVector3 pbbar = me_tbar_bbar.Vect(); if (m_debug) { - std::cout << "mex and mey " << me_mex << " " << me_mey << "\n"; - std::cout << "Starting Calculation\n"; - std::cout << "Calculating a\n"; + std::cout << "mex and mey " << me_mex << " " << me_mey << "\n"; + std::cout << "Starting Calculation\n"; + std::cout << "Calculating a\n"; } - double a1 = (Eb + Elp)*(mass_wp * mass_wp - mlp * mlp) - - Elp * (mass_t * mass_t - mb * mb - mlp * mlp) - + 2 * Eb * Elp * Elp - 2 * Elp * pb * plp; + double a1 = (Eb + Elp) * (mass_wp * mass_wp - mlp * mlp) + - Elp * (mass_t * mass_t - mb * mb - mlp * mlp) + + 2 * Eb * Elp * Elp - 2 * Elp * pb * plp; double a2 = 2 * (Eb * plpx - Elp * pbx); double a3 = 2 * (Eb * plpy - Elp * pby); double a4 = 2 * (Eb * plpz - Elp * pbz); if (m_debug) { - std::cout << "a1 : " << a1 << "\n"; - std::cout << "a2 : " << a2 << "\n"; - std::cout << "a3 : " << a3 << "\n"; - std::cout << "a4 : " << a4 << "\n"; - - //double pvx = nu->Px() ; - //double pvy = nu->Py() ; - //double pvz = nu->Pz() ; - //std::cout << a1 + a2 * pvx + a3 * pvy + a4 * pvz << "\n"; + std::cout << "a1 : " << a1 << "\n"; + std::cout << "a2 : " << a2 << "\n"; + std::cout << "a3 : " << a3 << "\n"; + std::cout << "a4 : " << a4 << "\n"; + + //double pvx = nu->Px() ; + //double pvy = nu->Py() ; + //double pvz = nu->Pz() ; + //std::cout << a1 + a2 * pvx + a3 * pvy + a4 * pvz << "\n"; } - double b1 = (Ebbar + Elm)*(mass_wm * mass_wm - mlm * mlm) - - Elm * (mass_tbar * mass_tbar - mbbar * mbbar - mlm * mlm) - + 2 * Ebbar * Elm * Elm - 2 * Elm * pbbar * plm; + double b1 = (Ebbar + Elm) * (mass_wm * mass_wm - mlm * mlm) + - Elm * (mass_tbar * mass_tbar - mbbar * mbbar - mlm * mlm) + + 2 * Ebbar * Elm * Elm - 2 * Elm * pbbar * plm; double b2 = 2 * (Ebbar * plmx - Elm * pbbarx); double b3 = 2 * (Ebbar * plmy - Elm * pbbary); double b4 = 2 * (Ebbar * plmz - Elm * pbbarz); if (m_debug) { - std::cout << "Calculating b\n"; - std::cout << "b1 : " << b1 << "\n"; - std::cout << "b2 : " << b2 << "\n"; - std::cout << "b3 : " << b3 << "\n"; - std::cout << "b4 : " << b4 << "\n"; + std::cout << "Calculating b\n"; + std::cout << "b1 : " << b1 << "\n"; + std::cout << "b2 : " << b2 << "\n"; + std::cout << "b3 : " << b3 << "\n"; + std::cout << "b4 : " << b4 << "\n"; - //std::cout << "Checking b" << "\n"; + //std::cout << "Checking b" << "\n"; - //double pvbarx = nu2->Px() ; - //double pvbary = nu2->Py() ; - //double pvbarz = nu2->Pz() ; + //double pvbarx = nu2->Px() ; + //double pvbary = nu2->Py() ; + //double pvbarz = nu2->Pz() ; - //std::cout << b1 + b2 * pvbarx + b3 * pvbary + b4 * pvbarz << "\n"; + //std::cout << b1 + b2 * pvbarx + b3 * pvbary + b4 * pvbarz << "\n"; - std::cout << "Calculating c\n"; + std::cout << "Calculating c\n"; } double c22 = (mass_wp * mass_wp - mlp * mlp) * (mass_wp * mass_wp - mlp * mlp) - -4 * (Elp * Elp - plpz * plpz) * (a1 / a4) * (a1 / a4) - -4 * (mass_wp * mass_wp - mlp * mlp) * plpz * a1 / a4; + - 4 * (Elp * Elp - plpz * plpz) * (a1 / a4) * (a1 / a4) + - 4 * (mass_wp * mass_wp - mlp * mlp) * plpz * a1 / a4; - double c21 = 4 * (mass_wp * mass_wp - mlp * mlp) * (plpx - plpz * a2 / a4) //? - -8 * (Elp * Elp - plpz * plpz) * a1 * a2 / (a4 * a4) - -8 * plpx * plpz * a1 / a4; + double c21 = 4 * (mass_wp * mass_wp - mlp * mlp) * (plpx - plpz * a2 / a4) //? + - 8 * (Elp * Elp - plpz * plpz) * a1 * a2 / (a4 * a4) + - 8 * plpx * plpz * a1 / a4; double c20 = -4 * (Elp * Elp - plpx * plpx) - -4 * (Elp * Elp - plpz * plpz)*(a2 / a4)*(a2 / a4) - -8 * plpx * plpz * a2 / a4; + - 4 * (Elp * Elp - plpz * plpz) * (a2 / a4) * (a2 / a4) + - 8 * plpx * plpz * a2 / a4; - double c11 = 4 * (mass_wp * mass_wp - mlp * mlp) * (plpy - plpz * a3 / a4) - -8 * (Elp * Elp - plpz * plpz) * a1 * a3 / (a4 * a4) - -8 * plpy * plpz * a1 / a4; + double c11 = 4 * (mass_wp * mass_wp - mlp * mlp) * (plpy - plpz * a3 / a4) + - 8 * (Elp * Elp - plpz * plpz) * a1 * a3 / (a4 * a4) + - 8 * plpy * plpz * a1 / a4; double c10 = -8 * (Elp * Elp - plpz * plpz) * a2 * a3 / (a4 * a4) - +8 * plpx * plpy - -8 * plpx * plpz * a3 / a4 - -8 * plpy * plpz * a2 / a4; + + 8 * plpx * plpy + - 8 * plpx * plpz * a3 / a4 + - 8 * plpy * plpz * a2 / a4; double c00 = -4 * (Elp * Elp - plpy * plpy) - -4 * (Elp * Elp - plpz * plpz) * (a3 / a4) * (a3 / a4) - -8 * plpy * plpz * a3 / a4; + - 4 * (Elp * Elp - plpz * plpz) * (a3 / a4) * (a3 / a4) + - 8 * plpy * plpz * a3 / a4; /* - for cross check - the original paper used these definitions. - similar for dp. + for cross check - the original paper used these definitions. + similar for dp. */ c22 = a4 * a4 * c22; c21 = a4 * a4 * c21; @@ -153,49 +159,49 @@ std::vector<std::pair<TLorentzVector, TLorentzVector> > SonnenscheinEngine::solv c00 = a4 * a4 * c00; if (m_debug) { - std::cout << "c22 : " << c22 << "\n"; - std::cout << "c21 : " << c21 << "\n"; - std::cout << "c20 : " << c20 << "\n"; - std::cout << "c11 : " << c11 << "\n"; - std::cout << "c10 : " << c10 << "\n"; - std::cout << "c00 : " << c00 << "\n"; - - //std::cout "c=0? " << - //c22 - //+ c21 * pvx - //+ c11 * pvy - //+ c20 * pvx * pvx - //+ c10 * pvx * pvy - //+ c00 * pvy * pvy - //<<"\n"; - - std::cout << "Calculating d'\n"; + std::cout << "c22 : " << c22 << "\n"; + std::cout << "c21 : " << c21 << "\n"; + std::cout << "c20 : " << c20 << "\n"; + std::cout << "c11 : " << c11 << "\n"; + std::cout << "c10 : " << c10 << "\n"; + std::cout << "c00 : " << c00 << "\n"; + + //std::cout "c=0? " << + //c22 + //+ c21 * pvx + //+ c11 * pvy + //+ c20 * pvx * pvx + //+ c10 * pvx * pvy + //+ c00 * pvy * pvy + //<<"\n"; + + std::cout << "Calculating d'\n"; } - double dp22 = pow( mass_wm * mass_wm - mlm * mlm, 2) - -4 * (Elm * Elm - plmz * plmz) * (b1 / b4) * (b1 / b4) - -4 * (mass_wm * mass_wm - mlm * mlm) * plmz * b1 / b4; + double dp22 = pow(mass_wm * mass_wm - mlm * mlm, 2) + - 4 * (Elm * Elm - plmz * plmz) * (b1 / b4) * (b1 / b4) + - 4 * (mass_wm * mass_wm - mlm * mlm) * plmz * b1 / b4; - double dp21 = 4 * (mass_wm * mass_wm - mlm * mlm) * (plmx - plmz * b2 / b4) - -8 * (Elm * Elm - plmz * plmz) * b1 * b2 / (b4 * b4) - -8 * plmx * plmz * b1 / b4; + double dp21 = 4 * (mass_wm * mass_wm - mlm * mlm) * (plmx - plmz * b2 / b4) + - 8 * (Elm * Elm - plmz * plmz) * b1 * b2 / (b4 * b4) + - 8 * plmx * plmz * b1 / b4; double dp20 = -4 * (Elm * Elm - plmx * plmx) - -4 * (Elm * Elm - plmz * plmz)*(b2 / b4)*(b2 / b4) - -8 * plmx * plmz * b2 / b4; + - 4 * (Elm * Elm - plmz * plmz) * (b2 / b4) * (b2 / b4) + - 8 * plmx * plmz * b2 / b4; - double dp11 = 4 * (mass_wm * mass_wm - mlm * mlm) * (plmy - plmz * b3 / b4) - -8 * (Elm * Elm - plmz * plmz) * b1 * b3 / (b4 * b4) - -8 * plmy * plmz * b1 / b4; + double dp11 = 4 * (mass_wm * mass_wm - mlm * mlm) * (plmy - plmz * b3 / b4) + - 8 * (Elm * Elm - plmz * plmz) * b1 * b3 / (b4 * b4) + - 8 * plmy * plmz * b1 / b4; double dp10 = -8 * (Elm * Elm - plmz * plmz) * b2 * b3 / (b4 * b4) - +8 * plmx * plmy - -8 * plmx * plmz * b3 / b4 - -8 * plmy * plmz * b2 / b4; + + 8 * plmx * plmy + - 8 * plmx * plmz * b3 / b4 + - 8 * plmy * plmz * b2 / b4; double dp00 = -4 * (Elm * Elm - plmy * plmy) - -4 * (Elm * Elm - plmz * plmz) * (b3 / b4) * (b3 / b4) - -8 * plmy * plmz * b3 / b4; + - 4 * (Elm * Elm - plmz * plmz) * (b3 / b4) * (b3 / b4) + - 8 * plmy * plmz * b3 / b4; dp22 = b4 * b4 * dp22; dp21 = b4 * b4 * dp21; @@ -205,195 +211,193 @@ std::vector<std::pair<TLorentzVector, TLorentzVector> > SonnenscheinEngine::solv dp00 = b4 * b4 * dp00; if (m_debug) { - std::cout << "dp22 : " << dp22 << "\n"; - std::cout << "dp21 : " << dp21 << "\n"; - std::cout << "dp20 : " << dp20 << "\n"; - std::cout << "dp11 : " << dp11 << "\n"; - std::cout << "dp10 : " << dp10 << "\n"; - std::cout << "dp00 : " << dp00 << "\n"; - - //in the paper for c and dp c21 appears twice. is this right? - //std::cout << "dp=0? " << - //dp22 - //+ dp21 * pvbarx - //+ dp11 * pvbary - //+ dp20 * pvbarx * pvbarx - //+ dp10 * pvbarx * pvbary - //+ dp00 * pvbary * pvbary - //<<"\n"; - - std::cout << "Calculating d\n"; + std::cout << "dp22 : " << dp22 << "\n"; + std::cout << "dp21 : " << dp21 << "\n"; + std::cout << "dp20 : " << dp20 << "\n"; + std::cout << "dp11 : " << dp11 << "\n"; + std::cout << "dp10 : " << dp10 << "\n"; + std::cout << "dp00 : " << dp00 << "\n"; + + //in the paper for c and dp c21 appears twice. is this right? + //std::cout << "dp=0? " << + //dp22 + //+ dp21 * pvbarx + //+ dp11 * pvbary + //+ dp20 * pvbarx * pvbarx + //+ dp10 * pvbarx * pvbary + //+ dp00 * pvbary * pvbary + //<<"\n"; + + std::cout << "Calculating d\n"; } const double d22 = dp22 - + me_mex * me_mex * dp20 - + me_mey * me_mey * dp00 - + me_mex * me_mey * dp10 - + me_mex * dp21 - + me_mey * dp11; + + me_mex * me_mex * dp20 + + me_mey * me_mey * dp00 + + me_mex * me_mey * dp10 + + me_mex * dp21 + + me_mey * dp11; const double d21 = -1 * dp21 - -2 * me_mex * dp20 - - me_mey * dp10; + - 2 * me_mex * dp20 + - me_mey * dp10; const double d20 = dp20; const double d11 = -1 * dp11 - - 2 * me_mey * dp00 - - me_mex * dp10; + - 2 * me_mey * dp00 + - me_mex * dp10; const double d10 = dp10; const double d00 = dp00; if (m_debug) { - std::cout << "d22 : " << d22 << "\n"; - std::cout << "d21 : " << d21 << "\n"; - std::cout << "d20 : " << d20 << "\n"; - std::cout << "d11 : " << d11 << "\n"; - std::cout << "d10 : " << d10 << "\n"; - std::cout << "d00 : " << d00 << "\n"; - - //std::cout << "d " << - //d22 - //+d21 * pvx - //+d11 * pvy - //+d20 * pvx * pvx - //+d10 * pvx * pvy - //+d00 * pvy * pvy - //<< "\n"; - - std::cout << "Calculating h\n"; + std::cout << "d22 : " << d22 << "\n"; + std::cout << "d21 : " << d21 << "\n"; + std::cout << "d20 : " << d20 << "\n"; + std::cout << "d11 : " << d11 << "\n"; + std::cout << "d10 : " << d10 << "\n"; + std::cout << "d00 : " << d00 << "\n"; + + //std::cout << "d " << + //d22 + //+d21 * pvx + //+d11 * pvy + //+d20 * pvx * pvx + //+d10 * pvx * pvy + //+d00 * pvy * pvy + //<< "\n"; + + std::cout << "Calculating h\n"; } const double h4 = c00 * c00 * d22 * d22 - + c11 * d22 * (c11 * d00 - c00 * d11) - + c00 * c22 * (d11 * d11 - 2 * d00 * d22) - + c22 * d00 * (c22 * d00 - c11 * d11); + + c11 * d22 * (c11 * d00 - c00 * d11) + + c00 * c22 * (d11 * d11 - 2 * d00 * d22) + + c22 * d00 * (c22 * d00 - c11 * d11); const double h3 = c00 * d21 * (2 * c00 * d22 - c11 * d11) - + c00 * d11 * (2 * c22 * d10 + c21 * d11) - + c22 * d00 * (2 * c21 * d00 - c11 * d10) - - c00 * d22 * (c11 * d10 + c10 * d11) - -2 * c00 * d00 *(c22 * d21 + c21 * d22) - - d00 * d11 * (c11 * c21 + c10 * c22) - + c11 * d00 * (c11 * d21 + 2 * c10 * d22); + + c00 * d11 * (2 * c22 * d10 + c21 * d11) + + c22 * d00 * (2 * c21 * d00 - c11 * d10) + - c00 * d22 * (c11 * d10 + c10 * d11) + - 2 * c00 * d00 * (c22 * d21 + c21 * d22) + - d00 * d11 * (c11 * c21 + c10 * c22) + + c11 * d00 * (c11 * d21 + 2 * c10 * d22); const double h2 = c00 * c00 * (2 * d22 * d20 + d21 * d21) - - c00 * d21 * (c11 * d10 + c10 * d11) - + c11 * d20 * (c11 * d00 - c00 * d11) - + c00 * d10 * (c22 * d10 - c10 * d22) - + c00 * d11 * (2 * c21 * d10 + c20 * d11) - + (2 * c22 * c20 + c21 * c21) * d00 * d00 - - 2 * c00 * d00 * (c22 * d20 + c21 * d21 + c20 * d22) - + c10 * d00 * (2 * c11 * d21 + c10 * d22) - - d00 * d10 * (c11 * c21 + c10 * c22) - - d00 * d11 * (c11 * c20 + c10 * c21); + - c00 * d21 * (c11 * d10 + c10 * d11) + + c11 * d20 * (c11 * d00 - c00 * d11) + + c00 * d10 * (c22 * d10 - c10 * d22) + + c00 * d11 * (2 * c21 * d10 + c20 * d11) + + (2 * c22 * c20 + c21 * c21) * d00 * d00 + - 2 * c00 * d00 * (c22 * d20 + c21 * d21 + c20 * d22) + + c10 * d00 * (2 * c11 * d21 + c10 * d22) + - d00 * d10 * (c11 * c21 + c10 * c22) + - d00 * d11 * (c11 * c20 + c10 * c21); /* * leave! */ /* - double h1 = c00 * d21 * (2 * c00 * d20 - c10 * d10) - - c00 * d20 * (c11 * d10 + c10 * d11) - + c00 * d10 * (c21 * d10 + 2 * c20 * d11) - -2 * c00 * d00 * (c21 * d20 + c20 * d21) - + c10 * d00 * (2 * c11 * d20 + c10 * d21) - - c20 * d00 * (2 * c21 * d00 - c10 * d11) - - d00 * d10 * (c11 * c20 + c10 * c21); + double h1 = c00 * d21 * (2 * c00 * d20 - c10 * d10) + - c00 * d20 * (c11 * d10 + c10 * d11) + + c00 * d10 * (c21 * d10 + 2 * c20 * d11) + -2 * c00 * d00 * (c21 * d20 + c20 * d21) + + c10 * d00 * (2 * c11 * d20 + c10 * d21) + - c20 * d00 * (2 * c21 * d00 - c10 * d11) + - d00 * d10 * (c11 * c20 + c10 * c21); */ const double h1 = c00 * d21 * (2 * c00 * d20 - c10 * d10) - - c00 * d20 * (c11 * d10 + c10 * d11) - + c00 * d10 * (c21 * d10 + 2 * c20 * d11) - -2 * c00 * d00 * (c21 * d20 + c20 * d21) - + c10 * d00 * (2 * c11 * d20 + c10 * d21) - + c20 * d00 * (2 * c21 * d00 - c10 * d11) - - d00 * d10 * (c11 * c20 + c10 * c21); + - c00 * d20 * (c11 * d10 + c10 * d11) + + c00 * d10 * (c21 * d10 + 2 * c20 * d11) + - 2 * c00 * d00 * (c21 * d20 + c20 * d21) + + c10 * d00 * (2 * c11 * d20 + c10 * d21) + + c20 * d00 * (2 * c21 * d00 - c10 * d11) + - d00 * d10 * (c11 * c20 + c10 * c21); const double h0 = c00 * c00 * d20 * d20 - + c10 * d20 * (c10 * d00 - c00 * d10) - + c20 * d10 * (c00 * d10 - c10 * d00) - + c20 * d00 * (c20 * d00 - 2 * c00 * d20); + + c10 * d20 * (c10 * d00 - c00 * d10) + + c20 * d10 * (c00 * d10 - c10 * d00) + + c20 * d00 * (c20 * d00 - 2 * c00 * d20); if (m_debug) { - std::cout << "h4 : " << h4 << "\n"; - std::cout << "h3 : " << h3 << "\n"; - std::cout << "h2 : " << h2 << "\n"; - std::cout << "h1 : " << h1 << "\n"; - std::cout << "h0 : " << h0 << "\n"; + std::cout << "h4 : " << h4 << "\n"; + std::cout << "h3 : " << h3 << "\n"; + std::cout << "h2 : " << h2 << "\n"; + std::cout << "h1 : " << h1 << "\n"; + std::cout << "h0 : " << h0 << "\n"; - std::cout << "Messy Calculate Over\n"; + std::cout << "Messy Calculate Over\n"; - //function is h0 pvx ^4 + h1 pvx ^3 + h2 pvx ^2 + h3 pvx + h4 + //function is h0 pvx ^4 + h1 pvx ^3 + h2 pvx ^2 + h3 pvx + h4 - std::cout << "gnuplot command\n"; + std::cout << "gnuplot command\n"; - std::stringstream s; - s << h0/h0 << "*x*x*x*x + " << - h1/h0 << "*x*x*x + " << - h2/h0<< "*x*x + " << - h3/h0 << "*x + " << h4/h0; + std::stringstream s; + s << h0 / h0 << "*x*x*x*x + " << + h1 / h0 << "*x*x*x + " << + h2 / h0 << "*x*x + " << + h3 / h0 << "*x + " << h4 / h0; - std::string fn = s.str(); + std::string fn = s.str(); - std::cout << "plot " << fn << "\n"; + std::cout << "plot " << fn << "\n"; } std::vector<double> pvxs = solveQuartic(h0, h1, h2, h3, h4); if (m_debug) { - std::cout << "--------------------------\n"; - std::cout << "Kinematic Solutions\n"; + std::cout << "--------------------------\n"; + std::cout << "Kinematic Solutions\n"; } int num = 0; for (std::vector<double>::const_iterator it = pvxs.begin(); it != pvxs.end(); ++it, ++num) { - double pvx = *it; + double pvx = *it; - double pvbarx = me_mex - *it; + double pvbarx = me_mex - *it; - double c0 = c00; - double d0 = d00; + double c0 = c00; + double d0 = d00; - double c1 = c10 * pvx + c11; - double c2 = c20 * pvx * pvx + c21 * pvx + c22; + double c1 = c10 * pvx + c11; + double c2 = c20 * pvx * pvx + c21 * pvx + c22; - double d1 = d10 * pvx + d11; - double d2 = d20 * pvx * pvx + d21 * pvx + d22; + double d1 = d10 * pvx + d11; + double d2 = d20 * pvx * pvx + d21 * pvx + d22; - double pvy = (c0 * d2 - c2 * d0) / (c1 * d0 - c0 * d1); - double pvbary = me_mey - pvy; + double pvy = (c0 * d2 - c2 * d0) / (c1 * d0 - c0 * d1); + double pvbary = me_mey - pvy; - double pvz = (a1 + a2 * pvx + a3 * pvy) / (-a4); - double pvbarz = (b1 + b2 * pvbarx + b3 * pvbary) / (-b4); + double pvz = (a1 + a2 * pvx + a3 * pvy) / (-a4); + double pvbarz = (b1 + b2 * pvbarx + b3 * pvbary) / (-b4); - double pvE = sqrt(pvx*pvx + pvy*pvy + pvz*pvz); - double pvbarE = sqrt(pvbarx*pvbarx + pvbary*pvbary + pvbarz*pvbarz); + double pvE = sqrt(pvx * pvx + pvy * pvy + pvz * pvz); + double pvbarE = sqrt(pvbarx * pvbarx + pvbary * pvbary + pvbarz * pvbarz); - TLorentzVector tlv1(pvx,pvy,pvz,pvE); - TLorentzVector tlv2(pvbarx,pvbary,pvbarz,pvbarE); + TLorentzVector tlv1(pvx, pvy, pvz, pvE); + TLorentzVector tlv2(pvbarx, pvbary, pvbarz, pvbarE); - if (m_debug) { - std::cout << "Solution " << num << "\n"; - std::cout << tlv1 << std::endl; - std::cout << tlv2 << std::endl; - std::cout << "----------" << "\n"; - } + if (m_debug) { + std::cout << "Solution " << num << "\n"; + std::cout << tlv1 << std::endl; + std::cout << tlv2 << std::endl; + std::cout << "----------" << "\n"; + } - std::pair<TLorentzVector, TLorentzVector> p(tlv1,tlv2); + std::pair<TLorentzVector, TLorentzVector> p(tlv1, tlv2); - lvs.push_back(p); + lvs.push_back(p); } - if (m_debug) - std::cout << "Finished Kinematic Solution" << "\n"; + if (m_debug) std::cout << "Finished Kinematic Solution" << "\n"; return lvs; -} + } -std::vector<double> SonnenscheinEngine::solveQuartic(double h0, double h1, double h2, double h3, double h4) const { - if (m_debug) - std::cout << "Solve Quartic\n"; + std::vector<double> SonnenscheinEngine::solveQuartic(double h0, double h1, double h2, double h3, double h4) const { + if (m_debug) std::cout << "Solve Quartic\n"; //normalise to coefficient of highest order. const double nh1 = h1 / h0; @@ -407,130 +411,120 @@ std::vector<double> SonnenscheinEngine::solveQuartic(double h0, double h1, doubl const double k3 = nh4 - 3 * pow(nh1, 4) / 256. + nh1 * nh1 * nh2 / 16. - nh1 * nh3 / 4.; if (m_debug) { - std::cout << "e " << k1 << "\n"; - std::cout << "f " << k2 << "\n"; - std::cout << "g " << k3 << "\n"; + std::cout << "e " << k1 << "\n"; + std::cout << "f " << k2 << "\n"; + std::cout << "g " << k3 << "\n"; } - std::vector<double> sols = solveCubic(2. * k1, k1 * k1 -4. * k3, -k2 * k2); + std::vector<double> sols = solveCubic(2. * k1, k1 * k1 - 4. * k3, -k2 * k2); //using the solutions from above... double t1 = -1.; for (std::vector<double>::const_iterator it = sols.begin(); it != sols.end(); ++it) { - if (*it > 0.) - t1 = sqrt(*it); + if (*it > 0.) t1 = sqrt(*it); } //we just need one positive root to get the other roots... double t2 = (k1 + t1 * t1 - k2 / t1) / 2.; - if (m_debug) - std::cout << "first quadratic\n"; + if (m_debug) std::cout << "first quadratic\n"; std::vector<double> s1 = solveQuadratic(1., t1, t2); std::vector<double> pvxs; for (std::vector<double>::const_iterator it = s1.begin(); it != s1.end(); ++it) { + if (m_debug) std::cout << "pvx " << *it - nh1 / 4. << "\n"; - if (m_debug) - std::cout << "pvx " << *it - nh1 / 4. << "\n"; - - pvxs.push_back(*it - nh1 / 4.); + pvxs.push_back(*it - nh1 / 4.); } //now use the other quadratic - if (m_debug) - std::cout << "second quadratic\n"; + if (m_debug) std::cout << "second quadratic\n"; std::vector<double> s2 = solveQuadratic(1., -t1, k3 / t2); for (std::vector<double>::const_iterator it = s2.begin(); it != s2.end(); ++it) { - if (m_debug) - std::cout << "pvx " << *it - nh1 / 4. << "\n"; + if (m_debug) std::cout << "pvx " << *it - nh1 / 4. << "\n"; - pvxs.push_back(*it - nh1 / 4.); + pvxs.push_back(*it - nh1 / 4.); } return pvxs; -} + } -std::vector<double> SonnenscheinEngine::solveCubic(double s1, double s2, double s3) const { + std::vector<double> SonnenscheinEngine::solveCubic(double s1, double s2, double s3) const { std::vector<double> sols; const double q = (s1 * s1 - 3 * s2) / 9.; const double r = (2 * s1 * s1 * s1 - 9 * s1 * s2 + 27 * s3) / 54.; if (m_debug) { - std::cout << "Solve Cubic\n"; - std::cout << "q " << q << "\n"; - std::cout << "r " << r << "\n"; + std::cout << "Solve Cubic\n"; + std::cout << "q " << q << "\n"; + std::cout << "r " << r << "\n"; } - if (r*r < q*q*q) { - const double theta = acos(r / sqrt(q*q*q) ); - const double z1_1 = -2 * sqrt(q) * cos(theta / 3.) - s1 / 3.; - const double z1_2 = -2 * sqrt(q) * cos((theta + 2 * M_PI) / 3.) - s1 / 3.; - const double z1_3 = -2 * sqrt(q) * cos((theta - 2 * M_PI) / 3.) - s1 / 3.; - - if (m_debug) { - std::cout << "r^2 < q^3 -> 3 solutions\n"; - std::cout << "z1_1 " << z1_1 << "\n"; - std::cout << "z1_2 " << z1_2 << "\n"; - std::cout << "z1_3 " << z1_3 << "\n"; - } - - sols.push_back(z1_1); - sols.push_back(z1_2); - sols.push_back(z1_3); + if (r * r < q * q * q) { + const double theta = acos(r / sqrt(q * q * q)); + const double z1_1 = -2 * sqrt(q) * cos(theta / 3.) - s1 / 3.; + const double z1_2 = -2 * sqrt(q) * cos((theta + 2 * M_PI) / 3.) - s1 / 3.; + const double z1_3 = -2 * sqrt(q) * cos((theta - 2 * M_PI) / 3.) - s1 / 3.; + + if (m_debug) { + std::cout << "r^2 < q^3 -> 3 solutions\n"; + std::cout << "z1_1 " << z1_1 << "\n"; + std::cout << "z1_2 " << z1_2 << "\n"; + std::cout << "z1_3 " << z1_3 << "\n"; + } + + sols.push_back(z1_1); + sols.push_back(z1_2); + sols.push_back(z1_3); } else { - if (m_debug) - std::cout << "r^2 >= q^3 -> 1 solution" << "\n"; + if (m_debug) std::cout << "r^2 >= q^3 -> 1 solution" << "\n"; - const double radicant = -r + sqrt( r * r - q * q * q); - const double powthrd = pow( fabs(radicant), 1./3.); - const double a = sign(radicant) * powthrd; //sign?? - //double b = (a!=0.) ? q/a : 0.; - const double b = q / a; + const double radicant = -r + sqrt(r * r - q * q * q); + const double powthrd = pow(fabs(radicant), 1. / 3.); + const double a = sign(radicant) * powthrd; //sign?? + //double b = (a!=0.) ? q/a : 0.; + const double b = q / a; - const double z1_1 = a + b - s1 /3.; - //std::cout << "z1_1 " << z1_1 << "\n"; + const double z1_1 = a + b - s1 / 3.; + //std::cout << "z1_1 " << z1_1 << "\n"; - sols.push_back(z1_1); + sols.push_back(z1_1); } return sols; -} + } -std::vector<double> SonnenscheinEngine::solveQuadratic(double a, double b, double c) const { + std::vector<double> SonnenscheinEngine::solveQuadratic(double a, double b, double c) const { std::vector<double> sols; - if (m_debug) - std::cout << "Solve Quadratic\n"; + if (m_debug) std::cout << "Solve Quadratic\n"; const double b2m4ac = b * b - 4. * a * c; if (b2m4ac > 0.) { - const double sol1 = (-b + sqrt(b2m4ac)) / 2. * a; - const double sol2 = (-b - sqrt(b2m4ac)) / 2. * a; + const double sol1 = (-b + sqrt(b2m4ac)) / 2. * a; + const double sol2 = (-b - sqrt(b2m4ac)) / 2. * a; - if (m_debug) { - std::cout << "Quadratic sol1 : " << sol1 << "\n"; - std::cout << "Quadratic sol2 : " << sol2 << "\n"; - } + if (m_debug) { + std::cout << "Quadratic sol1 : " << sol1 << "\n"; + std::cout << "Quadratic sol2 : " << sol2 << "\n"; + } - sols.push_back(sol1); - sols.push_back(sol2); - } else if (m_debug) - std::cout << "Quadratic has no solutions\n"; + sols.push_back(sol1); + sols.push_back(sol2); + } else if (m_debug) std::cout << "Quadratic has no solutions\n"; return sols; -} + } -double SonnenscheinEngine::sign(double a) const { + double SonnenscheinEngine::sign(double a) const { return (a < 0) ? -1 : (a > 0) ? 1 : 0; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TopEventReconstructionToolsLoader.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TopEventReconstructionToolsLoader.cxx index 62a25e3470ff..808d0a1c4b12 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TopEventReconstructionToolsLoader.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TopEventReconstructionToolsLoader.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventReconstructionTools/TopEventReconstructionToolsLoader.h" #include "TopEventReconstructionTools/Sonnenschein.h" @@ -11,8 +11,10 @@ #include "TopAnalysis/Tools.h" //for the loadLibraries function namespace top { - -top::EventSelectorBase* TopEventReconstructionToolsLoader::initTool(const std::string& /*name*/, const std::string& line, TFile* /*outputFile*/,std::shared_ptr<top::TopConfig> config, EL::Worker* /*wk*/) { + top::EventSelectorBase* TopEventReconstructionToolsLoader::initTool(const std::string& name, const std::string& line, + TFile* /*outputFile*/, + std::shared_ptr<top::TopConfig> config, + EL::Worker* /*wk*/) { //get the first bit of the string and store it in toolname std::istringstream iss(line); std::string toolname; @@ -20,23 +22,18 @@ top::EventSelectorBase* TopEventReconstructionToolsLoader::initTool(const std::s //any parameters? std::string param; - if (line.size() > toolname.size()) - param = line.substr(toolname.size() + 1); + if (line.size() > toolname.size()) param = line.substr(toolname.size() + 1); - if (toolname == "RECO::SONNENSCHEIN") - return new top::Sonnenschein(); + if (toolname == "RECO::SONNENSCHEIN") return new top::Sonnenschein(); else if (toolname == "RECO::KLFITTERRUN") { loadLibraries("libKLFitter"); - return new top::KLFitterRun(param,config); - } - - else if (toolname == "RECO::PSEUDOTOP"){ + return new top::KLFitterRun(name, param, config); + } else if (toolname == "RECO::PSEUDOTOP") { return new top::PseudoTopRecoRun(param, config); } return nullptr; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresChi2.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresChi2.cxx index e991d93320ab..41af802ea11d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresChi2.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresChi2.cxx @@ -1,164 +1,164 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ /* ********************************************************************** - * Class : TTBarLeptonJetsBuilder_chi2 - * Author : LPC-ClermontFerrand team - ************************************************************************/ +* Class : TTBarLeptonJetsBuilder_chi2 +* Author : LPC-ClermontFerrand team +************************************************************************/ #include "TopEventReconstructionTools/TtresChi2.h" #include "TopEventReconstructionTools/TtresNeutrinoBuilder.h" //_________________________________________________________________________________________________ -TtresChi2::TtresChi2(std::string units){ +TtresChi2::TtresChi2(std::string units) { m_debug = 0; m_WReco = ROTATION; - if (units=="MeV")m_Units = 1000.; - else if(units=="GeV")m_Units = 1.; + if (units == "MeV") m_Units = 1000.; + else if (units == "GeV") m_Units = 1.; else std::cerr << "WARNING in TtresChi2: units different from GeV or MeV" << std::endl; m_UsePtDiff = PTDIFF; m_Btag = AFFECTBTAG; m_RunMode = RUNDEFAULT; m_NeutrinoBuilder = new TtresNeutrinoBuilder(units); Init(DATA2012SUMMER2013PT100); - res_chi2All = -1.; - res_chi2WH = -1.; + res_chi2All = -1.; + res_chi2WH = -1.; res_chi2TopH = -1.; res_chi2TopL = -1.; - res_Mtl = -1.; - res_Mwh = -1.; - res_Mth = -1.; - res_Mtt = -1.; - m_WhChi2Value = -1; - m_ThWhChi2Value = -1; - m_TlChi2Value = -1; + res_Mtl = -1.; + res_Mwh = -1.; + res_Mth = -1.; + res_Mtt = -1.; + m_WhChi2Value = -1; + m_ThWhChi2Value = -1; + m_TlChi2Value = -1; m_PtDiffChi2Value = -1; - m_category = -1; + m_category = -1; } //_________________________________________________________________________________________________ -TtresChi2::~TtresChi2(){ - if(m_debug>0) std::cout << "in destructor " << std::endl; +TtresChi2::~TtresChi2() { + if (m_debug > 0) std::cout << "in destructor " << std::endl; if (m_NeutrinoBuilder) delete m_NeutrinoBuilder; } //_________________________________________________________________________________________________ void TtresChi2::Init(Chi2Version version, double highJetMass) { - m_highJetMass = highJetMass; - switch (version){ - - case DATA2012SUMMER2013PT100: - //Rel17.2: values obtained for Z' 0.5TeV-2 TeV including njets>=5 events - // LC jets + Jet Area correction - // Applying a cut at 100 GeV on the pT of the leading jet - MjjP=82.74*m_Units; - SMjjP=9.524*m_Units; - - m_TopMinusW_had_mean=89.99*m_Units; - m_TopMinusW_had_sigma=13.91*m_Units; - - m_Top_lep_mean=166.6*m_Units; - m_Top_lep_sigma=17.34*m_Units; - - m_PtDiff_mean=-1.903*m_Units; - m_PtDiff_sigma=47.24*m_Units; - - m_PtDiffRel_mean=0.002678; - m_PtDiffRel_sigma=0.07662; - - m_PtDiffRelMass_mean=0.001315; - m_PtDiffRelMass_sigma=0.05092; - - MTHJJ=171.8*m_Units; - STHJJ=16.04*m_Units; - break; - - case DATA2012SUMMER2013: - //Rel17.2: values obtained for Z' 0.5TeV-2 TeV including njets>=5 events - // LC jets + Jet Area correction - MjjP=82.41*m_Units; - SMjjP=9.553*m_Units; - - m_TopMinusW_had_mean=89.01*m_Units; - m_TopMinusW_had_sigma=15.67*m_Units; - - m_Top_lep_mean=166*m_Units; - m_Top_lep_sigma=17.48*m_Units; - - m_PtDiff_mean=0.4305*m_Units; - m_PtDiff_sigma=46.07*m_Units; - - m_PtDiffRel_mean=0.00144; - m_PtDiffRel_sigma=0.07837; - - m_PtDiffRelMass_mean=0.0004532; - m_PtDiffRelMass_sigma=0.05112; - - MTHJJ=171.8*m_Units; - STHJJ=16.04*m_Units; - break; - case DATA2012AUTOMN2012: - //Rel17.2: values obtained for Z' 0.5TeV-2 TeV including njets>=5 events - // LC jets - MjjP=83.93*m_Units; - SMjjP=10.76*m_Units; - - m_TopMinusW_had_mean=91.05*m_Units; - m_TopMinusW_had_sigma=14.23*m_Units; - - m_Top_lep_mean=168.2*m_Units; - m_Top_lep_sigma=20.57*m_Units; - - m_PtDiff_mean=-8.709*m_Units; - m_PtDiff_sigma=55.*m_Units; - - MTHJJ=173.5*m_Units; - STHJJ=16.25*m_Units; - break; - - case DATA2011SUMMER2012: - //Rel17.0: values obtained for Z' 1TeV-2 TeV including njets>=5 events - // EM+JES jets - MjjP=83.18*m_Units; - SMjjP=10.67*m_Units; - - m_TopMinusW_had_mean=90.87*m_Units; - m_TopMinusW_had_sigma=12.78*m_Units; - - m_Top_lep_mean=167.6*m_Units; - m_Top_lep_sigma=20.53*m_Units; - - m_PtDiff_mean=-7.381*m_Units; - m_PtDiff_sigma=63.96*m_Units; - - MTHJJ=172.2*m_Units; - STHJJ=16.8*m_Units; - break; - default: - std::cerr << "TtresChi2::Init chi2 is not defined!!" << std::endl; - break; + switch (version) { + case DATA2012SUMMER2013PT100: + //Rel17.2: values obtained for Z' 0.5TeV-2 TeV including njets>=5 events + // LC jets + Jet Area correction + // Applying a cut at 100 GeV on the pT of the leading jet + MjjP = 82.74 * m_Units; + SMjjP = 9.524 * m_Units; + + m_TopMinusW_had_mean = 89.99 * m_Units; + m_TopMinusW_had_sigma = 13.91 * m_Units; + + m_Top_lep_mean = 166.6 * m_Units; + m_Top_lep_sigma = 17.34 * m_Units; + + m_PtDiff_mean = -1.903 * m_Units; + m_PtDiff_sigma = 47.24 * m_Units; + + m_PtDiffRel_mean = 0.002678; + m_PtDiffRel_sigma = 0.07662; + + m_PtDiffRelMass_mean = 0.001315; + m_PtDiffRelMass_sigma = 0.05092; + + MTHJJ = 171.8 * m_Units; + STHJJ = 16.04 * m_Units; + break; + + case DATA2012SUMMER2013: + //Rel17.2: values obtained for Z' 0.5TeV-2 TeV including njets>=5 events + // LC jets + Jet Area correction + MjjP = 82.41 * m_Units; + SMjjP = 9.553 * m_Units; + + m_TopMinusW_had_mean = 89.01 * m_Units; + m_TopMinusW_had_sigma = 15.67 * m_Units; + + m_Top_lep_mean = 166 * m_Units; + m_Top_lep_sigma = 17.48 * m_Units; + + m_PtDiff_mean = 0.4305 * m_Units; + m_PtDiff_sigma = 46.07 * m_Units; + + m_PtDiffRel_mean = 0.00144; + m_PtDiffRel_sigma = 0.07837; + + m_PtDiffRelMass_mean = 0.0004532; + m_PtDiffRelMass_sigma = 0.05112; + + MTHJJ = 171.8 * m_Units; + STHJJ = 16.04 * m_Units; + break; + + case DATA2012AUTOMN2012: + //Rel17.2: values obtained for Z' 0.5TeV-2 TeV including njets>=5 events + // LC jets + MjjP = 83.93 * m_Units; + SMjjP = 10.76 * m_Units; + + m_TopMinusW_had_mean = 91.05 * m_Units; + m_TopMinusW_had_sigma = 14.23 * m_Units; + + m_Top_lep_mean = 168.2 * m_Units; + m_Top_lep_sigma = 20.57 * m_Units; + + m_PtDiff_mean = -8.709 * m_Units; + m_PtDiff_sigma = 55. * m_Units; + + MTHJJ = 173.5 * m_Units; + STHJJ = 16.25 * m_Units; + break; + + case DATA2011SUMMER2012: + //Rel17.0: values obtained for Z' 1TeV-2 TeV including njets>=5 events + // EM+JES jets + MjjP = 83.18 * m_Units; + SMjjP = 10.67 * m_Units; + + m_TopMinusW_had_mean = 90.87 * m_Units; + m_TopMinusW_had_sigma = 12.78 * m_Units; + + m_Top_lep_mean = 167.6 * m_Units; + m_Top_lep_sigma = 20.53 * m_Units; + + m_PtDiff_mean = -7.381 * m_Units; + m_PtDiff_sigma = 63.96 * m_Units; + + MTHJJ = 172.2 * m_Units; + STHJJ = 16.8 * m_Units; + break; + + default: + std::cerr << "TtresChi2::Init chi2 is not defined!!" << std::endl; + break; } return; } //_________________________________________________________________________________________________ -void TtresChi2::Reset(){ - res_chi2All = -1.; - res_chi2WH = -1.; +void TtresChi2::Reset() { + res_chi2All = -1.; + res_chi2WH = -1.; res_chi2TopH = -1.; res_chi2TopL = -1.; - res_Mwh = -1.; - res_Mth = -1.; - res_Mtl = -1.; - res_Mtt = -1.; - m_WhChi2Value = -1; - m_ThWhChi2Value = -1; - m_TlChi2Value = -1; + res_Mwh = -1.; + res_Mth = -1.; + res_Mtl = -1.; + res_Mtt = -1.; + m_WhChi2Value = -1; + m_ThWhChi2Value = -1; + m_TlChi2Value = -1; m_PtDiffChi2Value = -1; - m_category = -1; + m_category = -1; m_nChi2Values = 0; m_chi2Values.clear(); m_chi2Wh_Values.clear(); @@ -175,7 +175,7 @@ void TtresChi2::Reset(){ m_Wh_Values.clear(); m_ThWh_Values.clear(); m_Th_Values.clear(); - m_Tl_Values.clear(); + m_Tl_Values.clear(); m_chi2Values.reserve(10000); m_chi2Wh_Values.reserve(10000); m_chi2Th_Values.reserve(10000); @@ -191,541 +191,564 @@ void TtresChi2::Reset(){ m_Wh_Values.reserve(10000); m_ThWh_Values.reserve(10000); m_Th_Values.reserve(10000); - m_Tl_Values.reserve(10000); + m_Tl_Values.reserve(10000); return; } //_________________________________________________________________________________________________ -std::vector<TLorentzVector*> TtresChi2::GetNeutrinos(TLorentzVector* L, TLorentzVector*MET){ +std::vector<TLorentzVector*> TtresChi2::GetNeutrinos(TLorentzVector* L, TLorentzVector* MET) { std::vector<TLorentzVector*> neutrinoVector; - if (m_WReco==ROTATION) neutrinoVector = m_NeutrinoBuilder->candidatesFromWMass_Rotation(L, MET, false /*m_useSmallestPz*/); - else if (m_WReco==REALPART)neutrinoVector = m_NeutrinoBuilder->candidatesFromWMass_RealPart(L, MET, false /*m_useSmallestPz*/); - else if (m_WReco==DECREASING) neutrinoVector = m_NeutrinoBuilder->candidatesFromWMass_Scaling(L, MET); + if (m_WReco == + ROTATION) neutrinoVector = m_NeutrinoBuilder->candidatesFromWMass_Rotation(L, MET, false /*m_useSmallestPz*/); + else if (m_WReco == + REALPART) neutrinoVector = + m_NeutrinoBuilder->candidatesFromWMass_RealPart(L, MET, false /*m_useSmallestPz*/); + else if (m_WReco == DECREASING) neutrinoVector = m_NeutrinoBuilder->candidatesFromWMass_Scaling(L, MET); return neutrinoVector; } //_________________________________________________________________________________________________ -bool TtresChi2::findMinChiSquare_HMelseLM(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, int& i_q2_W, int& i_b_had, int& i_b_lep, int& ign1, double& chi2ming1, double& chi2ming1H, double& chi2ming1L){ - if(m_debug>0) std::cout << "entering TtresChi2::findMinChiSquare_HMelseLM()" << std::endl; +bool TtresChi2::findMinChiSquare_HMelseLM(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, + const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, + int& i_q2_W, int& i_b_had, int& i_b_lep, int& ign1, double& chi2ming1, + double& chi2ming1H, double& chi2ming1L) { + if (m_debug > 0) std::cout << "entering TtresChi2::findMinChiSquare_HMelseLM()" << std::endl; bool status = false; - status = this->findMinChiSquare_HighMass(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_lep, ign1, chi2ming1, chi2ming1H, chi2ming1L); - - if (status && TMath::Log10(chi2ming1)<0.9) return status; // have found a good combination for HM - + status = this->findMinChiSquare_HighMass(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_lep, ign1, chi2ming1, + chi2ming1H, chi2ming1L); + + if (status && TMath::Log10(chi2ming1) < 0.9) return status; // have found a good combination for HM + // Otherwise try the LM chi2 - status = this->findMinChiSquare (L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_had, i_b_lep, ign1, chi2ming1, chi2ming1H, chi2ming1L); + status = this->findMinChiSquare(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_had, i_b_lep, ign1, chi2ming1, + chi2ming1H, chi2ming1L); return status; } - //_________________________________________________________________________________________________ -bool TtresChi2::findMinChiSquare_LMelseHM(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, int& i_q2_W, int& i_b_had, int& i_b_lep, int& ign1, double& chi2ming1, double& chi2ming1H, double& chi2ming1L){ - if(m_debug>0) std::cout << "entering TtresChi2::findMinChiSquare_LMelseHM()" << std::endl; +bool TtresChi2::findMinChiSquare_LMelseHM(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, + const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, + int& i_q2_W, int& i_b_had, int& i_b_lep, int& ign1, double& chi2ming1, + double& chi2ming1H, double& chi2ming1L) { + if (m_debug > 0) std::cout << "entering TtresChi2::findMinChiSquare_LMelseHM()" << std::endl; bool status = false; - status = this->findMinChiSquare (L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_had, i_b_lep, ign1, chi2ming1, chi2ming1H, chi2ming1L); - - if (status && TMath::Log10(chi2ming1)<0.9) return status; // have found a good combination for LM - + status = this->findMinChiSquare(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_had, i_b_lep, ign1, chi2ming1, + chi2ming1H, chi2ming1L); + + if (status && TMath::Log10(chi2ming1) < 0.9) return status; // have found a good combination for LM + // Otherwise try the HM chi2 - status = this->findMinChiSquare_HighMass(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_lep, ign1, chi2ming1, chi2ming1H, chi2ming1L); + status = this->findMinChiSquare_HighMass(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_lep, ign1, chi2ming1, + chi2ming1H, chi2ming1L); return status; } - //_________________________________________________________________________________________________ -bool TtresChi2::findMinChiSquare_AllRanges(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, int& i_q2_W, int& i_b_had, int& i_b_lep, int& ign1, double& chi2ming1, double& chi2ming1H, double& chi2ming1L){ - if(m_debug>0) std::cout << "entering TtresChi2::findMinChiSquare_AllRanges()" << std::endl; +bool TtresChi2::findMinChiSquare_AllRanges(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, + const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, + int& i_q2_W, int& i_b_had, int& i_b_lep, int& ign1, double& chi2ming1, + double& chi2ming1H, double& chi2ming1L) { + if (m_debug > 0) std::cout << "entering TtresChi2::findMinChiSquare_AllRanges()" << std::endl; bool status = false; float massMax = 0.; - for (unsigned int i=0; i<jetVector->size(); ++i) if(jetVector->at(i)->M()>massMax)massMax= jetVector->at(i)->M(); + for (unsigned int i = 0; i < jetVector->size(); + ++i) if (jetVector->at(i)->M() > massMax) massMax = jetVector->at(i)->M(); - if(massMax>=m_highJetMass*m_Units)status = this->findMinChiSquare_HighMass(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_lep, ign1, chi2ming1, chi2ming1H, chi2ming1L); - else status = this->findMinChiSquare (L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_had, i_b_lep, ign1, chi2ming1, chi2ming1H, chi2ming1L); + if (massMax >= m_highJetMass * m_Units) status = this->findMinChiSquare_HighMass(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_lep, ign1, chi2ming1, chi2ming1H, chi2ming1L); + else status = this->findMinChiSquare(L, jetVector, isJetBtagged, MET, i_q1_W, i_q2_W, i_b_had, i_b_lep, ign1, chi2ming1, chi2ming1H, chi2ming1L); return status; } //_________________________________________________________________________________________________ -bool TtresChi2::findMinChiSquare(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, int& i_q2_W, int& i_b_had, int& i_b_lep, int& ign1, double& chi2ming1, double& chi2ming1H, double& chi2ming1L){ - if(m_debug>0) std::cout << "entering TtresChi2::findMinChiSquare()" << std::endl; +bool TtresChi2::findMinChiSquare(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, int& i_q2_W, int& i_b_had, int& i_b_lep, int& ign1, double& chi2ming1, double& chi2ming1H, double& chi2ming1L) { + if (m_debug > 0) std::cout << "entering TtresChi2::findMinChiSquare()" << std::endl; //_________________________________________________________________________________________________ - i_q1_W=-1; - i_q2_W=-1; - i_b_had=-1; - i_b_lep=-1; - ign1=-1; - chi2ming1 =1e7; - chi2ming1H=1e7; - chi2ming1L=1e7; - double chi2ming1WH=1e7; + i_q1_W = -1; + i_q2_W = -1; + i_b_had = -1; + i_b_lep = -1; + ign1 = -1; + chi2ming1 = 1e7; + chi2ming1H = 1e7; + chi2ming1L = 1e7; + double chi2ming1WH = 1e7; int n_jets = jetVector->size(); int n_bjets = 0; - + this->Reset(); if (L == NULL) { - std::cerr << "ERROR : TtresChi2::findMinChiSquare: Lepton is NULL" << std::endl; - return false; + std::cerr << "ERROR : TtresChi2::findMinChiSquare: Lepton is NULL" << std::endl; + return false; } - - if(m_Btag==AFFECTBTAG){ - for(unsigned int ib = 0; ib<(unsigned int)isJetBtagged->size(); ++ib){ - if(isJetBtagged->at(ib)) n_bjets++; - } + + if (m_Btag == AFFECTBTAG) { + for (unsigned int ib = 0; ib < (unsigned int) isJetBtagged->size(); ++ib) { + if (isJetBtagged->at(ib)) n_bjets++; + } } - + //_________________________________________________________________________________________________ std::vector<TLorentzVector*> neutrinoVector = GetNeutrinos(L, MET); //_________________________________________________________________________________________________ - for (unsigned int i=0; i<(unsigned int)n_jets; i++){ + for (unsigned int i = 0; i < (unsigned int) n_jets; i++) { const TLorentzVector* I = jetVector->at(i); - for (unsigned int j=i+1; j<(unsigned int)n_jets; j++){ + for (unsigned int j = i + 1; j < (unsigned int) n_jets; j++) { const TLorentzVector* J = jetVector->at(j); - for (unsigned int k=0; k< (unsigned int)n_jets; k++){ - if ( k!=i && k!=j) { - const TLorentzVector* K = jetVector->at(k); - TLorentzVector TopH = (*I) + (*J) + (*K); - TLorentzVector Whad = (*I) + (*J); - for (unsigned int n=0; n< neutrinoVector.size(); n++){ - - TLorentzVector* N = neutrinoVector[n]; - - TLorentzVector Wlv = (*N) + (*L); - for (unsigned int m=0; m< (unsigned int)n_jets; m++){ - if (m!=i && m!=j && m!=k) { - const TLorentzVector* M = jetVector->at(m); - TLorentzVector Tlv = Wlv + (*M); - TLorentzVector Tt = Tlv + TopH; - double chi2WH = pow((Whad.M()-MjjP)/SMjjP,2); - double chi2H = chi2WH + pow((TopH.M()-Whad.M()-m_TopMinusW_had_mean)/m_TopMinusW_had_sigma,2); - double chi2L = pow((Tlv.M()-m_Top_lep_mean)/m_Top_lep_sigma,2); - - double chi2tempg1 = chi2H+chi2L; - if (m_UsePtDiff==PTDIFF){ - double chi2Diff = pow((TopH.Pt()-Tlv.Pt()-m_PtDiff_mean)/m_PtDiff_sigma,2); - chi2tempg1+=chi2Diff; - }else if (m_UsePtDiff==PTDIFFREL){ - double chi2DiffRel = pow(((TopH.Pt()-Tlv.Pt())/(TopH.Pt()+Tlv.Pt())-m_PtDiffRel_mean)/m_PtDiffRel_sigma,2); - chi2tempg1+=chi2DiffRel; - }else if (m_UsePtDiff==PTDIFFMASS){ - double chi2DiffRelMass = pow(((TopH.Pt()-Tlv.Pt())/(Tt.M())-m_PtDiffRelMass_mean)/m_PtDiffRelMass_sigma,2); - chi2tempg1+=chi2DiffRelMass; - } - - // does this combination contain a b - // k -> hadronic b - // m -> leptonic b - int n_bJetsComb = 0; - if (isJetBtagged->at(k)){ - n_bJetsComb++; - } - // second b - if (isJetBtagged->at(m)){ - n_bJetsComb++; - } - - bool passBtag = false; - if(m_Btag==STDBTAG || m_Btag==NO_BTAGHM){ - if(n_bJetsComb>0){ - passBtag = true; - } - }else if(m_Btag==AFFECTBTAG){ - if(n_bjets==0){ - passBtag = true; - }else if(n_bjets==1){ - if(n_bJetsComb==1){ passBtag = true; } - }else if(n_bjets>=2){ - if(n_bJetsComb==2){ passBtag = true; } - } - }else if(m_Btag==NO_BTAG){ - passBtag = true; - } - - if(passBtag && m_RunMode==RUNSTUDY){ - m_chi2Values.push_back(chi2tempg1); - m_chi2Wh_Values.push_back(chi2WH); - m_chi2ThWh_Values.push_back(chi2H - chi2WH); - m_chi2Tl_Values.push_back(chi2L); - m_chi2PtDiff_Values.push_back(chi2tempg1 - chi2H - chi2L); - m_i_Wq1.push_back(i); - m_i_Wq2.push_back(j); - m_i_Thb.push_back(k); - m_i_Tlb.push_back(m); - m_i_n.push_back(n); - if(m_UsePtDiff==PTDIFF) m_PtDiff_Values.push_back((TopH.Pt()-Tlv.Pt())/m_Units); - else if(m_UsePtDiff==PTDIFFMASS) m_PtDiff_Values.push_back((TopH.Pt()-Tlv.Pt())/(Tt.M())); - m_Wh_Values.push_back(Whad.M()/m_Units); - m_ThWh_Values.push_back((TopH.M()-Whad.M())/m_Units); - m_Tl_Values.push_back((Tlv.M())/m_Units); - m_nChi2Values++; - } - - //################# - //Original chi2 method - //################# - if (chi2tempg1<chi2ming1){ - - if(passBtag){ - chi2ming1 = chi2tempg1; - chi2ming1H = chi2H; - chi2ming1L = chi2L; - m_WhChi2Value = chi2WH; - m_ThWhChi2Value = chi2H - chi2WH; - m_TlChi2Value = chi2L; - m_PtDiffChi2Value = chi2tempg1 - chi2H - chi2L; - - i_q1_W=i; - i_q2_W=j; - i_b_had=k; - i_b_lep=m; - ign1=n; - res_Mtl=Tlv.M(); - res_Mwh=Whad.M(); - res_Mth=TopH.M(); - res_Mtt=Tt.M(); - res_Tt = Tt; - - //============================ - // bjet category splitting - //============================ - if(n_bjets==0){ - m_category = 0; - }else if(n_bjets==1){ - if(isJetBtagged->at(k)){//b-jet on the hadronic side - m_category = 2; - }else if(isJetBtagged->at(m)){//b-jet on the leptonic side - m_category = 3; - }else{ - std::cerr << "<!> In TtresChi2::findMinChiSquare : cannot find the corresponding category." << std::endl; - } - }else if(n_bjets>=2){ - if(isJetBtagged->at(k)){//b-jet on the hadronic side - if(isJetBtagged->at(m)){//b-jet on the leptonic side too - m_category = 1; - }else{//b-jet only on the hadronic side - m_category = 2; - } - }else if(isJetBtagged->at(m)){ - m_category = 3; - }else{ - std::cerr << "<!> In TtresChi2::findMinChiSquare : cannot find the corresponding category." << std::endl; - } - } - } - } // end of case a minimal chisquare was found - } // end of case unique combination - } //end of loop over jets - } // end of loop over all neutrino solutions - } // end of case this is the electron channel + for (unsigned int k = 0; k < (unsigned int) n_jets; k++) { + if (k != i && k != j) { + const TLorentzVector* K = jetVector->at(k); + TLorentzVector TopH = (*I) + (*J) + (*K); + TLorentzVector Whad = (*I) + (*J); + for (unsigned int n = 0; n < neutrinoVector.size(); n++) { + TLorentzVector* N = neutrinoVector[n]; + + TLorentzVector Wlv = (*N) + (*L); + for (unsigned int m = 0; m < (unsigned int) n_jets; m++) { + if (m != i && m != j && m != k) { + const TLorentzVector* M = jetVector->at(m); + TLorentzVector Tlv = Wlv + (*M); + TLorentzVector Tt = Tlv + TopH; + double chi2WH = pow((Whad.M() - MjjP) / SMjjP, 2); + double chi2H = chi2WH + pow((TopH.M() - Whad.M() - m_TopMinusW_had_mean) / m_TopMinusW_had_sigma, 2); + double chi2L = pow((Tlv.M() - m_Top_lep_mean) / m_Top_lep_sigma, 2); + + double chi2tempg1 = chi2H + chi2L; + if (m_UsePtDiff == PTDIFF) { + double chi2Diff = pow((TopH.Pt() - Tlv.Pt() - m_PtDiff_mean) / m_PtDiff_sigma, 2); + chi2tempg1 += chi2Diff; + } else if (m_UsePtDiff == PTDIFFREL) { + double chi2DiffRel = pow(((TopH.Pt() - Tlv.Pt()) / (TopH.Pt() + Tlv.Pt()) - m_PtDiffRel_mean) / m_PtDiffRel_sigma, 2); + chi2tempg1 += chi2DiffRel; + } else if (m_UsePtDiff == PTDIFFMASS) { + double chi2DiffRelMass = pow(((TopH.Pt() - Tlv.Pt()) / (Tt.M()) - m_PtDiffRelMass_mean) / m_PtDiffRelMass_sigma, 2); + chi2tempg1 += chi2DiffRelMass; + } + + // does this combination contain a b + // k -> hadronic b + // m -> leptonic b + int n_bJetsComb = 0; + if (isJetBtagged->at(k)) { + n_bJetsComb++; + } + // second b + if (isJetBtagged->at(m)) { + n_bJetsComb++; + } + + bool passBtag = false; + if (m_Btag == STDBTAG || m_Btag == NO_BTAGHM) { + if (n_bJetsComb > 0) { + passBtag = true; + } + } else if (m_Btag == AFFECTBTAG) { + if (n_bjets == 0) { + passBtag = true; + } else if (n_bjets == 1) { + if (n_bJetsComb == 1) { + passBtag = true; + } + } else if (n_bjets >= 2) { + if (n_bJetsComb == 2) { + passBtag = true; + } + } + } else if (m_Btag == NO_BTAG) { + passBtag = true; + } + + if (passBtag && m_RunMode == RUNSTUDY) { + m_chi2Values.push_back(chi2tempg1); + m_chi2Wh_Values.push_back(chi2WH); + m_chi2ThWh_Values.push_back(chi2H - chi2WH); + m_chi2Tl_Values.push_back(chi2L); + m_chi2PtDiff_Values.push_back(chi2tempg1 - chi2H - chi2L); + m_i_Wq1.push_back(i); + m_i_Wq2.push_back(j); + m_i_Thb.push_back(k); + m_i_Tlb.push_back(m); + m_i_n.push_back(n); + if (m_UsePtDiff == PTDIFF) m_PtDiff_Values.push_back((TopH.Pt() - Tlv.Pt()) / m_Units); + else if (m_UsePtDiff == PTDIFFMASS) m_PtDiff_Values.push_back((TopH.Pt() - Tlv.Pt()) / (Tt.M())); + m_Wh_Values.push_back(Whad.M() / m_Units); + m_ThWh_Values.push_back((TopH.M() - Whad.M()) / m_Units); + m_Tl_Values.push_back((Tlv.M()) / m_Units); + m_nChi2Values++; + } + + //################# + //Original chi2 method + //################# + if (chi2tempg1 < chi2ming1) { + if (passBtag) { + chi2ming1 = chi2tempg1; + chi2ming1H = chi2H; + chi2ming1L = chi2L; + m_WhChi2Value = chi2WH; + m_ThWhChi2Value = chi2H - chi2WH; + m_TlChi2Value = chi2L; + m_PtDiffChi2Value = chi2tempg1 - chi2H - chi2L; + + i_q1_W = i; + i_q2_W = j; + i_b_had = k; + i_b_lep = m; + ign1 = n; + res_Mtl = Tlv.M(); + res_Mwh = Whad.M(); + res_Mth = TopH.M(); + res_Mtt = Tt.M(); + res_Tt = Tt; + + //============================ + // bjet category splitting + //============================ + if (n_bjets == 0) { + m_category = 0; + } else if (n_bjets == 1) { + if (isJetBtagged->at(k)) {//b-jet on the hadronic side + m_category = 2; + } else if (isJetBtagged->at(m)) {//b-jet on the leptonic side + m_category = 3; + } else { + std::cerr << "<!> In TtresChi2::findMinChiSquare : cannot find the corresponding category." << std::endl; + } + } else if (n_bjets >= 2) { + if (isJetBtagged->at(k)) {//b-jet on the hadronic side + if (isJetBtagged->at(m)) {//b-jet on the leptonic side too + m_category = 1; + } else {//b-jet only on the hadronic side + m_category = 2; + } + } else if (isJetBtagged->at(m)) { + m_category = 3; + } else { + std::cerr << "<!> In TtresChi2::findMinChiSquare : cannot find the corresponding category." << std::endl; + } + } + } + } // end of case a minimal chisquare was found + } // end of case unique combination + } //end of loop over jets + } // end of loop over all neutrino solutions + } // end of case this is the electron channel } // end of loop over jets k } // end of loop over jets } // end of loop over jets - bool status=false; - if ( i_q1_W != -1 && i_q2_W != -1 && i_b_had != -1 && i_b_lep != -1 && ign1 != -1){ + bool status = false; + if (i_q1_W != -1 && i_q2_W != -1 && i_b_had != -1 && i_b_lep != -1 && ign1 != -1) { status = true; } - res_chi2All = chi2ming1; - res_chi2WH = chi2ming1WH; + res_chi2All = chi2ming1; + res_chi2WH = chi2ming1WH; res_chi2TopH = chi2ming1H; res_chi2TopL = chi2ming1L; - for (unsigned int i =0; i< neutrinoVector.size(); i++)delete neutrinoVector[i]; neutrinoVector.clear(); + for (unsigned int i = 0; i < neutrinoVector.size(); i++) { + delete neutrinoVector[i]; + } + neutrinoVector.clear(); return status; } - //_________________________________________________________________________________________________ -bool TtresChi2::findMinChiSquare_HighMass(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, int& i_q2_W, int& i_b_lep, int& ign1, double& chi2ming1, double& -chi2ming1H, double& chi2ming1L){ - if(m_debug>0) std::cout << "entering TtresChi2::findMinChiSquare_HighMass()" << std::endl; +bool TtresChi2::findMinChiSquare_HighMass(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q1_W, int& i_q2_W, int& i_b_lep, int& ign1, double& chi2ming1, double& + chi2ming1H, double& chi2ming1L) { + if (m_debug > 0) std::cout << "entering TtresChi2::findMinChiSquare_HighMass()" << std::endl; //_________________________________________________________________________________________________ - i_q1_W=-1; - i_q2_W=-1; - i_b_lep=-1; - ign1=-1; - chi2ming1 =1e7; - chi2ming1H=1e7; - chi2ming1L=1e7; + i_q1_W = -1; + i_q2_W = -1; + i_b_lep = -1; + ign1 = -1; + chi2ming1 = 1e7; + chi2ming1H = 1e7; + chi2ming1L = 1e7; double HMtop = -1e6; int n_jets = jetVector->size(); int n_bjets = 0; - + this->Reset(); if (L == NULL) { - std::cerr << "ERROR : TtresChi2::findMinChiSquare: Lepton is NULL" << std::endl; - return false; + std::cerr << "ERROR : TtresChi2::findMinChiSquare: Lepton is NULL" << std::endl; + return false; } - - if(m_Btag==AFFECTBTAG){ - for(unsigned int ib = 0; ib<(unsigned int)isJetBtagged->size(); ++ib){ - if(isJetBtagged->at(ib)) n_bjets++; - } + + if (m_Btag == AFFECTBTAG) { + for (unsigned int ib = 0; ib < (unsigned int) isJetBtagged->size(); ++ib) { + if (isJetBtagged->at(ib)) n_bjets++; + } } - + //_________________________________________________________________________________________________ - std::vector<TLorentzVector*> neutrinoVector= GetNeutrinos(L, MET); + std::vector<TLorentzVector*> neutrinoVector = GetNeutrinos(L, MET); //_________________________________________________________________________________________________ - for (unsigned int i=0; i<(unsigned int)n_jets; i++){ + for (unsigned int i = 0; i < (unsigned int) n_jets; i++) { const TLorentzVector* I = jetVector->at(i); - for (unsigned int j=i+1; j<(unsigned int)n_jets; j++){ + for (unsigned int j = i + 1; j < (unsigned int) n_jets; j++) { const TLorentzVector* J = jetVector->at(j); - if ( I->M()>m_highJetMass*m_Units || J->M()>m_highJetMass*m_Units ) { - TLorentzVector TopH = (*I) + (*J); - - for (unsigned int n=0; n< neutrinoVector.size(); n++){ - - TLorentzVector* N = neutrinoVector[n]; - - TLorentzVector Wlv = (*N) + (*L); - for (unsigned int m=0; m<(unsigned int) n_jets; m++){ - if (m!=i && m!=j) { - const TLorentzVector* M = jetVector->at(m); - TLorentzVector Tlv = Wlv + (*M); - TLorentzVector Tt = Tlv + TopH; - - double HMtoptemp = I->M(); - double chi2H = pow((TopH.M()-MTHJJ)/STHJJ,2); - double chi2L = pow((Tlv.M()-m_Top_lep_mean)/m_Top_lep_sigma,2); - - double chi2tempg1 = chi2H+chi2L; - if (m_UsePtDiff==PTDIFF){ - double chi2Diff = pow((TopH.Pt()-Tlv.Pt()-m_PtDiff_mean)/m_PtDiff_sigma,2); - chi2tempg1+=chi2Diff; - }else if (m_UsePtDiff==PTDIFFREL){ - double chi2DiffRel = pow(((TopH.Pt()-Tlv.Pt())/(TopH.Pt()+Tlv.Pt())-m_PtDiffRel_mean)/m_PtDiffRel_sigma,2); - chi2tempg1+=chi2DiffRel; - }else if (m_UsePtDiff==PTDIFFMASS){ - double chi2DiffRelMass = pow(((TopH.Pt()-Tlv.Pt())/(Tt.M())-m_PtDiffRelMass_mean)/m_PtDiffRelMass_sigma,2); - chi2tempg1+=chi2DiffRelMass; - } - - // does this combination contain a b - // k -> hadronic b - // m -> leptonic b - int n_bJetsComb = 0; - // check whether one of the taggers is passed - // first b - if (isJetBtagged->at(i) || isJetBtagged->at(j)){ - n_bJetsComb++; - } - // second b - if (isJetBtagged->at(m)){ - n_bJetsComb++; - } - - bool passBtag = false; - if(m_Btag==STDBTAG){ - if(n_bJetsComb>0){ - passBtag = true; - } - }else if(m_Btag==AFFECTBTAG){ - if(n_bjets==0){ - passBtag = true; - }else if(n_bjets==1){ - if(n_bJetsComb==1){ passBtag = true; } - }else if(n_bjets>=2){ - if(n_bJetsComb==2){ passBtag = true; } - } - }else if(m_Btag==NO_BTAGHM || m_Btag==NO_BTAG){ - passBtag = true; - } - - if(passBtag && m_RunMode==RUNSTUDY){ - m_chi2Values.push_back(chi2tempg1); - m_chi2Th_Values.push_back(chi2H); - m_chi2Tl_Values.push_back(chi2L); - m_chi2PtDiff_Values.push_back(chi2tempg1 - chi2H - chi2L); - m_i_Wq1.push_back(i); - m_i_Wq2.push_back(j); - m_i_Tlb.push_back(m); - m_i_n.push_back(n); - if(m_UsePtDiff==PTDIFF) m_PtDiff_Values.push_back((TopH.Pt()-Tlv.Pt())/m_Units); - else if(m_UsePtDiff==PTDIFFMASS) m_PtDiff_Values.push_back((TopH.Pt()-Tlv.Pt())/(Tt.M())); - m_Th_Values.push_back((TopH.M())/m_Units); - m_Tl_Values.push_back((Tlv.M())/m_Units); - m_nChi2Values++; - } - - //################# - //Original chi2 method - //################# - if (chi2tempg1<chi2ming1 && HMtoptemp>=HMtop){ - if(passBtag){ - HMtop=HMtoptemp; - chi2ming1=chi2tempg1; - chi2ming1H=chi2H; - chi2ming1L=chi2L; - m_ThWhChi2Value = chi2H; - m_TlChi2Value = chi2L; - m_PtDiffChi2Value = chi2tempg1 - chi2H - chi2L; - - i_q1_W=i; - i_q2_W=j; - i_b_lep=m; - ign1=n; - res_Mtl=Tlv.M(); - //res_Mwh is not defined here - res_Mth=TopH.M(); - res_Mtt=Tt.M(); - res_Tt = Tt; - - //============================ - // bjet category splitting - //============================ - if(n_bjets==0){ - m_category = 0; - }else if(n_bjets==1){ - if(isJetBtagged->at(i) || isJetBtagged->at(j)){//b-jet on the hadronic side - m_category = 2; - }else if(isJetBtagged->at(m)){//b-jet on the leptonic side - m_category = 3; - }else{ - std::cerr << "<!> In TtresChi2::findMinChiSquare : cannot find the corresponding category." << std::endl; - } - }else if(n_bjets>=2){ - if(isJetBtagged->at(i) || isJetBtagged->at(m)){//b-jet on the hadronic side - if(isJetBtagged->at(m)){//b-jet on the leptonic side too - m_category = 1; - }else{//b-jet only on the hadronic side - m_category = 2; - } - }else if(isJetBtagged->at(m)){ - m_category = 3; - }else{ - std::cerr << "<!> In TtresChi2::findMinChiSquare : cannot find the corresponding category." << std::endl; - } - } - - } //end of btag requirement - } // end of case a minimal chisquare was found - } // end of case unique combination - } //end of loop over jets - } // end of loop over all neutrino solutions + if (I->M() > m_highJetMass * m_Units || J->M() > m_highJetMass * m_Units) { + TLorentzVector TopH = (*I) + (*J); + + for (unsigned int n = 0; n < neutrinoVector.size(); n++) { + TLorentzVector* N = neutrinoVector[n]; + + TLorentzVector Wlv = (*N) + (*L); + for (unsigned int m = 0; m < (unsigned int) n_jets; m++) { + if (m != i && m != j) { + const TLorentzVector* M = jetVector->at(m); + TLorentzVector Tlv = Wlv + (*M); + TLorentzVector Tt = Tlv + TopH; + + double HMtoptemp = I->M(); + double chi2H = pow((TopH.M() - MTHJJ) / STHJJ, 2); + double chi2L = pow((Tlv.M() - m_Top_lep_mean) / m_Top_lep_sigma, 2); + + double chi2tempg1 = chi2H + chi2L; + if (m_UsePtDiff == PTDIFF) { + double chi2Diff = pow((TopH.Pt() - Tlv.Pt() - m_PtDiff_mean) / m_PtDiff_sigma, 2); + chi2tempg1 += chi2Diff; + } else if (m_UsePtDiff == PTDIFFREL) { + double chi2DiffRel = pow(((TopH.Pt() - Tlv.Pt()) / (TopH.Pt() + Tlv.Pt()) - m_PtDiffRel_mean) / m_PtDiffRel_sigma, 2); + chi2tempg1 += chi2DiffRel; + } else if (m_UsePtDiff == PTDIFFMASS) { + double chi2DiffRelMass = pow(((TopH.Pt() - Tlv.Pt()) / (Tt.M()) - m_PtDiffRelMass_mean) / m_PtDiffRelMass_sigma, 2); + chi2tempg1 += chi2DiffRelMass; + } + + // does this combination contain a b + // k -> hadronic b + // m -> leptonic b + int n_bJetsComb = 0; + // check whether one of the taggers is passed + // first b + if (isJetBtagged->at(i) || isJetBtagged->at(j)) { + n_bJetsComb++; + } + // second b + if (isJetBtagged->at(m)) { + n_bJetsComb++; + } + + bool passBtag = false; + if (m_Btag == STDBTAG) { + if (n_bJetsComb > 0) { + passBtag = true; + } + } else if (m_Btag == AFFECTBTAG) { + if (n_bjets == 0) { + passBtag = true; + } else if (n_bjets == 1) { + if (n_bJetsComb == 1) { + passBtag = true; + } + } else if (n_bjets >= 2) { + if (n_bJetsComb == 2) { + passBtag = true; + } + } + } else if (m_Btag == NO_BTAGHM || m_Btag == NO_BTAG) { + passBtag = true; + } + + if (passBtag && m_RunMode == RUNSTUDY) { + m_chi2Values.push_back(chi2tempg1); + m_chi2Th_Values.push_back(chi2H); + m_chi2Tl_Values.push_back(chi2L); + m_chi2PtDiff_Values.push_back(chi2tempg1 - chi2H - chi2L); + m_i_Wq1.push_back(i); + m_i_Wq2.push_back(j); + m_i_Tlb.push_back(m); + m_i_n.push_back(n); + if (m_UsePtDiff == PTDIFF) m_PtDiff_Values.push_back((TopH.Pt() - Tlv.Pt()) / m_Units); + else if (m_UsePtDiff == PTDIFFMASS) m_PtDiff_Values.push_back((TopH.Pt() - Tlv.Pt()) / (Tt.M())); + m_Th_Values.push_back((TopH.M()) / m_Units); + m_Tl_Values.push_back((Tlv.M()) / m_Units); + m_nChi2Values++; + } + + //################# + //Original chi2 method + //################# + if (chi2tempg1 < chi2ming1 && HMtoptemp >= HMtop) { + if (passBtag) { + HMtop = HMtoptemp; + chi2ming1 = chi2tempg1; + chi2ming1H = chi2H; + chi2ming1L = chi2L; + m_ThWhChi2Value = chi2H; + m_TlChi2Value = chi2L; + m_PtDiffChi2Value = chi2tempg1 - chi2H - chi2L; + + i_q1_W = i; + i_q2_W = j; + i_b_lep = m; + ign1 = n; + res_Mtl = Tlv.M(); + //res_Mwh is not defined here + res_Mth = TopH.M(); + res_Mtt = Tt.M(); + res_Tt = Tt; + + //============================ + // bjet category splitting + //============================ + if (n_bjets == 0) { + m_category = 0; + } else if (n_bjets == 1) { + if (isJetBtagged->at(i) || isJetBtagged->at(j)) {//b-jet on the hadronic side + m_category = 2; + } else if (isJetBtagged->at(m)) {//b-jet on the leptonic side + m_category = 3; + } else { + std::cerr << "<!> In TtresChi2::findMinChiSquare : cannot find the corresponding category." << std::endl; + } + } else if (n_bjets >= 2) { + if (isJetBtagged->at(i) || isJetBtagged->at(m)) {//b-jet on the hadronic side + if (isJetBtagged->at(m)) {//b-jet on the leptonic side too + m_category = 1; + } else {//b-jet only on the hadronic side + m_category = 2; + } + } else if (isJetBtagged->at(m)) { + m_category = 3; + } else { + std::cerr << "<!> In TtresChi2::findMinChiSquare : cannot find the corresponding category." << std::endl; + } + } + } //end of btag requirement + } // end of case a minimal chisquare was found + } // end of case unique combination + } //end of loop over jets + } // end of loop over all neutrino solutions } // end of case this is the electron channel } // end of loop over jets } // end of loop over jets - bool status=false; - if ( i_q1_W != -1 && i_q2_W != -1 && i_b_lep != -1 && ign1 != -1){ + bool status = false; + if (i_q1_W != -1 && i_q2_W != -1 && i_b_lep != -1 && ign1 != -1) { status = true; } - res_chi2All = chi2ming1; + res_chi2All = chi2ming1; res_chi2TopH = chi2ming1H; res_chi2TopL = chi2ming1L; - for (unsigned int i =0; i< neutrinoVector.size(); i++)delete neutrinoVector[i]; neutrinoVector.clear(); + for (unsigned int i = 0; i < neutrinoVector.size(); i++) { + delete neutrinoVector[i]; + } + neutrinoVector.clear(); return status; } //_________________________________________________________________________________________________ -bool TtresChi2::findMinChiSquare_VeryHighMass(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q2_W, int& i_b_lep, int& ign1, double& chi2ming1, double& chi2ming1H, double& chi2ming1L){ - if(m_debug>0) std::cout << "entering TtresChi2::findMinChiSquare_VeryHighMass() " << std::endl; +bool TtresChi2::findMinChiSquare_VeryHighMass(TLorentzVector* L, const std::vector<TLorentzVector*>* jetVector, const std::vector<bool>* isJetBtagged, TLorentzVector* MET, int& i_q2_W, int& i_b_lep, int& ign1, double& chi2ming1, double& chi2ming1H, double& chi2ming1L) { + if (m_debug > 0) std::cout << "entering TtresChi2::findMinChiSquare_VeryHighMass() " << std::endl; //_________________________________________________________________________________________________ - i_q2_W=-1; - i_b_lep=-1; - ign1=-1; - chi2ming1 =1e7; - chi2ming1H=1e7; - chi2ming1L=1e7; + i_q2_W = -1; + i_b_lep = -1; + ign1 = -1; + chi2ming1 = 1e7; + chi2ming1H = 1e7; + chi2ming1L = 1e7; double HMtop = -1e6; int n_jets = jetVector->size(); this->Reset(); if (L == NULL) { - std::cerr << "ERROR : TtresChi2::findMinChiSquare: Lepton is NULL" << std::endl; - return false; + std::cerr << "ERROR : TtresChi2::findMinChiSquare: Lepton is NULL" << std::endl; + return false; } - std::vector<TLorentzVector*> neutrinoVector= GetNeutrinos(L, MET); + std::vector<TLorentzVector*> neutrinoVector = GetNeutrinos(L, MET); //_________________________________________________________________________________________________ - for (unsigned int i=0; i<(unsigned int)n_jets; i++){ + for (unsigned int i = 0; i < (unsigned int) n_jets; i++) { const TLorentzVector* I = jetVector->at(i); TLorentzVector TopH = (*I); - if (I->M()>150.*m_Units){ - for (unsigned int n=0; n< neutrinoVector.size(); n++){ - - TLorentzVector* N = neutrinoVector[n]; - - TLorentzVector Wlv = (*N) + (*L); - for (unsigned int m=0; m< (unsigned int)n_jets; m++){ - if (m!=i) { - const TLorentzVector* M = jetVector->at(m); - TLorentzVector Tlv = Wlv + (*M); - TLorentzVector Tt = Tlv + TopH; - - double HMtoptemp = I->M(); - double chi2H = 1.; - double chi2L = pow((Tlv.M()-m_Top_lep_mean)/m_Top_lep_sigma,2); - double chi2Diff = pow((TopH.Pt()-Tlv.Pt()-m_PtDiff_mean)/m_PtDiff_sigma,2); - double chi2tempg1 = chi2L; - - if (m_UsePtDiff) chi2tempg1+=chi2Diff; - - //################# - //Original chi2 method - //################# - if (chi2tempg1<chi2ming1 && HMtoptemp>=HMtop){ - - // does this combination contain a b - // k -> hadronic b - // m -> leptonic b - int n_bJets = 0; - // check whether one of the taggers is passed - // first b - if (isJetBtagged->at(i)){ - n_bJets++; - } - // second b - if (isJetBtagged->at(m)){ - n_bJets++; - } - - if (n_bJets >= 1){ - HMtop=HMtoptemp; - chi2ming1=chi2tempg1; - chi2ming1H=chi2H; - chi2ming1L=chi2L; - i_q2_W=i; - i_b_lep=m; - ign1=n; - res_Mtl=Tlv.M(); - //res_Mwh is not defined here - res_Mth=TopH.M(); - res_Mtt=Tt.M(); - res_Tt = Tt; - } - } // end of case a minimal chisquare was found - } // end of case unique combination - } //end of loop over jets + if (I->M() > 150. * m_Units) { + for (unsigned int n = 0; n < neutrinoVector.size(); n++) { + TLorentzVector* N = neutrinoVector[n]; + + TLorentzVector Wlv = (*N) + (*L); + for (unsigned int m = 0; m < (unsigned int) n_jets; m++) { + if (m != i) { + const TLorentzVector* M = jetVector->at(m); + TLorentzVector Tlv = Wlv + (*M); + TLorentzVector Tt = Tlv + TopH; + + double HMtoptemp = I->M(); + double chi2H = 1.; + double chi2L = pow((Tlv.M() - m_Top_lep_mean) / m_Top_lep_sigma, 2); + double chi2Diff = pow((TopH.Pt() - Tlv.Pt() - m_PtDiff_mean) / m_PtDiff_sigma, 2); + double chi2tempg1 = chi2L; + + if (m_UsePtDiff) chi2tempg1 += chi2Diff; + + //################# + //Original chi2 method + //################# + if (chi2tempg1 < chi2ming1 && HMtoptemp >= HMtop) { + // does this combination contain a b + // k -> hadronic b + // m -> leptonic b + int n_bJets = 0; + // check whether one of the taggers is passed + // first b + if (isJetBtagged->at(i)) { + n_bJets++; + } + // second b + if (isJetBtagged->at(m)) { + n_bJets++; + } + + if (n_bJets >= 1) { + HMtop = HMtoptemp; + chi2ming1 = chi2tempg1; + chi2ming1H = chi2H; + chi2ming1L = chi2L; + i_q2_W = i; + i_b_lep = m; + ign1 = n; + res_Mtl = Tlv.M(); + //res_Mwh is not defined here + res_Mth = TopH.M(); + res_Mtt = Tt.M(); + res_Tt = Tt; + } + } // end of case a minimal chisquare was found + } // end of case unique combination + } //end of loop over jets } // end of loop over all neutrino solutions } // end of high mass } // end of loop over jets bool status = false; - if ( i_q2_W != -1 && i_b_lep != -1 && ign1 != -1){ + if (i_q2_W != -1 && i_b_lep != -1 && ign1 != -1) { status = true; } - res_chi2All = chi2ming1; + res_chi2All = chi2ming1; res_chi2TopH = chi2ming1H; res_chi2TopL = chi2ming1L; - for (unsigned int i =0; i< neutrinoVector.size(); i++)delete neutrinoVector[i]; neutrinoVector.clear(); + for (unsigned int i = 0; i < neutrinoVector.size(); i++) { + delete neutrinoVector[i]; + } + neutrinoVector.clear(); return status; } - - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresNeutrinoBuilder.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresNeutrinoBuilder.cxx index f177f65c3f0d..41a6e140176a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresNeutrinoBuilder.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresNeutrinoBuilder.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include <TMinuit.h> #include "TopEventReconstructionTools/TtresNeutrinoBuilder.h" @@ -9,26 +9,26 @@ void delta2_fcn(Int_t&, Double_t*, Double_t&, Double_t*, Int_t); //_________________________________________________________________________________________________ -TtresNeutrinoBuilder::TtresNeutrinoBuilder(std::string units){ +TtresNeutrinoBuilder::TtresNeutrinoBuilder(std::string units) { m_debug = 0; - if (units=="MeV")m_Units = 1000.; - else if(units=="GeV")m_Units = 1.; + if (units == "MeV") m_Units = 1000.; + else if (units == "GeV") m_Units = 1.; else std::cerr << "WARNING in NeutrinoBuilder: units different from GeV or MeV" << std::endl; } //_________________________________________________________________________________________________ -TtresNeutrinoBuilder::~TtresNeutrinoBuilder(){ - if(m_debug>0) std::cout << "in destructor " << std::endl; +TtresNeutrinoBuilder::~TtresNeutrinoBuilder() { + if (m_debug > 0) std::cout << "in destructor " << std::endl; } -//_________________________________________________________________________________________________ -TtresNeutrinoBuilder::TtresNeutrinoBuilder(const TtresNeutrinoBuilder& other) { +//_________________________________________________________________________________________________ +TtresNeutrinoBuilder::TtresNeutrinoBuilder(const TtresNeutrinoBuilder& other) { m_debug = other.m_debug; } -//_________________________________________________________________________________________________ -TtresNeutrinoBuilder& TtresNeutrinoBuilder::operator=(const TtresNeutrinoBuilder& other) { - if(this != &other) { +//_________________________________________________________________________________________________ +TtresNeutrinoBuilder& TtresNeutrinoBuilder::operator = (const TtresNeutrinoBuilder& other) { + if (this != &other) { m_debug = other.m_debug; } return *this; @@ -36,8 +36,7 @@ TtresNeutrinoBuilder& TtresNeutrinoBuilder::operator=(const TtresNeutrinoBuilder //_________________________________________________________________________________________________ // JDM - fix compiler warnings -void delta2_fcn(Int_t& /*npar*/, Double_t* /*grad*/, Double_t& f, Double_t* par, Int_t /*iflag*/){ - +void delta2_fcn(Int_t& /*npar*/, Double_t* /*grad*/, Double_t& f, Double_t* par, Int_t /*iflag*/) { Double_t delta2 = 0; Double_t alpha = par[0]; Double_t r = par[1]; @@ -46,14 +45,16 @@ void delta2_fcn(Int_t& /*npar*/, Double_t* /*grad*/, Double_t& f, Double_t* par, Double_t l_m = par[4]; Double_t n_px = par[5]; Double_t n_py = par[6]; + r /= sqrt(l_pt * l_pt + l_m * l_m) - l_pt * cos(dphi + alpha); - TLorentzVector *neut = new TLorentzVector(n_px, n_py, 0., 0.); + TLorentzVector* neut = new TLorentzVector(n_px, n_py, 0., 0.); neut->SetE(neut->P()); - - TLorentzVector *neut_new = new TLorentzVector(r * neut->P() * cos(neut->Phi() + alpha), r * neut->P() * sin(neut->Phi() + alpha), 0., 0.); + + TLorentzVector* neut_new = + new TLorentzVector(r * neut->P() * cos(neut->Phi() + alpha), r * neut->P() * sin(neut->Phi() + alpha), 0., 0.); neut_new->SetE(neut_new->P()); - - delta2 = pow((neut_new->Px() - neut->Px()), 2) + pow((neut_new->Py() - neut->Py()), 2); + + delta2 = pow((neut_new->Px() - neut->Px()), 2) + pow((neut_new->Py() - neut->Py()), 2); r *= sqrt(l_pt * l_pt + l_m * l_m) - l_pt * cos(dphi + alpha); delete neut; delete neut_new; @@ -61,29 +62,41 @@ void delta2_fcn(Int_t& /*npar*/, Double_t* /*grad*/, Double_t& f, Double_t* par, } //_________________________________________________________________________________________________ -double TtresNeutrinoBuilder::fitAlpha(const TLorentzVector* L, const Double_t met, const Double_t metphi){ - +double TtresNeutrinoBuilder::fitAlpha(const TLorentzVector* L, const Double_t met, const Double_t metphi) { // initialize double m_mWpdg = 80.4 * m_Units; Double_t pxNu = met * cos(metphi); Double_t pyNu = met * sin(metphi); Double_t ptNu = met; - - TMinuit *fit = new TMinuit(7); + + TMinuit* fit = new TMinuit(7); + fit->SetFCN(delta2_fcn); int ierr = 0; - double arglist[1] = {-1}; - fit->mnexcm("SET PRIN",arglist,1,ierr); + double arglist[1] = { + -1 + }; + fit->mnexcm("SET PRIN", arglist, 1, ierr); // Initialise the parameters - std::string par_name[7] = {"alpha", "r", "dphi", "l_pt", "l_m", "n_px", "n_py"}; - Double_t par_ival[7] = {0., (m_mWpdg * m_mWpdg - L->M() * L->M()) / (2 * ptNu), metphi - L->Phi(), L->Pt(), L->M(), pxNu, pyNu}; - Double_t par_step[7] = {0.1, 0., 0., 0., 0., 0., 0.}; - Double_t par_min[7] = {-3.15, 0., -3.15, 0., 0., -10000., -10000.}; - Double_t par_max[7] = {3.15, 1., 3.15, 10000., 80., 10000., 10000.}; - for (Int_t i = 0; i < 7; i++){ - fit->DefineParameter(i,par_name[i].c_str(),par_ival[i],par_step[i],par_min[i],par_max[i]); - if (i != 0){ + std::string par_name[7] = { + "alpha", "r", "dphi", "l_pt", "l_m", "n_px", "n_py" + }; + Double_t par_ival[7] = { + 0., (m_mWpdg * m_mWpdg - L->M() * L->M()) / (2 * ptNu), metphi - L->Phi(), L->Pt(), L->M(), pxNu, pyNu + }; + Double_t par_step[7] = { + 0.1, 0., 0., 0., 0., 0., 0. + }; + Double_t par_min[7] = { + -3.15, 0., -3.15, 0., 0., -10000., -10000. + }; + Double_t par_max[7] = { + 3.15, 1., 3.15, 10000., 80., 10000., 10000. + }; + for (Int_t i = 0; i < 7; i++) { + fit->DefineParameter(i, par_name[i].c_str(), par_ival[i], par_step[i], par_min[i], par_max[i]); + if (i != 0) { fit->FixParameter(i); } } @@ -92,27 +105,27 @@ double TtresNeutrinoBuilder::fitAlpha(const TLorentzVector* L, const Double_t me Double_t a, e_a; Int_t ret = fit->GetParameter(0, a, e_a); delete fit; - if (ret > 0){ + if (ret > 0) { return a; - } - else { + } else { std::cout << "Error in fit of alpha for met correction" << std::endl; return 0.; } - } - // In case of negative discriminant, decrease the MET //_________________________________________________________________________________________________ -std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Scaling(const TLorentzVector* L, const TLorentzVector* MET){ -return this->candidatesFromWMass_Scaling(L, MET->Px(), MET->Py()); +std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Scaling(const TLorentzVector* L, + const TLorentzVector* MET) { + return this->candidatesFromWMass_Scaling(L, MET->Px(), MET->Py()); } // In case of negative discriminant, decrease the MET //_________________________________________________________________________________________________ -std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Scaling(const TLorentzVector* L, const double met_etx, const double met_ety){ - if(m_debug>0) std::cout << "entering NeutrinoBuilder::candidatesFromWMass_Scaling()" << std::endl; +std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Scaling(const TLorentzVector* L, + const double met_etx, + const double met_ety) { + if (m_debug > 0) std::cout << "entering NeutrinoBuilder::candidatesFromWMass_Scaling()" << std::endl; std::vector<TLorentzVector*> NC; this->candidatesFromWMass_Scaling(L, met_etx, met_ety, NC); return NC; @@ -120,9 +133,9 @@ std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Scaling(c // In case of negative discriminant, decrease the MET //_________________________________________________________________________________________________ -bool TtresNeutrinoBuilder::candidatesFromWMass_Scaling(const TLorentzVector* L, const double met_etx, const double met_ety, std::vector<TLorentzVector*>& NC){ - - if(m_debug>0) std::cout << "entering NeutrinoBuilder::candidatesFromWMass_Scaling()" << std::endl; +bool TtresNeutrinoBuilder::candidatesFromWMass_Scaling(const TLorentzVector* L, const double met_etx, + const double met_ety, std::vector<TLorentzVector*>& NC) { + if (m_debug > 0) std::cout << "entering NeutrinoBuilder::candidatesFromWMass_Scaling()" << std::endl; // initialize double delta; double lambda; @@ -132,218 +145,220 @@ bool TtresNeutrinoBuilder::candidatesFromWMass_Scaling(const TLorentzVector* L, double alpha; double beta; double gamma; - double m_mWpdg=80.4 * m_Units; + double m_mWpdg = 80.4 * m_Units; int count = 0; - + pxNu = met_etx; pyNu = met_ety; do { // solve the quadratic equation ++count; - ptNu = sqrt (pxNu*pxNu + pyNu*pyNu); - alpha = pow(m_mWpdg,2)+pow((pxNu+L->Px()),2)+pow((pyNu+L->Py()),2)-pow(L->E(),2); - - beta = 0.5 * ( alpha-pow(ptNu,2)+pow(L->Pz(),2) ); - gamma = -( beta*beta - ( pow(L->E(),2)*pow(ptNu,2) ) ) / ( pow(L->E(),2)-pow(L->Pz(),2) ); - lambda = 2*beta*L->Pz() / (pow(L->E(),2)-pow(L->Pz(),2)); - delta = pow(lambda,2)-4*gamma; - if(m_debug>1) std::cout << "count = " << count << "\tptNu = " << ptNu << "\tdelta = " << delta << "\tm_mWpdg = " << m_mWpdg << std::endl; + ptNu = sqrt(pxNu * pxNu + pyNu * pyNu); + alpha = pow(m_mWpdg, 2) + pow((pxNu + L->Px()), 2) + pow((pyNu + L->Py()), 2) - pow(L->E(), 2); + + beta = 0.5 * (alpha - pow(ptNu, 2) + pow(L->Pz(), 2)); + gamma = -(beta * beta - (pow(L->E(), 2) * pow(ptNu, 2))) / (pow(L->E(), 2) - pow(L->Pz(), 2)); + lambda = 2 * beta * L->Pz() / (pow(L->E(), 2) - pow(L->Pz(), 2)); + delta = pow(lambda, 2) - 4 * gamma; + if (m_debug > + 1) std::cout << "count = " << count << "\tptNu = " << ptNu << "\tdelta = " << delta << "\tm_mWpdg = " << + m_mWpdg << + std::endl; // if no real solution, reduce Pt by 0.1 GeV and recompute pxNu & pyNu // in consequence - if (delta < 0){ - if(ptNu > 100. ){ - double Ptmiss = ptNu; - ptNu -= 100. ; - pxNu *= ptNu/Ptmiss; - pyNu *= ptNu/Ptmiss; - } + if (delta < 0) { + if (ptNu > 100.) { + double Ptmiss = ptNu; + ptNu -= 100.; + pxNu *= ptNu / Ptmiss; + pyNu *= ptNu / Ptmiss; + } } // end of case delta is negatively defined - - } while( (delta < 0) && (count < 10000) && ( ptNu > 20 *1000)); - if (delta < 0){ - if(m_debug>0) std::cout << "no solution delta still<0" << std::endl; return false; + } while ((delta < 0) && (count < 10000) && (ptNu > 20 * 1000)); + if (delta < 0) { + if (m_debug > 0) std::cout << "no solution delta still<0" << std::endl; + return false; } delta = sqrt(delta); // instantiate Neutrino - double pz = (lambda-delta)/2.0; - double e = sqrt(pxNu*pxNu+pyNu*pyNu+pz*pz); - TLorentzVector *nu1 = new TLorentzVector(pxNu,pyNu,pz,e); - pz = (lambda+delta)/2.0; - e = sqrt(pxNu*pxNu+pyNu*pyNu+pz*pz); - TLorentzVector *nu2 = new TLorentzVector(pxNu,pyNu,pz,e); + double pz = (lambda - delta) / 2.0; + double e = sqrt(pxNu * pxNu + pyNu * pyNu + pz * pz); + TLorentzVector* nu1 = new TLorentzVector(pxNu, pyNu, pz, e); + pz = (lambda + delta) / 2.0; + e = sqrt(pxNu * pxNu + pyNu * pyNu + pz * pz); + TLorentzVector* nu2 = new TLorentzVector(pxNu, pyNu, pz, e); NC.push_back(nu1); NC.push_back(nu2); - if(m_debug>0) std::cout << "quitting NeutrinoBuilder::candidatesFromWMass_Scaling()" << std::endl; + if (m_debug > 0) std::cout << "quitting NeutrinoBuilder::candidatesFromWMass_Scaling()" << std::endl; return true; } - - - - // In case of negative discriminant, decrese the MET //_________________________________________________________________________________________________ -std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Rotation(const TLorentzVector* L, const TLorentzVector* MET, const bool useSmallestPz){ - return this->candidatesFromWMass_Rotation(L, MET->Pt(), MET->Phi(), useSmallestPz); +std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Rotation(const TLorentzVector* L, + const TLorentzVector* MET, + const bool useSmallestPz) { + return this->candidatesFromWMass_Rotation(L, MET->Pt(), MET->Phi(), useSmallestPz); } // In case of negative discriminant, decrese the MET //_________________________________________________________________________________________________ -std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Rotation(const TLorentzVector* L, const Double_t met, const Double_t metphi, const bool useSmallestPz){ - if(m_debug>0) std::cout << "entering candidatesFromWMassRotation()" << std::endl; - - // initialize - Double_t m_mWpdg = 80.4 * m_Units; - Double_t pxNu = met * cos(metphi); - Double_t pyNu = met * sin(metphi); - Double_t pzNu = -1000000; - Double_t ptNu = met; - Double_t eNu; - - std::vector<TLorentzVector*> NC; - - Double_t c1 = m_mWpdg * m_mWpdg - L->M() * L->M() + 2 * (L->Px() * pxNu + L->Py() * pyNu); - Double_t b1 = 2 * L->Pz(); - - Double_t A = 4 * pow(L->E(), 2) - b1 * b1; - Double_t B = -2 * c1 * b1; - Double_t C = 4 * pow(L->E(), 2) * ptNu * ptNu - c1 * c1; - Double_t discr = B*B - 4*A*C; - Double_t r = 1; - - Double_t sol1, sol2; - if (discr > 0){ - sol1 = (-B + sqrt(discr)) / (2*A); - sol2 = (-B - sqrt(discr)) / (2*A); - } - else { - Double_t alpha = fitAlpha(L, met, metphi); - Double_t dphi = metphi - L->Phi(); - r = ( pow(m_mWpdg,2) - pow(L->M(),2) ) / (2 * ptNu * (sqrt(pow(L->Pt(),2) + pow(L->M(),2)) - L->Pt() * cos(dphi + alpha))); - - Double_t old_p = ptNu; - Double_t old_phi = metphi; - pxNu = r * old_p * cos(old_phi + alpha); - pyNu = r * old_p * sin(old_phi + alpha); - ptNu = sqrt (pxNu*pxNu + pyNu*pyNu); - - c1 = m_mWpdg * m_mWpdg - pow(L->M(),2) + 2 * (L->Px() * pxNu + L->Py() * pyNu); - B = -2 * c1 * b1; - C = 4 * pow(L->E(),2) * ptNu * ptNu - c1 * c1; - discr = B*B - 4*A*C; - - sol1 = -B / (2*A); - sol2 = -B / (2*A); - } - - if (useSmallestPz){ - - pzNu = (fabs(sol1) > fabs(sol2)) ? sol2 : sol1; - - eNu = sqrt(pxNu*pxNu + pyNu*pyNu + pzNu*pzNu); - TLorentzVector *nu1 = new TLorentzVector(pxNu,pyNu,pzNu,eNu); - NC.push_back(nu1); - - }else{ - - pzNu = sol1; - eNu = sqrt(pxNu*pxNu + pyNu*pyNu + pzNu*pzNu); - TLorentzVector *nu1 = new TLorentzVector(pxNu,pyNu,pzNu,eNu); - pzNu = sol2; - eNu = sqrt(pxNu*pxNu + pyNu*pyNu + pzNu*pzNu); - TLorentzVector *nu2 = new TLorentzVector(pxNu,pyNu,pzNu,eNu); - NC.push_back(nu1); - NC.push_back(nu2); - - } +std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_Rotation(const TLorentzVector* L, + const Double_t met, + const Double_t metphi, + const bool useSmallestPz) { + if (m_debug > 0) std::cout << "entering candidatesFromWMassRotation()" << std::endl; - if(m_debug>0) std::cout << "quitting NeutrinoBuilder::candidatesFromWMassRotation() : " << NC.size() << std::endl; - return NC; + // initialize + Double_t m_mWpdg = 80.4 * m_Units; + Double_t pxNu = met * cos(metphi); + Double_t pyNu = met * sin(metphi); + Double_t pzNu = -1000000; + Double_t ptNu = met; + Double_t eNu; + + std::vector<TLorentzVector*> NC; + + Double_t c1 = m_mWpdg * m_mWpdg - L->M() * L->M() + 2 * (L->Px() * pxNu + L->Py() * pyNu); + Double_t b1 = 2 * L->Pz(); + + Double_t A = 4 * pow(L->E(), 2) - b1 * b1; + Double_t B = -2 * c1 * b1; + Double_t C = 4 * pow(L->E(), 2) * ptNu * ptNu - c1 * c1; + Double_t discr = B * B - 4 * A * C; + Double_t r = 1; + + Double_t sol1, sol2; + if (discr > 0) { + sol1 = (-B + sqrt(discr)) / (2 * A); + sol2 = (-B - sqrt(discr)) / (2 * A); + } else { + Double_t alpha = fitAlpha(L, met, metphi); + Double_t dphi = metphi - L->Phi(); + r = + (pow(m_mWpdg, + 2) - pow(L->M(), 2)) / (2 * ptNu * (sqrt(pow(L->Pt(), 2) + pow(L->M(), 2)) - L->Pt() * cos(dphi + alpha))); + + Double_t old_p = ptNu; + Double_t old_phi = metphi; + pxNu = r * old_p * cos(old_phi + alpha); + pyNu = r * old_p * sin(old_phi + alpha); + ptNu = sqrt(pxNu * pxNu + pyNu * pyNu); + + c1 = m_mWpdg * m_mWpdg - pow(L->M(), 2) + 2 * (L->Px() * pxNu + L->Py() * pyNu); + B = -2 * c1 * b1; + C = 4 * pow(L->E(), 2) * ptNu * ptNu - c1 * c1; + discr = B * B - 4 * A * C; + + sol1 = -B / (2 * A); + sol2 = -B / (2 * A); + } + + if (useSmallestPz) { + pzNu = (fabs(sol1) > fabs(sol2)) ? sol2 : sol1; + + eNu = sqrt(pxNu * pxNu + pyNu * pyNu + pzNu * pzNu); + TLorentzVector* nu1 = new TLorentzVector(pxNu, pyNu, pzNu, eNu); + NC.push_back(nu1); + } else { + pzNu = sol1; + eNu = sqrt(pxNu * pxNu + pyNu * pyNu + pzNu * pzNu); + TLorentzVector* nu1 = new TLorentzVector(pxNu, pyNu, pzNu, eNu); + pzNu = sol2; + eNu = sqrt(pxNu * pxNu + pyNu * pyNu + pzNu * pzNu); + TLorentzVector* nu2 = new TLorentzVector(pxNu, pyNu, pzNu, eNu); + NC.push_back(nu1); + NC.push_back(nu2); + } + + if (m_debug > 0) std::cout << "quitting NeutrinoBuilder::candidatesFromWMassRotation() : " << NC.size() << std::endl; + return NC; } // In case of negative discriminant, use the real part //_________________________________________________________________________________________________ -std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_RealPart(const TLorentzVector* L, const TLorentzVector* MET, const bool useSmallestPz){ - return this->candidatesFromWMass_RealPart(L, MET->Pt(), MET->Phi(), useSmallestPz); +std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_RealPart(const TLorentzVector* L, + const TLorentzVector* MET, + const bool useSmallestPz) { + return this->candidatesFromWMass_RealPart(L, MET->Pt(), MET->Phi(), useSmallestPz); } + // In case of negative discriminant, use the real part //_________________________________________________________________________________________________ -std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_RealPart(const TLorentzVector* L, Double_t met, Double_t metphi, const bool useSmallestPz){ - if(m_debug>0) std::cout << "entering candidatesFromWMass_RealPart()" << std::endl; - - // initialize - Double_t m_mWpdg = 80.4 * m_Units; - Double_t pxNu = met * cos(metphi); - Double_t pyNu = met * sin(metphi); - Double_t pzNu = -1000000; - Double_t ptNu = met; - Double_t eNu; - - std::vector<TLorentzVector*> NC; - - Double_t c1 = m_mWpdg * m_mWpdg - L->M() * L->M() + 2 * (L->Px() * pxNu + L->Py() * pyNu); - Double_t b1 = 2 * L->Pz(); - - Double_t A = 4 * pow(L->E(), 2) - b1 * b1; - Double_t B = -2 * c1 * b1; - Double_t C = 4 * pow(L->E(), 2) * ptNu * ptNu - c1 * c1; - Double_t discr = B*B - 4*A*C; - - Double_t sol1, sol2; - if (discr > 0){ - sol1 = (-B + sqrt(discr)) / (2*A); - sol2 = (-B - sqrt(discr)) / (2*A); - } - //if discr<0 - else { - pzNu = -B / (2*A); - - eNu = sqrt(pxNu*pxNu + pyNu*pyNu + pzNu*pzNu); - TLorentzVector *nu1 = new TLorentzVector(pxNu,pyNu,pzNu,eNu); - NC.push_back(nu1); - return NC; - } - - if (useSmallestPz){ - - pzNu = (fabs(sol1) > fabs(sol2)) ? sol2 : sol1; - - eNu = sqrt(pxNu*pxNu + pyNu*pyNu + pzNu*pzNu); - TLorentzVector *nu1 = new TLorentzVector(pxNu,pyNu,pzNu,eNu); - NC.push_back(nu1); - - }else{ - - pzNu = sol1; - eNu = sqrt(pxNu*pxNu + pyNu*pyNu + pzNu*pzNu); - TLorentzVector *nu1 = new TLorentzVector(pxNu,pyNu,pzNu,eNu); - pzNu = sol2; - eNu = sqrt(pxNu*pxNu + pyNu*pyNu + pzNu*pzNu); - TLorentzVector *nu2 = new TLorentzVector(pxNu,pyNu,pzNu,eNu); - NC.push_back(nu1); - NC.push_back(nu2); - - } +std::vector<TLorentzVector*> TtresNeutrinoBuilder::candidatesFromWMass_RealPart(const TLorentzVector* L, Double_t met, + Double_t metphi, + const bool useSmallestPz) { + if (m_debug > 0) std::cout << "entering candidatesFromWMass_RealPart()" << std::endl; + + // initialize + Double_t m_mWpdg = 80.4 * m_Units; + Double_t pxNu = met * cos(metphi); + Double_t pyNu = met * sin(metphi); + Double_t pzNu = -1000000; + Double_t ptNu = met; + Double_t eNu; + + std::vector<TLorentzVector*> NC; + + Double_t c1 = m_mWpdg * m_mWpdg - L->M() * L->M() + 2 * (L->Px() * pxNu + L->Py() * pyNu); + Double_t b1 = 2 * L->Pz(); + + Double_t A = 4 * pow(L->E(), 2) - b1 * b1; + Double_t B = -2 * c1 * b1; + Double_t C = 4 * pow(L->E(), 2) * ptNu * ptNu - c1 * c1; + Double_t discr = B * B - 4 * A * C; + + Double_t sol1, sol2; + if (discr > 0) { + sol1 = (-B + sqrt(discr)) / (2 * A); + sol2 = (-B - sqrt(discr)) / (2 * A); + } + //if discr<0 + else { + pzNu = -B / (2 * A); - if(m_debug>0) std::cout << "quitting NeutrinoBuilder::candidatesFromWMass_RealPart() : " << NC.size() << std::endl; + eNu = sqrt(pxNu * pxNu + pyNu * pyNu + pzNu * pzNu); + TLorentzVector* nu1 = new TLorentzVector(pxNu, pyNu, pzNu, eNu); + NC.push_back(nu1); return NC; -} + } + + if (useSmallestPz) { + pzNu = (fabs(sol1) > fabs(sol2)) ? sol2 : sol1; -Double_t TtresNeutrinoBuilder::getDiscriminant(const TLorentzVector* L, Double_t met, Double_t metphi){ - - // initialize - Double_t m_mWpdg = 80.4 * m_Units; - Double_t pxNu = met * cos(metphi); - Double_t pyNu = met * sin(metphi); - Double_t ptNu = met; - - Double_t c1 = m_mWpdg * m_mWpdg - L->M() * L->M() + 2 * (L->Px() * pxNu + L->Py() * pyNu); - Double_t b1 = 2 * L->Pz(); - - Double_t A = 4 * pow(L->E(), 2) - b1 * b1; - Double_t B = -2 * c1 * b1; - Double_t C = 4 * pow(L->E(), 2) * ptNu * ptNu - c1 * c1; - Double_t discr = B*B - 4*A*C; - return discr; + eNu = sqrt(pxNu * pxNu + pyNu * pyNu + pzNu * pzNu); + TLorentzVector* nu1 = new TLorentzVector(pxNu, pyNu, pzNu, eNu); + NC.push_back(nu1); + } else { + pzNu = sol1; + eNu = sqrt(pxNu * pxNu + pyNu * pyNu + pzNu * pzNu); + TLorentzVector* nu1 = new TLorentzVector(pxNu, pyNu, pzNu, eNu); + pzNu = sol2; + eNu = sqrt(pxNu * pxNu + pyNu * pyNu + pzNu * pzNu); + TLorentzVector* nu2 = new TLorentzVector(pxNu, pyNu, pzNu, eNu); + NC.push_back(nu1); + NC.push_back(nu2); + } + + if (m_debug > 0) std::cout << "quitting NeutrinoBuilder::candidatesFromWMass_RealPart() : " << NC.size() << std::endl; + + return NC; } +Double_t TtresNeutrinoBuilder::getDiscriminant(const TLorentzVector* L, Double_t met, Double_t metphi) { + // initialize + Double_t m_mWpdg = 80.4 * m_Units; + Double_t pxNu = met * cos(metphi); + Double_t pyNu = met * sin(metphi); + Double_t ptNu = met; + + Double_t c1 = m_mWpdg * m_mWpdg - L->M() * L->M() + 2 * (L->Px() * pxNu + L->Py() * pyNu); + Double_t b1 = 2 * L->Pz(); + + Double_t A = 4 * pow(L->E(), 2) - b1 * b1; + Double_t B = -2 * c1 * b1; + Double_t C = 4 * pow(L->E(), 2) * ptNu * ptNu - c1 * c1; + Double_t discr = B * B - 4 * A * C; + + return discr; +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresdRmin.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresdRmin.cxx index 551fa4518b13..80c542ae0bbe 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresdRmin.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/Root/TtresdRmin.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ /////////////////////////////////////////////////////////////////////////////////// // // @@ -33,54 +33,50 @@ // Class constructor // TtresdRmin::TtresdRmin(TString units, bool verbose) { - m_init = false; m_verbose = verbose; - if(units == "MeV") { + if (units == "MeV") { m_Units = 1000.0; - } else if(units == "GeV") { + } else if (units == "GeV") { m_Units = 1.0; } else { - cout << " ERROR in in TtresdRmin :: Unit setting '" << units << "' doest not match pattern of GeV or MeV" << endl; + cout << " ERROR in in TtresdRmin :: Unit setting '" << units << "' doest not match pattern of GeV or MeV" << endl; } } - //========================================================================================================== // Initialize parameters for tool // void TtresdRmin::Init(double highJetMass, double minJetPt, double dRCutOffset, double dRCutMassFactor) { //Set parameters - m_highM = highJetMass; - m_minJetPt = minJetPt; - m_dRCutOffset = dRCutOffset; + m_highM = highJetMass; + m_minJetPt = minJetPt; + m_dRCutOffset = dRCutOffset; m_dRCutMassFactor = dRCutMassFactor; //Reset m_jet_indices.clear(); m_highMassJetIndex = -1; - m_highestJetMass = 0.0; + m_highestJetMass = 0.0; //Initialization status m_init = true; } - //========================================================================================================== // Setup event with kinematic objects // -bool TtresdRmin::SetupEvent(vector<TLorentzVector*> &jets, TLorentzVector &lepton, TLorentzVector &neutrino) { - - if(!m_init) { +bool TtresdRmin::SetupEvent(vector<TLorentzVector*>& jets, TLorentzVector& lepton, TLorentzVector& neutrino) { + if (!m_init) { cout << " ERROR in TtresdRmin :: Tool not initialized! Initialize tool before usage!!!" << endl; return false; } //Set objects - m_jets = jets; - m_lepton = lepton; - m_neutrino = neutrino; + m_jets = jets; + m_lepton = lepton; + m_neutrino = neutrino; m_Wleptonic = lepton + neutrino; //Reset @@ -90,24 +86,23 @@ bool TtresdRmin::SetupEvent(vector<TLorentzVector*> &jets, TLorentzVector &lepto //===== Search for high mass jet ===== - int highMJetIdx = -1; //Index of jet with highest mass above threshold - double highM = m_highM*m_Units; //Threshold for high mass jet - double minJetPt = m_minJetPt*m_Units; //Threshold for jet pT + int highMJetIdx = -1; //Index of jet with highest mass above threshold + double highM = m_highM * m_Units; //Threshold for high mass jet + double minJetPt = m_minJetPt * m_Units; //Threshold for jet pT //Loop jets - for(int ijet = 0; ijet < (int)jets.size(); ijet++) { - + for (int ijet = 0; ijet < (int) jets.size(); ijet++) { //pT requirmenet - if(jets.at(ijet)->Pt() <= minJetPt) continue; //next jet + if (jets.at(ijet)->Pt() <= minJetPt) continue; //next jet //high mass requirement - if(jets.at(ijet)->M() <= highM) continue; //next jet + if (jets.at(ijet)->M() <= highM) continue; //next jet highMJetIdx = ijet; highM = jets.at(ijet)->M(); }//end of jet loop - if(highMJetIdx >= 0) { + if (highMJetIdx >= 0) { m_highMassJetIndex = highMJetIdx; m_highestJetMass = highM; FindJetIndices_HM(); @@ -118,17 +113,15 @@ bool TtresdRmin::SetupEvent(vector<TLorentzVector*> &jets, TLorentzVector &lepto return true; } - //========================================================================================================== // Get invariant ttbar mass // double TtresdRmin::GetMttdRmin() { - double mtt_dRmin = 0.0; - if(m_jet_indices.size() > 0) { - TLorentzVector dRsumJet(0,0,0,0); - for(unsigned int ijet = 0; ijet < m_jet_indices.size(); ijet++) { + if (m_jet_indices.size() > 0) { + TLorentzVector dRsumJet(0, 0, 0, 0); + for (unsigned int ijet = 0; ijet < m_jet_indices.size(); ijet++) { dRsumJet += *(m_jets.at(m_jet_indices.at(ijet))); } mtt_dRmin = (dRsumJet + m_Wleptonic).M(); @@ -141,12 +134,11 @@ double TtresdRmin::GetMttdRmin() { // Get ttbar system TLorentzVector // TLorentzVector TtresdRmin::GetTlvdRmin() { + TLorentzVector tt_dRmin(0, 0, 0, 0); - TLorentzVector tt_dRmin(0,0,0,0); - - if(m_jet_indices.size() > 0) { - TLorentzVector dRsumJet(0,0,0,0); - for(unsigned int ijet = 0; ijet < (unsigned int)m_jet_indices.size(); ijet++) { + if (m_jet_indices.size() > 0) { + TLorentzVector dRsumJet(0, 0, 0, 0); + for (unsigned int ijet = 0; ijet < (unsigned int) m_jet_indices.size(); ijet++) { dRsumJet += *(m_jets.at(m_jet_indices.at(ijet))); } tt_dRmin = dRsumJet + m_Wleptonic; @@ -155,21 +147,19 @@ TLorentzVector TtresdRmin::GetTlvdRmin() { return tt_dRmin; } - //========================================================================================================== // Find jet indices for reconstruction for events with a high mass jet // bool TtresdRmin::FindJetIndices_HM() { - //===== Find closest jet to high mass jet ===== double dR_had = 999.9; int closest_jetIdx_had = -1; //Loop m_jets - for(int ijet = 0; ijet < (int)m_jets.size(); ijet++) { - if(ijet == m_highMassJetIndex) continue; //next jet + for (int ijet = 0; ijet < (int) m_jets.size(); ijet++) { + if (ijet == m_highMassJetIndex) continue; //next jet double dR = m_jets.at(m_highMassJetIndex)->DeltaR(*(m_jets.at(ijet))); - if(dR < dR_had) { + if (dR < dR_had) { closest_jetIdx_had = ijet; dR_had = dR; } @@ -181,11 +171,11 @@ bool TtresdRmin::FindJetIndices_HM() { int closest_jetIdx_lep = -1; //Loop jets - for(int ijet = 0; ijet < (int)m_jets.size(); ijet++) { - if(ijet == m_highMassJetIndex) continue; //next jet - if(ijet == closest_jetIdx_had) continue; //next jet + for (int ijet = 0; ijet < (int) m_jets.size(); ijet++) { + if (ijet == m_highMassJetIndex) continue; //next jet + if (ijet == closest_jetIdx_had) continue; //next jet double dR = m_Wleptonic.DeltaR(*(m_jets.at(ijet))); - if(dR < dR_lep) { + if (dR < dR_lep) { closest_jetIdx_lep = ijet; dR_lep = dR; } @@ -194,35 +184,33 @@ bool TtresdRmin::FindJetIndices_HM() { //===== Save jet indices used for reconstruction ===== m_jet_indices.push_back(m_highMassJetIndex); - if(closest_jetIdx_had >= 0){ + if (closest_jetIdx_had >= 0) { m_jet_indices.push_back(closest_jetIdx_had); } else { - if(m_verbose) cout << " WARNING in TtresdRmin :: Can not find jet close to high mass jet" << endl; + if (m_verbose) cout << " WARNING in TtresdRmin :: Can not find jet close to high mass jet" << endl; } - if(closest_jetIdx_lep >= 0) { + if (closest_jetIdx_lep >= 0) { m_jet_indices.push_back(closest_jetIdx_lep); } else { - if(m_verbose) cout << " WARNING in TtresdRmin :: Can not find jet close to leptonic W-boson" << endl; + if (m_verbose) cout << " WARNING in TtresdRmin :: Can not find jet close to leptonic W-boson" << endl; } return true; } - //========================================================================================================== // Find jet indices for reconstruction for events without a high mass jet // bool TtresdRmin::FindJetIndices_LM() { - //jetflag vector to flag jets rejected by dRmin method vector<bool> jetflags(m_jets.size(), true); //do dRmin procedure if at least 4 jets are available - bool repeat_dRmin = ((int)m_jets.size() > 3); + bool repeat_dRmin = ((int) m_jets.size() > 3); //Loop dRmin method - while(repeat_dRmin) { + while (repeat_dRmin) { repeat_dRmin = false; double dR_max = 0.0; //Maximum dR passing dRmin cut requirement @@ -232,12 +220,11 @@ bool TtresdRmin::FindJetIndices_LM() { int nijet = 0; //Outer jet loop - for(int ijet = 0; ijet < (int)m_jets.size(); ijet++) { - - if(!jetflags.at(ijet)) continue; //next outer jet + for (int ijet = 0; ijet < (int) m_jets.size(); ijet++) { + if (!jetflags.at(ijet)) continue; //next outer jet //Use maximum of 4 goodflagged jets - if(nijet > 3) break; + if (nijet > 3) break; nijet++; double dR_min = 999.9; @@ -249,45 +236,44 @@ bool TtresdRmin::FindJetIndices_LM() { int njjet = 0; //Inner jet loop - for(int jjet = 0; jjet < (int)m_jets.size(); jjet++) { + for (int jjet = 0; jjet < (int) m_jets.size(); jjet++) { + if (!jetflags.at(jjet)) continue; //next inner jet - if(!jetflags.at(jjet)) continue; //next inner jet + //Use maximum of 4 goodflagged jets + if (njjet > 3) break; + njjet++; - //Use maximum of 4 goodflagged jets - if(njjet > 3) break; - njjet++; + if (jjet == ijet) continue; //next inner jet - if(jjet == ijet) continue; //next inner jet - - double dR_jet = m_jets.at(ijet)->DeltaR(*(m_jets.at(jjet))); - if(dR_jet < dR_min){ - dR_min = dR_jet; - } + double dR_jet = m_jets.at(ijet)->DeltaR(*(m_jets.at(jjet))); + if (dR_jet < dR_min) { + dR_min = dR_jet; + } } //end of inner jet loop - if(dR_min > dR_max) { - //dRmin specific cut (defined for GeV, needs m_Units correction on mass) - double dR_cut = m_dRCutOffset - m_dRCutMassFactor * m_jets.at(ijet)->M()/m_Units; - if(dR_min > dR_cut) { - dR_max = dR_min; - index_max = ijet; - } + if (dR_min > dR_max) { + //dRmin specific cut (defined for GeV, needs m_Units correction on mass) + double dR_cut = m_dRCutOffset - m_dRCutMassFactor * m_jets.at(ijet)->M() / m_Units; + if (dR_min > dR_cut) { + dR_max = dR_min; + index_max = ijet; + } } }//end of outer jet loop - if(index_max >= 0) { + if (index_max >= 0) { jetflags.at(index_max) = false; - if(count(jetflags.begin(), jetflags.end(), true) > 3) repeat_dRmin = true; + if (count(jetflags.begin(), jetflags.end(), true) > 3) repeat_dRmin = true; } }//end of while(repeat) int nijet = 0; //Save selected jet indices - for(int ijet = 0; ijet < (int)m_jets.size(); ijet++) { - if(!jetflags.at(ijet)) continue; //next jet + for (int ijet = 0; ijet < (int) m_jets.size(); ijet++) { + if (!jetflags.at(ijet)) continue; //next jet //Use maximum of 4 goodflagged jets - if(nijet > 3) break; + if (nijet > 3) break; nijet++; m_jet_indices.push_back(ijet); @@ -295,4 +281,3 @@ bool TtresdRmin::FindJetIndices_LM() { return true; } - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/Chi2LJets.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/Chi2LJets.h index def6b3cce0d9..c377b6ab9c59 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/Chi2LJets.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/Chi2LJets.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef CHI2LJETS_H_ #define CHI2LJETS_H_ @@ -12,13 +12,13 @@ class TMinuit; namespace top { -class Event; + class Event; /** * @brief Hold the information that is required for the chi^2 minimisation */ -class FitInfo : public TObject { -public: + class FitInfo: public TObject { + public: ///Mass of the hadronic W (j+j) double hadronic_w_mass; @@ -36,28 +36,27 @@ public: ///Four vector of the jet that we think is the leptonic b quark TLorentzVector leptonic_b; -}; + }; /** * @brief Not complete. Work in progress */ -class Chi2LJets : public EventSelectorBase { -public: + class Chi2LJets: public EventSelectorBase { + public: Chi2LJets(); virtual ~Chi2LJets(); virtual bool apply(const top::Event&) const override; - std::string name() const { return "RECO:CHI2LJETS"; } - -private: + std::string name() const override {return "RECO:CHI2LJETS";} + private: ///So we can do a minimisation TMinuit* min; mutable FitInfo params; //so the fcn function can see them -public: + public: ///The top mass that we're using as the baseline - used in chi2 function. static const double input_topmass; @@ -69,8 +68,7 @@ public: ///The W resolution that we're using as the baseline - used in chi2 function. static const double input_wsigma; -}; - + }; } void fcn(int& npar, double* deriv, double& result, double par[], int flag); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/KLFitterRun.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/KLFitterRun.h index f11c5c282194..d2c1ddc0d727 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/KLFitterRun.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/KLFitterRun.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: KLFitterRun.h 688037 2015-08-07 01:24:06Z morrisj $ #ifndef ANALYSISTOP_TOPEVENTRECONSTRCUTIONTOOLS_KLFITTERRUN_H @@ -9,23 +9,22 @@ #include "TopEventSelectionTools/EventSelectorBase.h" #include "TopEventReconstructionTools/KLFitterTool.h" -namespace top{ +namespace top { class Event; class TopConfig; - - class KLFitterRun : public EventSelectorBase { - public: - KLFitterRun(const std::string& kLeptonType,std::shared_ptr<top::TopConfig> config); - virtual ~KLFitterRun(){} - - virtual bool apply(const top::Event&) const override; - std::string name() const; - - private: - std::string m_name; - std::unique_ptr<top::KLFitterTool> m_myFitter; - + class KLFitterRun: public EventSelectorBase { + public: + KLFitterRun(const std::string& kSelectionName, const std::string& kParameters, + std::shared_ptr<top::TopConfig> config); + virtual ~KLFitterRun() {} + + virtual bool apply(const top::Event&) const override; + std::string name() const override; + private: + std::string m_name; + + std::unique_ptr<top::KLFitterTool> m_myFitter; }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/KLFitterTool.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/KLFitterTool.h index 8d28f4c22a68..ad8e92cec34c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/KLFitterTool.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/KLFitterTool.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ // $Id: KLFitterTool.h 788027 2016-12-04 18:30:45Z aknue $ #ifndef ANALYSISTOP_TOPEVENTRECONSTRCUTIONTOOLS_KLFITTERTOOL_H @@ -8,13 +8,20 @@ // Framework include(s): #include "AsgTools/AsgTool.h" -#include "xAODBTaggingEfficiency/IBTaggingEfficiencyTool.h" +#include "FTagAnalysisInterfaces/IBTaggingEfficiencyTool.h" +#include "xAODJet/JetContainer.h" +#include "xAODJet/JetAuxContainer.h" +#include "TopConfiguration/Tokenize.h" // KLFitter include(s): #include "KLFitter/Fitter.h" #include "KLFitter/LikelihoodTopLeptonJets.h" #include "KLFitter/LikelihoodTTHLeptonJets.h" +#include "KLFitter/LikelihoodTopLeptonJets_JetAngles.h" +#include "KLFitter/LikelihoodTTZTrilepton.h" +#include "KLFitter/LikelihoodTopAllHadronic.h" +#include "KLFitter/BoostedLikelihoodTopLeptonJets.h" #include "KLFitter/PhysicsConstants.h" #include "KLFitter/LikelihoodBase.h" #include "KLFitter/DetectorAtlas_8TeV.h" @@ -28,86 +35,110 @@ #include <memory> - /// - /// @author John Morris <john.morris@cern.ch> - /// - /// $Revision: 788027 $ - /// $Date: 2016-12-04 19:30:45 +0100 (Sun, 04 Dec 2016) $ - /// - /// @brief Interface to KLFitter - /// - +/// +/// @author John Morris <john.morris@cern.ch> +/// +/// $Revision: 788027 $ +/// $Date: 2016-12-04 18:30:45 +0000 (Sun, 04 Dec 2016) $ +/// +/// @brief Interface to KLFitter +/// + // Forware declare -namespace KLFitter{ +namespace KLFitter { class Particles; } -namespace top{ +namespace top { class Event; class TopConfig; - + /// Some additional enums - namespace KLFitterJetSelection{ - enum JetSelectionMode{ kLeadingFour , kLeadingFive , kLeadingSix, kBtagPriorityFourJets , kBtagPriorityFiveJets , kBtagPrioritySixJets}; + namespace KLFitterJetSelection { + enum JetSelectionMode { + kLeadingThree, kLeadingFour, kLeadingFive, kLeadingSix, + kLeadingSeven, kLeadingEight, kBtagPriorityThreeJets, + kBtagPriorityFourJets, kBtagPriorityFiveJets, kBtagPrioritySixJets, + kBtagPrioritySevenJets, kBtagPriorityEightJets + }; } - - - class KLFitterTool final : public asg::AsgTool { - - public: - /// Constructor - explicit KLFitterTool( const std::string& name ); - /// Destructor - virtual ~KLFitterTool(){} - - /// Function initialising the tool - virtual StatusCode initialize(); - /// Function executing the tool - virtual StatusCode execute(const top::Event&); - /// Function finalizing the tool - virtual StatusCode finalize(); - - private: - - // set jets depending on selection mode - void setJets(const top::Event&,KLFitter::Particles* inputParticles); - void setJetskLeadingFour(const top::Event&,KLFitter::Particles* inputParticles); - void setJetskLeadingFive(const top::Event&,KLFitter::Particles* inputParticles); - void setJetskLeadingSix(const top::Event&,KLFitter::Particles* inputParticles); - - void setJetskLeadingX(const top::Event& event,KLFitter::Particles* inputParticles, int); - - - void setJetskBtagPriorityFourJets(const top::Event&,KLFitter::Particles* inputParticles); - void setJetskBtagPriorityFiveJets(const top::Event&,KLFitter::Particles* inputParticles); - void setJetskBtagPrioritySixJets(const top::Event&,KLFitter::Particles* inputParticles); - - void setJetskBtagPriority(const top::Event&,KLFitter::Particles* inputParticles,const unsigned int maxJets); - - // configuration - std::shared_ptr<top::TopConfig> m_config; - float m_massTop; - float m_bTagCutValue; - - // Tools and functions for btagging - ToolHandle<IBTaggingEfficiencyTool> m_btagging_eff_tool; - bool HasTag(const xAOD::Jet& jet, double& weight) const; - void retrieveEfficiencies(const xAOD::Jet& jet, float* efficiency, float* inefficiency); - - /// KLFitter parameters, to be set by input file - std::string m_transferFunctionsPathPrefix; - std::string m_transferFunctionsPath; - - std::string m_leptonType; - std::string m_LHType; - KLFitter::LikelihoodTopLeptonJets::LeptonType m_leptonTypeKLFitterEnum; - KLFitter::LikelihoodTTHLeptonJets::LeptonType m_leptonTypeKLFitterEnum_TTH; - top::KLFitterJetSelection::JetSelectionMode m_jetSelectionModeKLFitterEnum; - KLFitter::LikelihoodBase::BtaggingMethod m_bTaggingMethodKLFitterEnum; - - /// The KLFitter - std::unique_ptr<KLFitter::Fitter> m_myFitter; - + + + class KLFitterTool final: public asg::AsgTool { + public: + /// Constructor + explicit KLFitterTool(const std::string& name); + /// Destructor + virtual ~KLFitterTool() {} + + /// Function initialising the tool + virtual StatusCode initialize(); + /// Function executing the tool + virtual StatusCode execute(const top::Event&); + /// Function finalizing the tool + virtual StatusCode finalize(); + private: + // set jets depending on selection mode + bool setJets(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskLeadingThree(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskLeadingFour(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskLeadingFive(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskLeadingSix(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskLeadingSeven(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskLeadingEight(const top::Event&, KLFitter::Particles* inputParticles); + + bool setJetskLeadingX(const top::Event& event, KLFitter::Particles* inputParticles, const unsigned int); + + + bool setJetskBtagPriorityThreeJets(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskBtagPriorityFourJets(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskBtagPriorityFiveJets(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskBtagPrioritySixJets(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskBtagPrioritySevenJets(const top::Event&, KLFitter::Particles* inputParticles); + bool setJetskBtagPriorityEightJets(const top::Event&, KLFitter::Particles* inputParticles); + + bool setJetskBtagPriority(const top::Event&, KLFitter::Particles* inputParticles, const unsigned int maxJets); + + // configuration + std::shared_ptr<top::TopConfig> m_config; + float m_massTop; + float m_bTagCutValue; + bool m_isWorkingPoint; + bool findOption(std::vector<std::string> full_options, std::string option, std::string& op_value); + + // Tools and functions for btagging + ToolHandle<IBTaggingEfficiencyTool> m_btagging_eff_tool; + bool HasTag(const xAOD::Jet& jet, double& weight) const; + void retrieveEfficiencies(const xAOD::Jet& jet, float* efficiency, float* inefficiency); + + /// KLFitter parameters, to be set by input file + std::string m_transferFunctionsPathPrefix; + std::string m_transferFunctionsPath; + + std::string m_selectionName; + std::string m_leptonType; + std::string m_customParameters; + std::string m_LHType; + KLFitter::LikelihoodTopLeptonJets::LeptonType m_leptonTypeKLFitterEnum; + KLFitter::LikelihoodTTHLeptonJets::LeptonType m_leptonTypeKLFitterEnum_TTH; + KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType m_leptonTypeKLFitterEnum_JetAngles; + KLFitter::LikelihoodTTZTrilepton::LeptonType m_leptonTypeKLFitterEnum_TTZ; + KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType m_leptonTypeKLFitterEnum_BoostedLJets; + + std::unique_ptr<KLFitter::LikelihoodTopLeptonJets> m_myLikelihood; + std::unique_ptr<KLFitter::LikelihoodTTHLeptonJets> m_myLikelihood_TTH; + std::unique_ptr<KLFitter::LikelihoodTopLeptonJets_JetAngles> m_myLikelihood_JetAngles; + std::unique_ptr<KLFitter::LikelihoodTTZTrilepton> m_myLikelihood_TTZ; + std::unique_ptr<KLFitter::LikelihoodTopAllHadronic> m_myLikelihood_AllHadronic; + std::unique_ptr<KLFitter::BoostedLikelihoodTopLeptonJets> m_myLikelihood_BoostedLJets; + + std::unique_ptr<KLFitter::DetectorAtlas_8TeV> m_myDetector; + + top::KLFitterJetSelection::JetSelectionMode m_jetSelectionModeKLFitterEnum; + KLFitter::LikelihoodBase::BtaggingMethod m_bTaggingMethodKLFitterEnum; + + /// The KLFitter + std::unique_ptr<KLFitter::Fitter> m_myFitter; }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/MT2Reco.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/MT2Reco.h index 21730795c365..314c63949211 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/MT2Reco.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/MT2Reco.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef MT2RECO_H_ #define MT2RECO_H_ @@ -10,21 +10,20 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { -class Event; + class Event; /** * @brief Not complete. Work in progress */ -class MT2Reco : public EventSelectorBase { -public: + class MT2Reco: public EventSelectorBase { + public: MT2Reco(); virtual ~MT2Reco(); virtual bool apply(const top::Event&) const override; - std::string name() const { return "RECO:MT2"; } -}; - + std::string name() const {return "RECO:MT2";} + }; } #endif //ROOTCORE_PACKAGE_Oxbridgekinetics diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/NeutrinoWeighting.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/NeutrinoWeighting.h index 1a4a6ea63d93..1cf81a31c528 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/NeutrinoWeighting.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/NeutrinoWeighting.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NEUTRINOWEIGHTING_H_ #define NEUTRINOWEIGHTING_H_ @@ -8,7 +8,7 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { -class Event; + class Event; /** * @brief Holds the two solutions from the quadratic equation as TLorentVectors. @@ -16,31 +16,31 @@ class Event; * Filled when solving the quadratic equation to calculate the 4 Vectors for * the two neutrinos in the event. */ -class NWSolution { -public: + class NWSolution { + public: void setSolutions(int num, const TLorentzVector& a, const TLorentzVector& b) { - m_v1 = a; - m_v2 = b; - m_solutions = num; + m_v1 = a; + m_v2 = b; + m_solutions = num; } void setSolutions(int num) { - m_solutions = num; + m_solutions = num; } int getNumSolutions() const { - return m_solutions; + return m_solutions; } TLorentzVector getv1() const { - return m_v1; + return m_v1; } TLorentzVector getv2() const { - return m_v2; + return m_v2; } -private: + private: ///Number of solutions. 0 or 2, one solution isn't possible due to the use of floats. int m_solutions; @@ -49,28 +49,28 @@ private: ///Second solution from the quadratic, check m_solutions is 2 first. TLorentzVector m_v2; -}; + }; /** * @brief Not complete. Work in progress */ -class NeutrinoWeighting : public EventSelectorBase { -public: + class NeutrinoWeighting: public EventSelectorBase { + public: NeutrinoWeighting(); virtual ~NeutrinoWeighting(); bool apply(const top::Event&) const override; - std::string name() const { return "RECO:NEUTRINOWEIGHTING"; } - -private: + std::string name() const override {return "RECO:NEUTRINOWEIGHTING";} + private: /** * @param lepton The lepton 4 vector. * @param bJet The b jet 4 vector. * @param topMass The top mass is a constraint in the spin correlation calculation. * @param index Gives the position in the neutrino eta array of this neutrino. */ - NWSolution solveForNeutrinoEta(const TLorentzVector& lepton, const TLorentzVector& bJet, double topMass, int index) const; + NWSolution solveForNeutrinoEta(const TLorentzVector& lepton, const TLorentzVector& bJet, double topMass, + int index) const; /** * @brief Calculate the weight for this combination of particles by comparing with Met. @@ -106,9 +106,7 @@ private: //For weighter. double sigmay; - -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PTMaxReco.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PTMaxReco.h index 7d701f9871b9..b4b0239c7e94 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PTMaxReco.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PTMaxReco.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef PTMAXRECO_H_ #define PTMAXRECO_H_ @@ -10,27 +10,26 @@ #include "TLorentzVector.h" namespace top { -class Event; + class Event; /** * @brief Not complete. Work in progress */ -class PTMaxReco : public EventSelectorBase { -public: + class PTMaxReco: public EventSelectorBase { + public: PTMaxReco(); virtual ~PTMaxReco(); bool apply(const top::Event&) const override; - std::string name() const { return "RECO:PTMAX"; } - -private: - TLorentzVector neutrinoCandidate(const TLorentzVector& lep, const xAOD::MissingET& met, bool dealWithNegative_nu) const; + std::string name() const override {return "RECO:PTMAX";} + private: + TLorentzVector neutrinoCandidate(const TLorentzVector& lep, const xAOD::MissingET& met, + bool dealWithNegative_nu) const; double m_wmass; double m_topmass; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PseudoTopReco.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PseudoTopReco.h index 0b5ea4b5a0bb..f6b2636066fc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PseudoTopReco.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PseudoTopReco.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOP_TOPEVENTRECONSTRCUTIONTOOLS_PSEUDOTOPRECO_H @@ -19,77 +19,74 @@ #include <memory> - /// - /// @translated by A.Knue from MAMbo tool, Link: https://twiki.cern.ch/twiki/bin/view/Main/MAMbo - /// - /// @brief use PseudoTop definitions to reconstruct tttbar event - /// - -namespace PseudoTopReco{ +/// +/// @translated by A.Knue from MAMbo tool, Link: https://twiki.cern.ch/twiki/bin/view/Main/MAMbo +/// +/// @brief use PseudoTop definitions to reconstruct tttbar event +/// + +namespace PseudoTopReco { class Particles; } -namespace top{ +namespace top { class Event; class TopConfig; - - enum LeptonType{kElectron, kMuon}; - - class PseudoTopReco final : public asg::AsgTool { - - public: - /// Constructor - explicit PseudoTopReco( const std::string& name ); - /// Destructor - virtual ~PseudoTopReco(){} - - /// Function initialising the tool - virtual StatusCode initialize(); - /// Function executing the tool - virtual StatusCode execute(const top::Event&); - - virtual StatusCode execute(const top::ParticleLevelEvent& plEvent); - - /// Function finalizing the tool - virtual StatusCode finalize(); - - // fill first all four vectors to use for the reconstruction - bool SetChargedLeptonInfo(const top::Event& event); - bool SetJetInfo(const top::Event& event); - - bool SetChargedLeptonInfo(const top::ParticleLevelEvent& plEvent); - bool SetJetInfo(const top::ParticleLevelEvent& plEvent); - - bool RunReconstruction(); - - bool ReconstructLeptonicW(); - - private: - - // config file - std::shared_ptr<top::TopConfig> m_config; - float m_bTagCutValue; - - std::string m_leptonType; - - std::vector<TLorentzVector> m_bJets; - std::vector<TLorentzVector> m_lightJets; - TLorentzVector m_lepton; - TLorentzVector m_neutrino; - TLorentzVector m_W_lep; - TLorentzVector m_W_had; - TLorentzVector m_b_lep; - TLorentzVector m_b_had; - TLorentzVector m_top_lep; - TLorentzVector m_top_had; - TLorentzVector m_ttbar; - double m_nu_px, m_nu_py, m_nu_pz, m_met_et; - double m_ht,m_R_lb,m_R_Wb_had,m_R_Wb_lep; - - const double KinemEdge = 13.9e6; - const double mWPDG = 80.399; - - + + enum LeptonType { + kElectron, kMuon + }; + + class PseudoTopReco final: public asg::AsgTool { + public: + /// Constructor + explicit PseudoTopReco(const std::string& name); + /// Destructor + virtual ~PseudoTopReco() {} + + /// Function initialising the tool + virtual StatusCode initialize(); + /// Function executing the tool + virtual StatusCode execute(const top::Event&); + + virtual StatusCode execute(const top::ParticleLevelEvent& plEvent); + + /// Function finalizing the tool + virtual StatusCode finalize(); + + // fill first all four vectors to use for the reconstruction + bool SetChargedLeptonInfo(const top::Event& event); + bool SetJetInfo(const top::Event& event); + + bool SetChargedLeptonInfo(const top::ParticleLevelEvent& plEvent); + bool SetJetInfo(const top::ParticleLevelEvent& plEvent); + + bool RunReconstruction(); + + bool ReconstructLeptonicW(); + private: + // config file + std::shared_ptr<top::TopConfig> m_config; + float m_bTagCutValue; + + std::string m_leptonType; + + std::vector<TLorentzVector> m_bJets; + std::vector<TLorentzVector> m_lightJets; + TLorentzVector m_lepton; + TLorentzVector m_neutrino; + TLorentzVector m_W_lep; + TLorentzVector m_W_had; + TLorentzVector m_b_lep; + TLorentzVector m_b_had; + TLorentzVector m_top_lep; + TLorentzVector m_top_had; + TLorentzVector m_ttbar; + double m_nu_px, m_nu_py, m_nu_pz, m_met_et; + double m_ht, m_R_lb, m_R_Wb_had, m_R_Wb_lep; + + const double KinemEdge = 13.9e6; + const double mWPDG = 80.399; }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PseudoTopRecoRun.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PseudoTopRecoRun.h index b5c11a73f0b3..b04ddec6572d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PseudoTopRecoRun.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/PseudoTopRecoRun.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOP_TOPEVENTRECONSTRCUTIONTOOLS_PSEUDOTOPRECORUN_H #define ANALYSISTOP_TOPEVENTRECONSTRCUTIONTOOLS_PSEUDOTOPRECORUN_H @@ -8,26 +8,24 @@ #include "TopEventSelectionTools/EventSelectorBase.h" #include "TopEventReconstructionTools/PseudoTopReco.h" -namespace top{ +namespace top { class Event; class TopConfig; - - class PseudoTopRecoRun : public EventSelectorBase { - public: + + class PseudoTopRecoRun: public EventSelectorBase { + public: PseudoTopRecoRun(const std::string& kLeptonType, std::shared_ptr<top::TopConfig> config); - virtual ~PseudoTopRecoRun(){} - + virtual ~PseudoTopRecoRun() {} + virtual bool apply(const top::Event&) const override; virtual bool applyParticleLevel(const top::ParticleLevelEvent& plEvent) const override; - std::string name() const; - + std::string name() const override; private: std::string m_name; - + std::unique_ptr<top::PseudoTopReco> m_PseudoTopReco; - }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/Sonnenschein.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/Sonnenschein.h index d9882e2d94b0..c56e663b3336 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/Sonnenschein.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/Sonnenschein.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SONNENSCHEIN_H_ #define SONNENSCHEIN_H_ @@ -11,27 +11,26 @@ #include "TLorentzVector.h" namespace top { -class Event; + class Event; /** * @brief An AnalysisTop friendly wrapper for the Sonnenschein reconstruction * that is implemented in SonnenscheinEngine. */ -class Sonnenschein : public EventSelectorBase { -public: + class Sonnenschein: public EventSelectorBase { + public: Sonnenschein(); virtual ~Sonnenschein(); virtual bool apply(const top::Event&) const override; - std::string name() const { return "RECO:SONNENSCHEIN"; } - -private: - bool tWb(const top::Event& event, int start, TLorentzVector& t, TLorentzVector& W, TLorentzVector& b, TLorentzVector& l, TLorentzVector& nu) const; + std::string name() const override {return "RECO:SONNENSCHEIN";} + private: + bool tWb(const top::Event& event, int start, TLorentzVector& t, TLorentzVector& W, TLorentzVector& b, + TLorentzVector& l, TLorentzVector& nu) const; top::SonnenscheinEngine m_sonn; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/SonnenscheinEngine.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/SonnenscheinEngine.h index 564bc2519701..537c36abef0b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/SonnenscheinEngine.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/SonnenscheinEngine.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SONNENSCEINENGINE_H_ #define SONNENSCEINENGINE_H_ @@ -12,7 +12,6 @@ #include "TLorentzVector.h" namespace top { - /** * @brief Rewrite the top and anti-top decays as a quartic polynomial using top * and W mass constraints. And solve. @@ -22,8 +21,8 @@ namespace top { * and returns the neutrino Lorentz vectors for both neutrinos in the event. * */ -class SonnenscheinEngine { -public: + class SonnenscheinEngine { + public: /** * @brief Does nothing except sets the default flag to false. */ @@ -46,9 +45,12 @@ public: * function you assumed a lepton-b pairing, so if you want to try the other * one you'll have to call it again with the b and bbar swapped or something. */ - std::vector<std::pair<TLorentzVector, TLorentzVector> > solve(const TLorentzVector& me_t_lp, const TLorentzVector& me_t_b, double mass_t, double mass_wp, const TLorentzVector& me_tbar_lm, const TLorentzVector& me_tbar_bbar, double mass_tbar, double mass_wm, double me_mex, double me_mey) const; - -private: + std::vector<std::pair<TLorentzVector, TLorentzVector> > solve(const TLorentzVector& me_t_lp, + const TLorentzVector& me_t_b, double mass_t, + double mass_wp, const TLorentzVector& me_tbar_lm, + const TLorentzVector& me_tbar_bbar, double mass_tbar, + double mass_wm, double me_mex, double me_mey) const; + private: /** * @brief Solve a quartic. * @@ -90,8 +92,7 @@ private: ///Print a load of debug information (probably not by default, right)? bool m_debug; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TopEventReconstructionToolsLoader.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TopEventReconstructionToolsLoader.h index 5f2dd1b0d6dd..910e1d2b8bb9 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TopEventReconstructionToolsLoader.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TopEventReconstructionToolsLoader.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef RECONSTRUCTIONTOOLLOADER_H_ #define RECONSTRUCTIONTOOLLOADER_H_ @@ -8,7 +8,6 @@ #include "TopEventSelectionTools/ToolLoaderBase.h" namespace top { - /** * @brief Load a ttbar event reconstruction code based on the same. * @@ -25,8 +24,8 @@ namespace top { * top::ToolLoaderBase. * */ -class TopEventReconstructionToolsLoader : public ToolLoaderBase { -public: + class TopEventReconstructionToolsLoader: public ToolLoaderBase { + public: /** * @brief Some sort of factory that can create the tool you need given a * string. @@ -38,11 +37,11 @@ public: * @param wk Not used, but needed by EventLoop for some of the selection tools. * @return A pointer to a fully initialised and ready to use tool. */ - top::EventSelectorBase* initTool(const std::string& name, const std::string& line, TFile* outputFile, std::shared_ptr<top::TopConfig> config,EL::Worker* wk = nullptr); + top::EventSelectorBase* initTool(const std::string& name, const std::string& line, TFile* outputFile, + std::shared_ptr<top::TopConfig> config, EL::Worker* wk = nullptr); ClassDef(top::TopEventReconstructionToolsLoader, 0) -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresChi2.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresChi2.h index 1aee478fb6e3..4ff97c91c0b1 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresChi2.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresChi2.h @@ -1,39 +1,49 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TtresChi2_H #define TtresChi2_H -#include<iostream> +#include <iostream> #include <string> #include <vector> #include "TLorentzVector.h" #include "TopEventReconstructionTools/TtresNeutrinoBuilder.h" -class TtresChi2{ - public: - TtresChi2(std::string units="GeV"); +class TtresChi2 { +public: + TtresChi2(std::string units = "GeV"); virtual ~TtresChi2(); - enum WReco {ROTATION, REALPART, DECREASING}; - enum Chi2Version {DATA2011SUMMER2012, DATA2012AUTOMN2012, DATA2012SUMMER2013, DATA2012SUMMER2013PT100}; - enum PtDiff {NOPTDIFF, PTDIFF, PTDIFFREL, PTDIFFMASS}; - enum Btag {STDBTAG, AFFECTBTAG, NO_BTAGHM, NO_BTAG}; - enum RunMode {RUNDEFAULT, RUNSTUDY}; - - private: + enum WReco { + ROTATION, REALPART, DECREASING + }; + enum Chi2Version { + DATA2011SUMMER2012, DATA2012AUTOMN2012, DATA2012SUMMER2013, DATA2012SUMMER2013PT100 + }; + enum PtDiff { + NOPTDIFF, PTDIFF, PTDIFFREL, PTDIFFMASS + }; + enum Btag { + STDBTAG, AFFECTBTAG, NO_BTAGHM, NO_BTAG + }; + enum RunMode { + RUNDEFAULT, RUNSTUDY + }; +private: TtresChi2(const TtresChi2&); - TtresChi2& operator=(const TtresChi2&); + TtresChi2& operator = (const TtresChi2&); std::vector<TLorentzVector*> GetNeutrinos(TLorentzVector*, TLorentzVector*); - double MjjP, SMjjP, m_TopMinusW_had_mean, m_TopMinusW_had_sigma, m_Top_lep_mean, m_Top_lep_sigma, m_PtDiff_mean, m_PtDiff_sigma, m_PtDiffRel_mean, m_PtDiffRel_sigma, m_PtDiffRelMass_mean, m_PtDiffRelMass_sigma, MTHJJ, STHJJ; - double m_WhChi2Value,m_ThWhChi2Value,m_TlChi2Value,m_PtDiffChi2Value; - int m_debug; + double MjjP, SMjjP, m_TopMinusW_had_mean, m_TopMinusW_had_sigma, m_Top_lep_mean, m_Top_lep_sigma, m_PtDiff_mean, + m_PtDiff_sigma, m_PtDiffRel_mean, m_PtDiffRel_sigma, m_PtDiffRelMass_mean, m_PtDiffRelMass_sigma, MTHJJ, STHJJ; + double m_WhChi2Value, m_ThWhChi2Value, m_TlChi2Value, m_PtDiffChi2Value; + int m_debug; PtDiff m_UsePtDiff; - Btag m_Btag; - WReco m_WReco; + Btag m_Btag; + WReco m_WReco; RunMode m_RunMode; double m_Units; TtresNeutrinoBuilder* m_NeutrinoBuilder; @@ -49,77 +59,81 @@ class TtresChi2{ std::vector < double > m_chi2ThWh_Values; std::vector < double > m_chi2Tl_Values; std::vector < double > m_chi2PtDiff_Values; - + std::vector < double > m_PtDiff_Values; std::vector < double > m_Wh_Values; std::vector < double > m_ThWh_Values; std::vector < double > m_Th_Values; std::vector < double > m_Tl_Values; - + std::vector < int > m_i_Wq1; std::vector < int > m_i_Wq2; std::vector < int > m_i_Thb; std::vector < int > m_i_Tlb; std::vector < int > m_i_n; - + int m_nChi2Values; - - public: +public: void Init(Chi2Version version = DATA2012SUMMER2013, double highJetMass = 60.0); void Reset(); - bool findMinChiSquare_HMelseLM(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, TLorentzVector*, int&, int&, int&, int&, int&, double&, double&, double&); - bool findMinChiSquare_LMelseHM(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, TLorentzVector*, int&, int&, int&, int&, int&, double&, double&, double&); + bool findMinChiSquare_HMelseLM(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, + TLorentzVector*, int&, int&, int&, int&, int&, double&, double&, double&); + bool findMinChiSquare_LMelseHM(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, + TLorentzVector*, int&, int&, int&, int&, int&, double&, double&, double&); - bool findMinChiSquare_AllRanges(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, TLorentzVector*, int&, int&, int&, int&, int&, double&, double&, double&); + bool findMinChiSquare_AllRanges(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, + TLorentzVector*, int&, int&, int&, int&, int&, double&, double&, double&); - bool findMinChiSquare(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, TLorentzVector*, int&, int&, int&, int&, int&, double&, double&, double&); + bool findMinChiSquare(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, TLorentzVector*, + int&, int&, int&, int&, int&, double&, double&, double&); - bool findMinChiSquare_HighMass(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, TLorentzVector*, int&, int&, int&, int&, double&, double&, double&); + bool findMinChiSquare_HighMass(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, + TLorentzVector*, int&, int&, int&, int&, double&, double&, double&); - bool findMinChiSquare_VeryHighMass(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, TLorentzVector*, int&, int&, int&, double&, double&, double&); + bool findMinChiSquare_VeryHighMass(TLorentzVector*, const std::vector<TLorentzVector*>*, const std::vector<bool>*, + TLorentzVector*, int&, int&, int&, double&, double&, double&); - inline void SetDebugMode(bool X){m_debug=X;if(m_debug>2)m_NeutrinoBuilder->setdebuglevel(m_debug);} - inline void SetWReconstruction(WReco X){m_WReco=X;} - inline void SetBtagHandeling(Btag X){m_Btag=X;} + inline void SetDebugMode(bool X) {m_debug = X; if (m_debug > 2) m_NeutrinoBuilder->setdebuglevel(m_debug); } + inline void SetWReconstruction(WReco X) {m_WReco = X;} + inline void SetBtagHandeling(Btag X) {m_Btag = X;} inline void SetHighMThreshold(double highJetMass) {m_highJetMass = highJetMass;} - inline void UsePtDiff(PtDiff X){m_UsePtDiff=X;} - inline void SetRunMode(RunMode X){m_RunMode=X;} - - inline double getResult_Chi2All() {return res_chi2All;} - inline double getResult_Chi2WH() {return res_chi2WH;} - inline double getResult_Chi2TopH() {return res_chi2TopH;} - inline double getResult_Chi2TopL() {return res_chi2TopL;} - inline double getResult_Mtl() {return res_Mtl;} - inline double getResult_Mwh() {return res_Mwh;} - inline double getResult_Mth() {return res_Mth;} - inline double getResult_Mtt() {return res_Mtt;} - - inline std::vector < double > getAllChi2Values() {return m_chi2Values; } - inline std::vector < double > getAllWh_Chi2Values() {return m_chi2Wh_Values; } - inline std::vector < double > getAllTh_Chi2Values() {return m_chi2Th_Values; } - inline std::vector < double > getAllThWh_Chi2Values() {return m_chi2ThWh_Values; } - inline std::vector < double > getAllTl_Chi2Values() {return m_chi2Tl_Values; } - inline std::vector < double > getAllPtDiff_Chi2Values() {return m_chi2PtDiff_Values;} - inline std::vector < int > getAllIndicesWq1() {return m_i_Wq1; } - inline std::vector < int > getAllIndicesWq2() {return m_i_Wq2; } - inline std::vector < int > getAllIndicesThb() {return m_i_Thb; } - inline std::vector < int > getAllIndicesTlb() {return m_i_Tlb; } - inline std::vector < int > getAllIndicesN() {return m_i_n; } - - inline std::vector < double > getAllPtDiff_Values() {return m_PtDiff_Values; } - inline std::vector < double > getAllWh_Values() {return m_Wh_Values; } - inline std::vector < double > getAllThWh_Values() {return m_ThWh_Values; } - inline std::vector < double > getAllTh_Values() {return m_Th_Values; } - inline std::vector < double > getAllTl_Values() {return m_Tl_Values; } - - inline double getWhChi2Value() {return m_WhChi2Value; } - inline double getThWhChi2Value() {return m_ThWhChi2Value;} - inline double getTlChi2Value() {return m_TlChi2Value; } - inline double getPtDiffChi2Value() {return m_PtDiffChi2Value;} - inline int getNChi2Values() {return m_nChi2Values; } - inline int getCategory() {return m_category; } - inline TLorentzVector getResult_Tlv() {return res_Tt; } - + inline void UsePtDiff(PtDiff X) {m_UsePtDiff = X;} + inline void SetRunMode(RunMode X) {m_RunMode = X;} + + inline double getResult_Chi2All() {return res_chi2All;} + inline double getResult_Chi2WH() {return res_chi2WH;} + inline double getResult_Chi2TopH() {return res_chi2TopH;} + inline double getResult_Chi2TopL() {return res_chi2TopL;} + inline double getResult_Mtl() {return res_Mtl;} + inline double getResult_Mwh() {return res_Mwh;} + inline double getResult_Mth() {return res_Mth;} + inline double getResult_Mtt() {return res_Mtt;} + + inline std::vector < double > getAllChi2Values() {return m_chi2Values;} + inline std::vector < double > getAllWh_Chi2Values() {return m_chi2Wh_Values;} + inline std::vector < double > getAllTh_Chi2Values() {return m_chi2Th_Values;} + inline std::vector < double > getAllThWh_Chi2Values() {return m_chi2ThWh_Values;} + inline std::vector < double > getAllTl_Chi2Values() {return m_chi2Tl_Values;} + inline std::vector < double > getAllPtDiff_Chi2Values() {return m_chi2PtDiff_Values;} + inline std::vector < int > getAllIndicesWq1() {return m_i_Wq1;} + inline std::vector < int > getAllIndicesWq2() {return m_i_Wq2;} + inline std::vector < int > getAllIndicesThb() {return m_i_Thb;} + inline std::vector < int > getAllIndicesTlb() {return m_i_Tlb;} + inline std::vector < int > getAllIndicesN() {return m_i_n;} + + inline std::vector < double > getAllPtDiff_Values() {return m_PtDiff_Values;} + inline std::vector < double > getAllWh_Values() {return m_Wh_Values;} + inline std::vector < double > getAllThWh_Values() {return m_ThWh_Values;} + inline std::vector < double > getAllTh_Values() {return m_Th_Values;} + inline std::vector < double > getAllTl_Values() {return m_Tl_Values;} + + inline double getWhChi2Value() {return m_WhChi2Value;} + inline double getThWhChi2Value() {return m_ThWhChi2Value;} + inline double getTlChi2Value() {return m_TlChi2Value;} + inline double getPtDiffChi2Value() {return m_PtDiffChi2Value;} + inline int getNChi2Values() {return m_nChi2Values;} + inline int getCategory() {return m_category;} + inline TLorentzVector getResult_Tlv() {return res_Tt;} }; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresNeutrinoBuilder.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresNeutrinoBuilder.h index bc6ddbec57b7..a2e7cbd70fd4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresNeutrinoBuilder.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresNeutrinoBuilder.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TtresNeutrinoBuilder_H #define TtresNeutrinoBuilder_H 1 @@ -14,14 +14,13 @@ #include <TUUID.h> class TtresNeutrinoBuilder { - - public: +public: TtresNeutrinoBuilder(std::string units); virtual ~TtresNeutrinoBuilder(); TtresNeutrinoBuilder(const TtresNeutrinoBuilder&); - TtresNeutrinoBuilder& operator=(const TtresNeutrinoBuilder&); + TtresNeutrinoBuilder& operator = (const TtresNeutrinoBuilder&); - inline void setdebuglevel(int level){m_debug = level;}; + inline void setdebuglevel(int level) {m_debug = level;}; Double_t getDiscriminant(const TLorentzVector*, const Double_t, const Double_t); // In case of negative discriminant, decrease the MET @@ -29,17 +28,17 @@ class TtresNeutrinoBuilder { std::vector<TLorentzVector*> candidatesFromWMass_Scaling(const TLorentzVector*, const Double_t, const Double_t); std::vector<TLorentzVector*> candidatesFromWMass_Scaling(const TLorentzVector*, const TLorentzVector*); // In case of negative discriminant, rotate the MET - std::vector<TLorentzVector*> candidatesFromWMass_Rotation(const TLorentzVector*, const Double_t, const Double_t, const bool); - std::vector<TLorentzVector*> candidatesFromWMass_Rotation(const TLorentzVector*, const TLorentzVector*, const bool); + std::vector<TLorentzVector*> candidatesFromWMass_Rotation(const TLorentzVector*, const Double_t, const Double_t, + const bool); + std::vector<TLorentzVector*> candidatesFromWMass_Rotation(const TLorentzVector*, const TLorentzVector*, const bool); // In case of negative discriminant, use the real part - std::vector<TLorentzVector*> candidatesFromWMass_RealPart(const TLorentzVector*, const Double_t, const Double_t, const bool); - std::vector<TLorentzVector*> candidatesFromWMass_RealPart(const TLorentzVector*, const TLorentzVector*, const bool); - - protected: + std::vector<TLorentzVector*> candidatesFromWMass_RealPart(const TLorentzVector*, const Double_t, const Double_t, + const bool); + std::vector<TLorentzVector*> candidatesFromWMass_RealPart(const TLorentzVector*, const TLorentzVector*, const bool); +protected: double fitAlpha(const TLorentzVector*, const Double_t, const Double_t); int m_debug; double m_Units; - }; #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresdRmin.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresdRmin.h index 06bd7b2506ae..3014172d3c3a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresdRmin.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/TopEventReconstructionTools/TtresdRmin.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TtresdRmin_H #define TtresdRmin_H @@ -13,14 +13,10 @@ using namespace std; class TtresdRmin { - - ///////////////////////////////////////////////////////////////////////////////////////////// // public ///////////////////////////////////////////////////////////////////////////////////////////// - - public: - +public: /** * Class constructor. Set unit used in four momentum vector calculations * @param units : Unit used for reconstruction, MeV or GeV @@ -44,7 +40,8 @@ class TtresdRmin { * @param dRCutMassFactor : Factor applied to jet mass in dRmin specific cut * @return void */ - void Init(double highJetMass = 60.0, double minJetPt = 25.0, double dRCutOffset = 2.5, double dRCutMassFactor = 0.015); + void Init(double highJetMass = 60.0, double minJetPt = 25.0, double dRCutOffset = 2.5, + double dRCutMassFactor = 0.015); /** @@ -55,35 +52,35 @@ class TtresdRmin { * @param neutrino : Reconstructed neutrino * @return bool : Success of setup */ - bool SetupEvent(vector<TLorentzVector*> &jets, TLorentzVector &lepton, TLorentzVector &neutrino); + bool SetupEvent(vector<TLorentzVector*>& jets, TLorentzVector& lepton, TLorentzVector& neutrino); /** * Get jet indicices identified by dRmin method, used for mtt reconstruction * @return vector<int> : Indices of identified jets in passed jet vector */ - inline vector<int> GetJetIndices() { return m_jet_indices; }; + inline vector<int> GetJetIndices() {return m_jet_indices;}; /** * Get index of jet with highest mass * @return int : jet index */ - inline int GetHighMassJetIndex() { return m_highMassJetIndex; }; + inline int GetHighMassJetIndex() {return m_highMassJetIndex;}; /** * Get highest jet mass found in jet vector * @return double : jet mass */ - inline double GetHighestJetMass() { return m_highestJetMass; }; + inline double GetHighestJetMass() {return m_highestJetMass;}; /** * Set threshold for highMass case * @param highJetMass threshold for the high jet mass case */ - inline void SetHighMThreshold(double highJetMass) { m_highM = highJetMass; }; + inline void SetHighMThreshold(double highJetMass) {m_highM = highJetMass;}; /** @@ -101,8 +98,7 @@ class TtresdRmin { ///////////////////////////////////////////////////////////////////////////////////////////// // private ///////////////////////////////////////////////////////////////////////////////////////////// - - private: +private: /** * Find the jet indices used for mtt reconstruction for events containing a high mass jet * @return bool : success of function @@ -116,16 +112,16 @@ class TtresdRmin { */ bool FindJetIndices_LM(); - bool m_init; ///< Flag of initialization status of tool - bool m_verbose; ///< Flag for verbosity level - double m_highM; ///< Jet mass threshold to identify it as a "high mass jet" - double m_Units; ///< Unit factor used, GeV = 1, MeV = 1000 - double m_minJetPt; ///< Minimum jet pT used for highM jet search - double m_dRCutOffset; ///< Offset of dRmin specific cut on jet_dR - double m_dRCutMassFactor; ///< Jet mass factor of dRmin specific cut on jet_dR + bool m_init; ///< Flag of initialization status of tool + bool m_verbose; ///< Flag for verbosity level + double m_highM; ///< Jet mass threshold to identify it as a "high mass jet" + double m_Units; ///< Unit factor used, GeV = 1, MeV = 1000 + double m_minJetPt; ///< Minimum jet pT used for highM jet search + double m_dRCutOffset; ///< Offset of dRmin specific cut on jet_dR + double m_dRCutMassFactor; ///< Jet mass factor of dRmin specific cut on jet_dR - int m_highMassJetIndex; ///< Index of highest mass jet for current event - double m_highestJetMass; ///< Highest jet mass found for current event + int m_highMassJetIndex; ///< Index of highest mass jet for current event + double m_highestJetMass; ///< Highest jet mass found for current event vector<TLorentzVector*> m_jets; ///< Input vector of jet objects TLorentzVector m_lepton; ///< Input lepton object @@ -133,7 +129,6 @@ class TtresdRmin { TLorentzVector m_Wleptonic; ///< leptonic W object reconstructed from lepton and neutrino vector<int> m_jet_indices; ///< Indices of jets used for reconstruction of invariant ttbar mass - }; #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/util/topreco_test_mt2.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/util/topreco_test_mt2.cxx index 55e00f281b2f..144400c36be3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/util/topreco_test_mt2.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/util/topreco_test_mt2.cxx @@ -1,10 +1,10 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include <iostream> -#include "RootCore/Packages.h" +//#include "RootCore/Packages.h" #ifdef ROOTCORE_PACKAGE_Oxbridgekinetics #include "Mt2/Basic_Mt2_332_Calculator.h" @@ -14,22 +14,21 @@ #endif int main() { - #ifndef ROOTCORE_PACKAGE_Oxbridgekinetics - std::cout << "Oxbridgekinetics library not found when compiling" << std::endl; + std::cout << "Oxbridgekinetics library not found when compiling" << std::endl; #else - std::cout << "Starting top mt2 test\n"; - Mt2::LorentzTransverseVector a; - Mt2::LorentzTransverseVector b; - Mt2::TwoVector c; - double d = 0.; + std::cout << "Starting top mt2 test\n"; + Mt2::LorentzTransverseVector a; + Mt2::LorentzTransverseVector b; + Mt2::TwoVector c; + double d = 0.; - Mt2::Basic_Mt2_332_Calculator mt2Calculator; - const double mt2 = mt2Calculator.mt2_332( a, b, c, d); + Mt2::Basic_Mt2_332_Calculator mt2Calculator; + const double mt2 = mt2Calculator.mt2_332(a, b, c, d); - std::cout << "mt2 " << mt2 << std::endl; - std::cout << "Ending\n"; + std::cout << "mt2 " << mt2 << std::endl; + std::cout << "Ending\n"; #endif - return 0; + return 0; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt index 3413593ed74b..d6b986f9c287 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt @@ -1,6 +1,7 @@ +# Auto-generated on: 2017-03-08 14:47:36.708684 # Declare the name of this package: -atlas_subdir( TopEventSelectionTools ) +atlas_subdir( TopEventSelectionTools None ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -10,16 +11,19 @@ atlas_depends_on_subdirs( PUBLIC TopEvent TopCorrections TopParticleLevel - MuonSelectorTools ) + TriggerAnalysisInterfaces + JetSelectorTools ) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) +# Custom definitions needed for this package: +add_definitions( -g ) + # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopEventSelectionTools _cintDictSource - ROOT_HEADERS TopEventSelectionTools/ToolLoaderBase.h - TopEventSelectionTools/TopEventSelectionToolsLoader.h Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) # Build a library that other components can link against: atlas_add_library( TopEventSelectionTools Root/*.cxx Root/*.h Root/*.icc @@ -32,7 +36,7 @@ atlas_add_library( TopEventSelectionTools Root/*.cxx Root/*.h Root/*.icc TopEvent TopCorrections TopParticleLevel - MuonSelectorToolsLib + JetSelectorToolsLib ${ROOT_LIBRARIES} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ExamplePlots.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ExamplePlots.cxx index 6cabee37f80f..6a9b8b45f146 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ExamplePlots.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ExamplePlots.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/ExamplePlots.h" @@ -19,14 +19,13 @@ #include "PATInterfaces/SystematicSet.h" namespace top { + const double ExamplePlots::toGeV = 0.001; -const double ExamplePlots::toGeV = 0.001; - - ExamplePlots::ExamplePlots(const std::string& name, TFile* outputFile, EL::Worker* wk, std::shared_ptr<top::TopConfig> config) : + ExamplePlots::ExamplePlots(const std::string& name, TFile* outputFile, EL::Worker* wk, + std::shared_ptr<top::TopConfig> config) : m_hists(name, outputFile, wk), m_nominalHashValue(0) { - m_config = config; - CP::SystematicSet nominal; + CP::SystematicSet nominal; m_nominalHashValue = nominal.hash(); m_hists.addHist("event_mu", ";<#mu>;Events", 25, 0., 50.); @@ -85,9 +84,9 @@ const double ExamplePlots::toGeV = 0.001; m_hists.addHist("jet_mv2c10", ";Jet mv2c10;Jets", 20, -1., 1.); if (m_config->isMC()) { m_hists.addHist("jet_truthflav", ";Jet truth flavor;Jets", 20, 0., 20.); - m_hists.addHist("jet_btagSF_77", ";Jet btag SF;Jets", 100, 0.5, 1.5); + m_hists.addHist("jet_btagSF_MV2c10_77", ";Jet btag SF;Jets", 100, 0.5, 1.5); } - m_hists.addHist("jet_isbtagged_77", ";Jet is b-tagged;Jets", 2, 0., 2.); + m_hists.addHist("jet_isbtagged_MV2c10_77", ";Jet is b-tagged;Jets", 2, 0., 2.); m_hists.addHist("jet0_pt", ";Jet0 p_{T} / GeV; Events / 10 GeV", 25, 5, 505); m_hists.addHist("jet0_eta", ";Jet0 #eta; Jets", 25, -2.5, 2.5); @@ -96,9 +95,9 @@ const double ExamplePlots::toGeV = 0.001; m_hists.addHist("jet0_mv2c10", ";Jet0 mv2c10; Jets", 50, 0, 1); if (m_config->isMC()) { m_hists.addHist("jet0_truthflav", ";Jet0 truth flavor;Jets", 20, 0., 20.); - m_hists.addHist("jet0_btagSF_77", ";Jet0 btag SF;Jets", 100, 0.5, 1.5); + m_hists.addHist("jet0_btagSF_MV2c10_77", ";Jet0 btag SF;Jets", 100, 0.5, 1.5); } - m_hists.addHist("jet0_isbtagged_77", ";Jet is b-tagged;Jets", 2, 0., 2.); + m_hists.addHist("jet0_isbtagged_MV2c10_77", ";Jet is b-tagged;Jets", 2, 0., 2.); m_hists.addHist("jet1_pt", ";Jet1 p_{T} / GeV; Events / 10 GeV", 25, 5, 505); m_hists.addHist("jet1_eta", ";Jet1 #eta; Jets", 25, -2.5, 2.5); @@ -107,9 +106,9 @@ const double ExamplePlots::toGeV = 0.001; m_hists.addHist("jet1_mv2c10", ";Jet1 mv2c10; Jets", 50, 0, 1); if (m_config->isMC()) { m_hists.addHist("jet1_truthflav", ";Jet1 truth flavor;Jets", 20, 0., 20.); - m_hists.addHist("jet1_btagSF_77", ";Jet1 btag SF;Jets", 100, 0.5, 1.5); + m_hists.addHist("jet1_btagSF_MV2c10_77", ";Jet1 btag SF;Jets", 100, 0.5, 1.5); } - m_hists.addHist("jet1_isbtagged_77", ";Jet is b-tagged;Jets", 2, 0., 2.); + m_hists.addHist("jet1_isbtagged_MV2c10_77", ";Jet is b-tagged;Jets", 2, 0., 2.); m_hists.addHist("jet2_pt", ";Jet2 p_{T} / GeV; Events / 10 GeV", 25, 5, 505); m_hists.addHist("jet2_eta", ";Jet2 #eta; Jets", 25, -2.5, 2.5); @@ -118,9 +117,9 @@ const double ExamplePlots::toGeV = 0.001; m_hists.addHist("jet2_mv2c10", ";Jet2 mv2c10; Jets", 50, 0, 1); if (m_config->isMC()) { m_hists.addHist("jet2_truthflav", ";Jet2 truth flavor;Jets", 20, 0., 20.); - m_hists.addHist("jet2_btagSF_77", ";Jet2 btag SF;Jets", 100, 0.5, 1.5); + m_hists.addHist("jet2_btagSF_MV2c10_77", ";Jet2 btag SF;Jets", 100, 0.5, 1.5); } - m_hists.addHist("jet2_isbtagged_77", ";Jet is b-tagged;Jets", 2, 0., 2.); + m_hists.addHist("jet2_isbtagged_MV2c10_77", ";Jet is b-tagged;Jets", 2, 0., 2.); m_hists.addHist("jet3_pt", ";Jet3 p_{T} / GeV; Events / 10 GeV", 25, 5, 505); m_hists.addHist("jet3_eta", ";Jet3 #eta; Jets", 25, -2.5, 2.5); @@ -129,9 +128,9 @@ const double ExamplePlots::toGeV = 0.001; m_hists.addHist("jet3_mv2c10", ";Jet3 mv2c10; Jets", 50, 0, 1); if (m_config->isMC()) { m_hists.addHist("jet3_truthflav", ";Jet3 truth flavor;Jets", 20, 0., 20.); - m_hists.addHist("jet3_btagSF_77", ";Jet3 btag SF;Jets", 100, 0.5, 1.5); + m_hists.addHist("jet3_btagSF_MV2c10_77", ";Jet3 btag SF;Jets", 100, 0.5, 1.5); } - m_hists.addHist("jet3_isbtagged_77", ";Jet is b-tagged;Jets", 2, 0., 2.); + m_hists.addHist("jet3_isbtagged_MV2c10_77", ";Jet is b-tagged;Jets", 2, 0., 2.); //Large-R jet m_hists.addHist("ljet_n", ";Large-R Jet multiplicity; Jets ", 5, 0, 5); @@ -149,247 +148,236 @@ const double ExamplePlots::toGeV = 0.001; m_hists.addHist("event_met_et", ";MET / GeV;Events", 50, 0., 400.); m_hists.addHist("event_met_phi", ";MET #phi;Events", 20, -M_PI, M_PI); -} + } -bool ExamplePlots::apply(const top::Event& event) const { + bool ExamplePlots::apply(const top::Event& event) const { //only nominal - - if (event.m_hashValue != m_nominalHashValue) - return true; + + if (event.m_hashValue != m_nominalHashValue) return true; //only plot tight selection //before, we were plotting tight and loose together - if (event.m_isLoose) - return true; - - //std::cout << event << std::endl; + if (event.m_isLoose) return true; double eventWeight = 1.; - if (top::isSimulation(event)) -// eventWeight = event.m_info->mcEventWeight(); - eventWeight = event.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix + if (top::isSimulation(event)) eventWeight = event.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); if (m_config->isMC()) { m_hists.hist("mc_weight")->Fill(eventWeight, eventWeight); m_hists.hist("jvt_SF")->Fill(event.m_jvtSF, eventWeight); //pileup weight needs pileup reweighting tool to have run - if (top::ScaleFactorRetriever::hasPileupSF(event)) - m_hists.hist("pileup_weight")->Fill(top::ScaleFactorRetriever::pileupSF(event), eventWeight); + if (top::ScaleFactorRetriever::hasPileupSF(event)) m_hists.hist("pileup_weight")->Fill(top::ScaleFactorRetriever::pileupSF( + event), eventWeight); } m_hists.hist("event_mu")->Fill(event.m_info->averageInteractionsPerCrossing(), eventWeight); m_hists.hist("el_n")->Fill(event.m_electrons.size(), eventWeight); for (const auto* const elPtr : event.m_electrons) { - m_hists.hist("el_pt") -> Fill(elPtr->pt() * toGeV, eventWeight); - m_hists.hist("el_eta") -> Fill(elPtr->eta(), eventWeight); - m_hists.hist("el_phi") -> Fill(elPtr->phi(), eventWeight); - m_hists.hist("el_charge") -> Fill(elPtr->charge(), eventWeight); + m_hists.hist("el_pt")->Fill(elPtr->pt() * toGeV, eventWeight); + m_hists.hist("el_eta")->Fill(elPtr->eta(), eventWeight); + m_hists.hist("el_phi")->Fill(elPtr->phi(), eventWeight); + m_hists.hist("el_charge")->Fill(elPtr->charge(), eventWeight); - //protection from the derivation framework - - //So far we keep tracks associated with "good" electrons. - //It could be you have a super-loose selection here (just for testing) - //so we need to check if the electron has a track associated with it - if (elPtr->trackParticle()) - m_hists.hist("el_trkpart_charge")->Fill(elPtr->trackParticle()->charge(), eventWeight); + //protection from the derivation framework - + //So far we keep tracks associated with "good" electrons. + //It could be you have a super-loose selection here (just for testing) + //so we need to check if the electron has a track associated with it + if (elPtr->trackParticle()) m_hists.hist("el_trkpart_charge")->Fill(elPtr->trackParticle()->charge(), + eventWeight); - //retrieve the truth-matching variables from MCTruthClassifier - if (m_config->isMC()) { - static SG::AuxElement::Accessor<int> typeel("truthType"); - if (typeel.isAvailable(*elPtr)) m_hists.hist("el_true_type")->Fill(typeel(*elPtr), eventWeight); - } + //retrieve the truth-matching variables from MCTruthClassifier + if (m_config->isMC()) { + static SG::AuxElement::Accessor<int> typeel("truthType"); + if (typeel.isAvailable(*elPtr)) m_hists.hist("el_true_type")->Fill(typeel(*elPtr), eventWeight); + } - //testing isolation in the derivation framework - float iso = 0; + //testing isolation in the derivation framework + float iso = 0; - if (elPtr->isolationValue(iso, xAOD::Iso::topoetcone20)) - m_hists.hist("el_topoetcone20")->Fill(iso * toGeV, eventWeight); + if (elPtr->isolationValue(iso, xAOD::Iso::topoetcone20)) m_hists.hist("el_topoetcone20")->Fill(iso * toGeV, + eventWeight); - if (elPtr->isolationValue(iso, xAOD::Iso::topoetcone30)) - m_hists.hist("el_topoetcone30")->Fill(iso * toGeV, eventWeight); + if (elPtr->isolationValue(iso, xAOD::Iso::topoetcone30)) m_hists.hist("el_topoetcone30")->Fill(iso * toGeV, + eventWeight); - if (elPtr->isolationValue(iso, xAOD::Iso::topoetcone40)) - m_hists.hist("el_topoetcone40")->Fill(iso * toGeV, eventWeight); + if (elPtr->isolationValue(iso, xAOD::Iso::topoetcone40)) m_hists.hist("el_topoetcone40")->Fill(iso * toGeV, + eventWeight); - if (elPtr->isolationValue(iso, xAOD::Iso::ptcone20)) - m_hists.hist("el_ptcone20")->Fill(iso * toGeV, eventWeight); + if (elPtr->isolationValue(iso, xAOD::Iso::ptcone20)) m_hists.hist("el_ptcone20")->Fill(iso * toGeV, eventWeight); - if (elPtr->isolationValue(iso, xAOD::Iso::ptcone30)) - m_hists.hist("el_ptcone30")->Fill(iso * toGeV, eventWeight); + if (elPtr->isolationValue(iso, xAOD::Iso::ptcone30)) m_hists.hist("el_ptcone30")->Fill(iso * toGeV, eventWeight); - if (elPtr->isolationValue(iso, xAOD::Iso::ptcone40)) - m_hists.hist("el_ptcone40")->Fill(iso * toGeV, eventWeight); + if (elPtr->isolationValue(iso, xAOD::Iso::ptcone40)) m_hists.hist("el_ptcone40")->Fill(iso * toGeV, eventWeight); - if (elPtr->isAvailable<float>("ptvarcone20")) { - float ptvarcone20 = elPtr->auxdataConst<float>("ptvarcone20"); - m_hists.hist("el_ptvarcone20")->Fill(ptvarcone20 * toGeV, eventWeight); - } + if (elPtr->isAvailable<float>("ptvarcone20")) { + float ptvarcone20 = elPtr->auxdataConst<float>("ptvarcone20"); + m_hists.hist("el_ptvarcone20")->Fill(ptvarcone20 * toGeV, eventWeight); + } - if (elPtr->isAvailable<float>("ptvarcone30")) { - float ptvarcone30 = elPtr->auxdataConst<float>("ptvarcone30"); - m_hists.hist("el_ptvarcone30")->Fill(ptvarcone30 * toGeV, eventWeight); - } + if (elPtr->isAvailable<float>("ptvarcone30")) { + float ptvarcone30 = elPtr->auxdataConst<float>("ptvarcone30"); + m_hists.hist("el_ptvarcone30")->Fill(ptvarcone30 * toGeV, eventWeight); + } - if (elPtr->isAvailable<float>("ptvarcone40")) { - float ptvarcone40 = elPtr->auxdataConst<float>("ptvarcone40"); - m_hists.hist("el_ptvarcone40")->Fill(ptvarcone40 * toGeV, eventWeight); - } + if (elPtr->isAvailable<float>("ptvarcone40")) { + float ptvarcone40 = elPtr->auxdataConst<float>("ptvarcone40"); + m_hists.hist("el_ptvarcone40")->Fill(ptvarcone40 * toGeV, eventWeight); + } } m_hists.hist("mu_n")->Fill(event.m_muons.size(), eventWeight); for (const auto* const muPtr : event.m_muons) { - m_hists.hist("mu_pt")->Fill(muPtr->pt() * toGeV, eventWeight); - m_hists.hist("mu_eta")->Fill(muPtr->eta(), eventWeight); - m_hists.hist("mu_phi")->Fill(muPtr->phi(), eventWeight); - - //protection from derivation framework removing tracks - const xAOD::TrackParticle* mutrack = muPtr->primaryTrackParticle(); - if (mutrack!=nullptr) { - m_hists.hist("mu_charge")->Fill(mutrack->charge(), eventWeight); - if (m_config->isMC()) { - static SG::AuxElement::Accessor<int> acc_mctt("truthType"); - if (acc_mctt.isAvailable(*mutrack)) m_hists.hist("mu_true_type")->Fill(acc_mctt(*mutrack), eventWeight); - } - } + m_hists.hist("mu_pt")->Fill(muPtr->pt() * toGeV, eventWeight); + m_hists.hist("mu_eta")->Fill(muPtr->eta(), eventWeight); + m_hists.hist("mu_phi")->Fill(muPtr->phi(), eventWeight); + + //protection from derivation framework removing tracks + const xAOD::TrackParticle* mutrack = muPtr->primaryTrackParticle(); + if (mutrack != nullptr) { + m_hists.hist("mu_charge")->Fill(mutrack->charge(), eventWeight); + if (m_config->isMC()) { + static SG::AuxElement::Accessor<int> acc_mctt("truthType"); + if (acc_mctt.isAvailable(*mutrack)) m_hists.hist("mu_true_type")->Fill(acc_mctt(*mutrack), eventWeight); + } + } - //testing isolation in the derivation framework - float iso = 0; + //testing isolation in the derivation framework + float iso = 0; - if (muPtr->isAvailable<float>("topoetcone20") && muPtr->isolation(iso, xAOD::Iso::topoetcone20)) - m_hists.hist("mu_topoetcone20")->Fill(iso * toGeV, eventWeight); + if (muPtr->isAvailable<float>("topoetcone20") && muPtr->isolation(iso, xAOD::Iso::topoetcone20)) m_hists.hist( + "mu_topoetcone20")->Fill(iso * toGeV, eventWeight); - if (muPtr->isAvailable<float>("topoetcone30") && muPtr->isolation(iso, xAOD::Iso::topoetcone30)) - m_hists.hist("mu_topoetcone30")->Fill(iso * toGeV, eventWeight); + if (muPtr->isAvailable<float>("topoetcone30") && muPtr->isolation(iso, xAOD::Iso::topoetcone30)) m_hists.hist( + "mu_topoetcone30")->Fill(iso * toGeV, eventWeight); - if (muPtr->isAvailable<float>("topoetcone40") && muPtr->isolation(iso, xAOD::Iso::topoetcone40)) - m_hists.hist("mu_topoetcone40")->Fill(iso * toGeV, eventWeight); + if (muPtr->isAvailable<float>("topoetcone40") && muPtr->isolation(iso, xAOD::Iso::topoetcone40)) m_hists.hist( + "mu_topoetcone40")->Fill(iso * toGeV, eventWeight); - if (muPtr->isolation(iso, xAOD::Iso::ptcone20)) - m_hists.hist("mu_ptcone20")->Fill(iso * toGeV, eventWeight); + if (muPtr->isolation(iso, xAOD::Iso::ptcone20)) m_hists.hist("mu_ptcone20")->Fill(iso * toGeV, eventWeight); - if (muPtr->isolation(iso, xAOD::Iso::ptcone30)) - m_hists.hist("mu_ptcone30")->Fill(iso * toGeV, eventWeight); + if (muPtr->isolation(iso, xAOD::Iso::ptcone30)) m_hists.hist("mu_ptcone30")->Fill(iso * toGeV, eventWeight); - if (muPtr->isolation(iso, xAOD::Iso::ptcone40)) - m_hists.hist("mu_ptcone40")->Fill(iso * toGeV, eventWeight); + if (muPtr->isolation(iso, xAOD::Iso::ptcone40)) m_hists.hist("mu_ptcone40")->Fill(iso * toGeV, eventWeight); - if (muPtr->isAvailable<float>("ptvarcone20")) { - float ptvarcone20 = muPtr->auxdataConst<float>("ptvarcone20"); - m_hists.hist("mu_ptvarcone20")->Fill(ptvarcone20 * toGeV, eventWeight); - } + if (muPtr->isAvailable<float>("ptvarcone20")) { + float ptvarcone20 = muPtr->auxdataConst<float>("ptvarcone20"); + m_hists.hist("mu_ptvarcone20")->Fill(ptvarcone20 * toGeV, eventWeight); + } - if (muPtr->isAvailable<float>("ptvarcone30")) { - float ptvarcone30 = muPtr->auxdataConst<float>("ptvarcone30"); - m_hists.hist("mu_ptvarcone30")->Fill(ptvarcone30 * toGeV, eventWeight); - } + if (muPtr->isAvailable<float>("ptvarcone30")) { + float ptvarcone30 = muPtr->auxdataConst<float>("ptvarcone30"); + m_hists.hist("mu_ptvarcone30")->Fill(ptvarcone30 * toGeV, eventWeight); + } - if (muPtr->isAvailable<float>("ptvarcone40")) { - float ptvarcone40 = muPtr->auxdataConst<float>("ptvarcone40"); - m_hists.hist("mu_ptvarcone40")->Fill(ptvarcone40 * toGeV, eventWeight); - } + if (muPtr->isAvailable<float>("ptvarcone40")) { + float ptvarcone40 = muPtr->auxdataConst<float>("ptvarcone40"); + m_hists.hist("mu_ptvarcone40")->Fill(ptvarcone40 * toGeV, eventWeight); + } } m_hists.hist("ph_n")->Fill(event.m_photons.size(), eventWeight); for (const auto* const phPtr : event.m_photons) { - m_hists.hist("ph_pt") -> Fill(phPtr->pt() * toGeV, eventWeight); - m_hists.hist("ph_eta") -> Fill(phPtr->eta(), eventWeight); - m_hists.hist("ph_phi") -> Fill(phPtr->phi(), eventWeight); - m_hists.hist("ph_e") -> Fill(phPtr->e() * toGeV, eventWeight); - if (phPtr->isAvailable<float>("ptvarcone20")) { - float ptvarcone20 = phPtr->auxdataConst<float>("ptvarcone20"); - m_hists.hist("ph_ptvarcone20")->Fill(ptvarcone20 * toGeV, eventWeight); - } + m_hists.hist("ph_pt")->Fill(phPtr->pt() * toGeV, eventWeight); + m_hists.hist("ph_eta")->Fill(phPtr->eta(), eventWeight); + m_hists.hist("ph_phi")->Fill(phPtr->phi(), eventWeight); + m_hists.hist("ph_e")->Fill(phPtr->e() * toGeV, eventWeight); + if (phPtr->isAvailable<float>("ptvarcone20")) { + float ptvarcone20 = phPtr->auxdataConst<float>("ptvarcone20"); + m_hists.hist("ph_ptvarcone20")->Fill(ptvarcone20 * toGeV, eventWeight); + } } m_hists.hist("jet_n")->Fill(event.m_jets.size(), eventWeight); unsigned int i = 0; - std::array<std::string, 4> numbers{ {"jet0", "jet1", "jet2", "jet3"} }; + std::array<std::string, 4> numbers {{ + "jet0", "jet1", "jet2", "jet3" + }}; + for (const auto* const jetPtr : event.m_jets) { - m_hists.hist("jet_pt") -> Fill(jetPtr->pt() * toGeV, eventWeight); - m_hists.hist("jet_eta") -> Fill(jetPtr->eta(), eventWeight); - m_hists.hist("jet_phi") -> Fill(jetPtr->phi(), eventWeight); - m_hists.hist("jet_e") -> Fill(jetPtr->e() * toGeV, eventWeight); - - double mv2c10_discriminant = 0.; - const bool hasmv2c10 = jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); - if (hasmv2c10){ - m_hists.hist("jet_mv2c10")->Fill(mv2c10_discriminant, eventWeight); - - } - - int jet_truthflav = -1; - if (m_config->isMC()) { - if(jetPtr->isAvailable<int>("HadronConeExclTruthLabelID")){ - jetPtr->getAttribute("HadronConeExclTruthLabelID", jet_truthflav); - m_hists.hist("jet_truthflav")->Fill(jet_truthflav, eventWeight); - } - } - - int isbtagged = 0; - bool hasBtag = false; - float btagSF = 1.; - bool hasBtagSF = false; - hasBtag = jetPtr->isAvailable<char>("isbtagged_FixedCutBEff_77"); - if(hasBtag) { - isbtagged = jetPtr->auxdataConst<char>("isbtagged_FixedCutBEff_77"); - m_hists.hist("jet_isbtagged_77")->Fill(isbtagged, eventWeight); - if (m_config->isMC()) { - if (jetPtr -> isAvailable<float>("btag_SF_FixedCutBEff_77_nom")) { - btagSF = jetPtr -> auxdataConst<float>("btag_SF_FixedCutBEff_77_nom"); - m_hists.hist("jet_btagSF_77")->Fill(btagSF, eventWeight); - hasBtagSF = true; - } + m_hists.hist("jet_pt")->Fill(jetPtr->pt() * toGeV, eventWeight); + m_hists.hist("jet_eta")->Fill(jetPtr->eta(), eventWeight); + m_hists.hist("jet_phi")->Fill(jetPtr->phi(), eventWeight); + m_hists.hist("jet_e")->Fill(jetPtr->e() * toGeV, eventWeight); + + double mv2c10_discriminant = 0.; + const bool hasmv2c10 = jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); + if (hasmv2c10) { + m_hists.hist("jet_mv2c10")->Fill(mv2c10_discriminant, eventWeight); + } + + int jet_truthflav = -1; + if (m_config->isMC()) { + if (jetPtr->isAvailable<int>("HadronConeExclTruthLabelID")) { + jetPtr->getAttribute("HadronConeExclTruthLabelID", jet_truthflav); + m_hists.hist("jet_truthflav")->Fill(jet_truthflav, eventWeight); + } + } + + int isbtagged = 0; + bool hasBtag = false; + float btagSF = 1.; + bool hasBtagSF = false; + hasBtag = jetPtr->isAvailable<char>("isbtagged_MV2c10_FixedCutBEff_77"); + if (hasBtag) { + isbtagged = jetPtr->auxdataConst<char>("isbtagged_MV2c10_FixedCutBEff_77"); + m_hists.hist("jet_isbtagged_MV2c10_77")->Fill(isbtagged, eventWeight); + if (m_config->isMC()) { + if (jetPtr->isAvailable<float>("btag_SF_MV2c10_FixedCutBEff_77_nom")) { + btagSF = jetPtr->auxdataConst<float>("btag_SF_MV2c10_FixedCutBEff_77_nom"); + m_hists.hist("jet_btagSF_MV2c10_77")->Fill(btagSF, eventWeight); + hasBtagSF = true; } } - - if (i < numbers.size()) { - m_hists.hist(numbers[i] + "_pt") -> Fill(jetPtr->pt() * toGeV, eventWeight); - m_hists.hist(numbers[i] + "_eta") -> Fill(jetPtr->eta(), eventWeight); - m_hists.hist(numbers[i] + "_phi") -> Fill(jetPtr->phi(), eventWeight); - m_hists.hist(numbers[i] + "_e") -> Fill(jetPtr->e() * toGeV, eventWeight); - m_hists.hist(numbers[i] + "_mv2c10") -> Fill(mv2c10_discriminant, eventWeight); - if(hasBtag) m_hists.hist(numbers[i] + "_isbtagged_77")->Fill(isbtagged, eventWeight); - if (m_config->isMC()) { - if (hasBtagSF) m_hists.hist(numbers[i] + "_btagSF_77")->Fill(btagSF, eventWeight); - m_hists.hist(numbers[i] + "_truthflav")->Fill(jet_truthflav, eventWeight); - } + } + + if (i < numbers.size()) { + m_hists.hist(numbers[i] + "_pt")->Fill(jetPtr->pt() * toGeV, eventWeight); + m_hists.hist(numbers[i] + "_eta")->Fill(jetPtr->eta(), eventWeight); + m_hists.hist(numbers[i] + "_phi")->Fill(jetPtr->phi(), eventWeight); + m_hists.hist(numbers[i] + "_e")->Fill(jetPtr->e() * toGeV, eventWeight); + m_hists.hist(numbers[i] + "_mv2c10")->Fill(mv2c10_discriminant, eventWeight); + if (hasBtag) m_hists.hist(numbers[i] + "_isbtagged_MV2c10_77")->Fill(isbtagged, eventWeight); + if (m_config->isMC()) { + if (hasBtagSF) m_hists.hist(numbers[i] + "_btagSF_MV2c10_77")->Fill(btagSF, eventWeight); + m_hists.hist(numbers[i] + "_truthflav")->Fill(jet_truthflav, eventWeight); } + } - ++i; + + ++i; } - m_hists.hist("ljet_n") -> Fill(event.m_largeJets.size(), eventWeight); + m_hists.hist("ljet_n")->Fill(event.m_largeJets.size(), eventWeight); for (const auto* const jetPtr : event.m_largeJets) { - m_hists.hist("ljet_pt") -> Fill(jetPtr->pt() * toGeV, eventWeight); - m_hists.hist("ljet_eta") -> Fill(jetPtr->eta(), eventWeight); - m_hists.hist("ljet_phi") -> Fill(jetPtr->phi(), eventWeight); - m_hists.hist("ljet_m") -> Fill(jetPtr->m() * toGeV, eventWeight); - - float Split12 = 0; - jetPtr->getAttribute("Split12", Split12); - m_hists.hist("ljet_sd12") -> Fill(Split12 * toGeV, eventWeight); - + m_hists.hist("ljet_pt")->Fill(jetPtr->pt() * toGeV, eventWeight); + m_hists.hist("ljet_eta")->Fill(jetPtr->eta(), eventWeight); + m_hists.hist("ljet_phi")->Fill(jetPtr->phi(), eventWeight); + m_hists.hist("ljet_m")->Fill(jetPtr->m() * toGeV, eventWeight); + + float Split12 = 0; + jetPtr->getAttribute("Split12", Split12); + m_hists.hist("ljet_sd12")->Fill(Split12 * toGeV, eventWeight); } m_hists.hist("taujet_n")->Fill(event.m_tauJets.size(), eventWeight); for (const auto* const tauPtr : event.m_tauJets) { - m_hists.hist("taujet_pt") -> Fill(tauPtr->pt() * toGeV, eventWeight); - m_hists.hist("taujet_eta") -> Fill(tauPtr->eta(), eventWeight); - m_hists.hist("taujet_phi") -> Fill(tauPtr->phi(), eventWeight); - m_hists.hist("taujet_charge") -> Fill(tauPtr->charge(), eventWeight); + m_hists.hist("taujet_pt")->Fill(tauPtr->pt() * toGeV, eventWeight); + m_hists.hist("taujet_eta")->Fill(tauPtr->eta(), eventWeight); + m_hists.hist("taujet_phi")->Fill(tauPtr->phi(), eventWeight); + m_hists.hist("taujet_charge")->Fill(tauPtr->charge(), eventWeight); } if (event.m_met != nullptr) { - m_hists.hist("event_met_et") -> Fill(event.m_met->met() * toGeV, eventWeight); - m_hists.hist("event_met_phi") -> Fill(event.m_met->phi(), eventWeight); + m_hists.hist("event_met_et")->Fill(event.m_met->met() * toGeV, eventWeight); + m_hists.hist("event_met_phi")->Fill(event.m_met->phi(), eventWeight); } return true; -} + } -std::string ExamplePlots::name() const { + std::string ExamplePlots::name() const { return "EXAMPLEPLOTS"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/FakesMMConfigs.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/FakesMMConfigs.cxx index d133f58b0751..f47167d40678 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/FakesMMConfigs.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/FakesMMConfigs.cxx @@ -1,15 +1,14 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/FakesMMConfigs.h" namespace top { - FakesMMConfigs::FakesMMConfigs(const std::string& configs) { std::istringstream iss(configs); std::string config; - while (iss>>config) { + while (iss >> config) { m_configurations.push_back(config); } } @@ -21,5 +20,4 @@ namespace top { std::string FakesMMConfigs::name() const { return "FAKESMMCONFIGS"; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GRLSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GRLSelector.cxx index 91a261bed8ea..3b91c04c15ba 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GRLSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GRLSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/GRLSelector.h" @@ -9,13 +9,10 @@ #include "xAODEventInfo/EventInfo.h" namespace top { - - GRLSelector::GRLSelector() - { + GRLSelector::GRLSelector() { } - bool GRLSelector::apply(const top::Event& event) const - { + bool GRLSelector::apply(const top::Event& event) const { if (event.m_info->isAvailable<char>("AnalysisTop_GRL")) { if (event.m_info->auxdataConst<char>("AnalysisTop_GRL") == 1) { return true; @@ -24,9 +21,7 @@ namespace top { return false; } - std::string GRLSelector::name() const - { + std::string GRLSelector::name() const { return "GRL"; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigDecisionSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigDecisionSelector.cxx new file mode 100644 index 000000000000..252027d95c2c --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigDecisionSelector.cxx @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/GlobalTrigDecisionSelector.h" +#include "TopEvent/Event.h" +#include "TopEvent/EventTools.h" + +#include <vector> +#include <iostream> + + +namespace top { + GlobalTrigDecisionSelector::GlobalTrigDecisionSelector() + : m_globalTriggerSF("TrigGlobalEfficiencyCorrectionTool::TrigGlobal") + , m_globalTriggerSFLoose("TrigGlobalEfficiencyCorrectionTool::TrigGlobalLoose") { + } + + bool GlobalTrigDecisionSelector::apply(top::Event const& event) const { + auto&& tool = (event.m_isLoose ? m_globalTriggerSFLoose : m_globalTriggerSF); + + std::vector<std::string> triggers; +// top::check(tool->getRelevantTriggers(triggers), "TrigGlobalEfficiencyCorrectionTool::getRelevantTriggers failed"); + for (std::string const& trigger : triggers) { + if (event.m_info->auxdataConst<char>("TRIGDEC_HLT_" + trigger) > 0) return true; + } + return false; + } + + std::string GlobalTrigDecisionSelector::name() const { + return "GTRIGDEC"; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigMatchSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigMatchSelector.cxx new file mode 100644 index 000000000000..1dbed2e6c693 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigMatchSelector.cxx @@ -0,0 +1,39 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/GlobalTrigMatchSelector.h" +#include "TopEvent/Event.h" +#include "TopEvent/EventTools.h" + +#include "xAODBase/IParticle.h" +#include "xAODEgamma/ElectronContainer.h" +#include "xAODMuon/MuonContainer.h" + +#include <iostream> +#include <vector> + + +namespace top { + GlobalTrigMatchSelector::GlobalTrigMatchSelector() + : m_globalTriggerSF("TrigGlobalEfficiencyCorrectionTool::TrigGlobal") + , m_globalTriggerSFLoose("TrigGlobalEfficiencyCorrectionTool::TrigGlobalLoose") { + } + + bool GlobalTrigMatchSelector::apply(top::Event const& event) const { + auto&& tool = (event.m_isLoose ? m_globalTriggerSFLoose : m_globalTriggerSF); + bool result = false; + + std::vector<xAOD::IParticle const*> particles; + particles.insert(particles.end(), event.m_electrons.begin(), event.m_electrons.end()); + particles.insert(particles.end(), event.m_muons.begin(), event.m_muons.end()); +// top::check(tool->checkTriggerMatching(result, +// particles), +// "TrigGlobalEfficiencyCorrectionTool::checkTriggerMatching failed"); + return result; + } + + std::string GlobalTrigMatchSelector::name() const { + return "GTRIGMATCH"; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GoodCaloSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GoodCaloSelector.cxx index 430560520263..e7d78ddd04a8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GoodCaloSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GoodCaloSelector.cxx @@ -1,18 +1,15 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/GoodCaloSelector.h" #include "TopEvent/EventTools.h" namespace top { - - GoodCaloSelector::GoodCaloSelector() - { + GoodCaloSelector::GoodCaloSelector() { } - bool GoodCaloSelector::apply(const top::Event& event) const - { + bool GoodCaloSelector::apply(const top::Event& event) const { if (event.m_info->isAvailable<char>("AnalysisTop_GOODCALO")) { if (event.m_info->auxdataConst<char>("AnalysisTop_GOODCALO") == 1) { return true; @@ -21,9 +18,7 @@ namespace top { return false; } - std::string GoodCaloSelector::name() const - { + std::string GoodCaloSelector::name() const { return "GOODCALO"; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/HTSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/HTSelector.cxx index 4627ce137a86..f850f464f9a6 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/HTSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/HTSelector.cxx @@ -1,43 +1,42 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/HTSelector.h" #include "TopEvent/EventTools.h" namespace top { + HTSelector::HTSelector(const std::string& params) : + SignValueSelector("HT", params) { + } -HTSelector::HTSelector(const std::string& params) : - SignValueSelector("HT", params) { -} - -bool HTSelector::apply(const top::Event& event) const { + bool HTSelector::apply(const top::Event& event) const { const double ht = top::ht(event); + return checkFloat(ht, value()); -} + } -bool HTSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool HTSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons - or not event.m_jets ){ - return false; + if (not event.m_electrons + or not event.m_muons + or not event.m_jets) { + return false; } double sumHt = 0.0; - for (const auto el : * event.m_electrons) - sumHt += el->pt(); + for (const auto el : *event.m_electrons) + sumHt += el->pt(); - for (const auto mu : * event.m_muons) - sumHt += mu->pt(); + for (const auto mu : *event.m_muons) + sumHt += mu->pt(); - for (const auto jet : * event.m_jets) - sumHt += jet->pt(); + for (const auto jet : *event.m_jets) + sumHt += jet->pt(); return checkFloat(sumHt, value()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/InitialSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/InitialSelector.cxx index 06599f35b9d7..2b638f0b514d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/InitialSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/InitialSelector.cxx @@ -1,17 +1,15 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/InitialSelector.h" namespace top { - -bool InitialSelector::apply(const top::Event&) const { + bool InitialSelector::apply(const top::Event&) const { return true; -} + } -std::string InitialSelector::name() const { + std::string InitialSelector::name() const { return "INITIAL"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetCleaningSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetCleaningSelector.cxx index 8e2a2f9cc03a..63d05d636eea 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetCleaningSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetCleaningSelector.cxx @@ -1,65 +1,130 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/JetCleaningSelector.h" #include "TopEvent/EventTools.h" #include "xAODJet/JetContainer.h" #include "TopConfiguration/TopConfig.h" +#include "TopEventSelectionTools/MsgCategory.h" +using namespace TopEventSelectionTools; namespace top { - JetCleaningSelector::JetCleaningSelector(const std::string& level, std::shared_ptr<top::TopConfig> config) : - m_jetCleaningToolLooseBad("JetCleaningToolLooseBad"), - m_jetCleaningToolTightBad("JetCleaningToolTightBad"), m_level(level), m_useLooseBad(true), - m_config(config) - { + m_config(config) { + if (!m_config->isTruthDxAOD()) { + m_jetCleaningToolLooseBad = ToolHandle<IJetSelector>("JetCleaningToolLooseBad"); + m_jetCleaningToolTightBad = ToolHandle<IJetSelector>("JetCleaningToolTightBad"); + m_jetEventCleaningToolLooseBad = ToolHandle<ECUtils::IEventCleaningTool>("JetEventCleaningToolLooseBad"); + m_jetEventCleaningToolTightBad = ToolHandle<ECUtils::IEventCleaningTool>("JetEventCleaningToolTightBad"); - if (m_level != "LooseBad" && m_level != "TightBad") { - std::cout << "JetCleaningSelector level not recognised - " << m_level << "\n"; - std::cout << "Should be LooseBad or TightBad\n"; - exit(1); - } - - if (m_level == "LooseBad") m_useLooseBad = true; - if (m_level == "TightBad") m_useLooseBad = false; - - // we can't yet use jet cleaning for particle-flow jets - if (!m_config->useParticleFlowJets()) { - if (m_useLooseBad) - top::check( m_jetCleaningToolLooseBad.retrieve() , "Failed to retrieve JetCleaningToolLooseBad" ); - if (!m_useLooseBad) - top::check( m_jetCleaningToolTightBad.retrieve() , "Failed to retrieve JetCleaningToolTightBad" ); + if (m_level != "LooseBad" && m_level != "TightBad") { + ATH_MSG_ERROR("JetCleaningSelector level not recognised - " << m_level << "\n" + << "Should be LooseBad or TightBad"); + throw std::runtime_error ("JetCleaningSelector: Cannot continue"); + } + + if (m_level == "LooseBad") m_useLooseBad = true; + if (m_level == "TightBad") m_useLooseBad = false; + + + m_useEventLevelJetCleaningTool = m_config->useEventLevelJetCleaningTool(); + + // Checking configuration for particle-flow jets: + if (m_config->useParticleFlowJets()) { + top::check(m_useLooseBad, + "JetCleaningSelector: This cleaning configuration is not available for particle-flow jets. The only available configuration is\n JETCLEAN LooseBad"); + } + + // We can't yet use jet cleaning or event cleaning tools for particle-flow jets + if (!m_config->useParticleFlowJets()) { + if (m_useEventLevelJetCleaningTool) { + if (m_useLooseBad) top::check( + m_jetEventCleaningToolLooseBad.retrieve(), "Failed to retrieve JetEventCleaningToolLooseBad"); + else top::check(m_jetEventCleaningToolTightBad.retrieve(), "Failed to retrieve JetEventCleaningToolTightBad"); + + } else { + if (m_useLooseBad) top::check( + m_jetCleaningToolLooseBad.retrieve(), "Failed to retrieve JetCleaningToolLooseBad"); + else top::check(m_jetCleaningToolTightBad.retrieve(), "Failed to retrieve JetCleaningToolTightBad"); + } + } // end (!m_config->useParticleFlowJets()) } } bool JetCleaningSelector::apply(const top::Event& event) const { - for (const auto* const jetPtr : event.m_jets){ - // we can't yet use jet cleaning for particle-flow jets, so do nothing in this case - if (m_config->useParticleFlowJets()) return true; - - if (m_useLooseBad) { - if (m_jetCleaningToolLooseBad->keep(*jetPtr) == 0) { - return false; - } + if (m_config->isTruthDxAOD()) return true; + + if (m_config->useParticleFlowJets()) { + top::check(event.m_info->isAvailable<char>( + "DFCommonJets_eventClean_LooseBad"), + "JetCleaningSelector: DFCommonJets_eventClean_LooseBad not available in EventInfo. Needed for particle-flow jets cleaning"); + bool result = event.m_info->auxdataConst<char>("DFCommonJets_eventClean_LooseBad"); + + if (result && m_config->useBadBatmanCleaning()) { + // passed the standard cleaning + // finally, check if the BadBatman cleaning should be applied + return JetCleaningSelector::checkBadBatman(event); } - - if (!m_useLooseBad) { - if (m_jetCleaningToolTightBad->keep(*jetPtr) == 0) { - return false; + return result; + } + + // There are two jet cleaning tools and we have a request to test the event level one + // These should be very close/ equivalent as we already handle the OR and JVT elsewhere + if (m_useEventLevelJetCleaningTool) { + // If we are to use the event object, we can just do acceptEvent + + if (m_useLooseBad) return m_jetEventCleaningToolLooseBad->acceptEvent(&event.m_jets); + else return m_jetEventCleaningToolTightBad->acceptEvent(&event.m_jets); + } + // This is the default/standard method for jet cleaning + else { + for (const auto* const jetPtr : event.m_jets) { + if (m_useLooseBad) { + if (m_jetCleaningToolLooseBad->keep(*jetPtr) == 0) { + return false; + } + } else { + if (m_jetCleaningToolTightBad->keep(*jetPtr) == 0) { + return false; + } } } - + } + + // passed the standard cleaning + // finally, check if the BadBatman cleaning should be applied + if (m_config->useBadBatmanCleaning()) { + return JetCleaningSelector::checkBadBatman(event); } return true; } - std::string JetCleaningSelector::name() const - { + std::string JetCleaningSelector::name() const { return "JETCLEAN " + m_level; } + bool JetCleaningSelector::checkBadBatman(const top::Event& event) const { + // we apply this only to Data + if (m_config->isMC()) { + return true; + } + // first check if the RunNUmber are within the specified range + const unsigned int runNumber = event.m_info->runNumber(); + + if ((m_config->badBatmanCleaningMin() >= runNumber) || (m_config->badBatmanCleaningMax() <= runNumber)) { + // is outside of the specified range + return true; + } + + top::check(event.m_info->isAvailable<char>( + "DFCommonJets_isBadBatman"), + "JetCleaningSelector: DFCommonJets_isBadBatman not available in EventInfo. Needed for BadBatman cleaning"); + const bool result = event.m_info->auxdataConst<char>("DFCommonJets_isBadBatman"); + // we need to return negation of the flag as it is true for problematic events + return !result; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetFlavorPlots.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetFlavorPlots.cxx index e7545d70af9b..bd156abbb52f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetFlavorPlots.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetFlavorPlots.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/JetFlavorPlots.h" @@ -9,6 +9,7 @@ #include <string> #include "TopEvent/EventTools.h" +#include "TopConfiguration/TopConfig.h" #include "TopCorrections/ScaleFactorRetriever.h" #include "TH1.h" @@ -18,59 +19,262 @@ // Systematic include(s): #include "PATInterfaces/SystematicSet.h" +#include "TopEventSelectionTools/MsgCategory.h" +using namespace TopEventSelectionTools; + namespace top { + const double JetFlavorPlots::toGeV = 0.001; -const double JetFlavorPlots::toGeV = 0.001; -JetFlavorPlots::JetFlavorPlots(const std::string& name, - TFile* outputFile, EL::Worker* wk) : - m_hists(name, outputFile, wk), m_nominalHashValue(0) { + JetFlavorPlots::JetFlavorPlots(const std::string& name, + TFile* outputFile, const std::string& params, std::shared_ptr<top::TopConfig> config, + EL::Worker* wk) : + m_nominalHashValue(0), + m_detailed(false), + m_doNominal(false), + m_doRadHigh(false), + m_doRadLow(false), + // default pT and eta binning, and default max number of Jets + m_ptBins("15:20:30:45:60:80:110:160:210:260:310:400:500:600:800:1000:1200:1500:1800:2500"), + m_etaBins("0.:0.3:0.8:1.2:2.1:2.8:3.6:4.5"), + m_nJetsMax(15), + m_jetCollection(""), + m_config(config), + m_PMGTruthWeights(nullptr), + m_throwwarningPMG(true) { CP::SystematicSet nominal; m_nominalHashValue = nominal.hash(); - m_hists.addHist("gluon_jets", ";pT [GeV];Eta;Events", - 50, 0., 500., 10, 0, 5); - m_hists.addHist("quark_jets", ";pT [GeV];Eta;Events", - 50, 0., 500., 10, 0, 5); -} + // retrieve jet collection and remove the "Jets" at the end of it + m_jetCollection = m_config->sgKeyJets(); + int pos = m_jetCollection.find("Jets"); + m_jetCollection.erase(pos); + //FIXME: If no metadata is available, the PMGTool will crash. Providing here a "manual" workaround. + //FIXME PMG: comment from here + //retrieve PMGTruthWeights + const std::string truthWeightToolName = "PMGTruthWeightTool"; + if (asg::ToolStore::contains<PMGTools::PMGTruthWeightTool>(truthWeightToolName)) m_PMGTruthWeights = + asg::ToolStore::get<PMGTools::PMGTruthWeightTool>(truthWeightToolName); + else { + m_PMGTruthWeights = new PMGTools::PMGTruthWeightTool(truthWeightToolName); + top::check(m_PMGTruthWeights->initialize(), "Failed to initialize " + truthWeightToolName); + } + //FIXME PMG: comment till here + //decoding arguments + std::istringstream stream(params); + std::string s; + while (stream >> s) { + if (s == "detailed") m_detailed = true; + else if (s.substr(0, 3) == "pt:" || s.substr(0, 3) == "pT:") m_ptBins = s.substr(3, s.size() - 3); + else if (s.substr(0, 7) == "abseta:") m_etaBins = s.substr(7, s.size() - 7); + else if (s.substr(0, 9) == "nJetsMax:") m_nJetsMax = std::atoi(s.substr(9, s.size() - 9).c_str()); + else if (s == "nominal" || s == "NOMINAL" || s == "Nominal") m_doNominal = true; + else if (s == "radiationhigh" || s == "RADIATIONHIGH" || s == "RadiationHigh" || + s == "radiationHigh") m_doRadHigh = true; + else if (s == "radiationlow" || s == "RADIATIONLOW" || s == "RadiationLow" || + s == "radiationLow") m_doRadLow = true; + else { + throw std::runtime_error("ERROR: Can't understand argument " + s + "For JETFLAVORPLOTS"); + } + } + //If neither nominal or radiation has been selected, assume it's nominal + if ((m_doNominal + m_doRadHigh + m_doRadLow) == false) m_doNominal = true; + // create the JetFlavorPlots and JetFlavorPlots_Loose directories only if needed + if (m_config->doTightEvents()) { + if (m_doNominal) m_hists = std::make_shared<PlotManager>(name + "/JetFlavorPlots", outputFile, wk); + if (m_doRadHigh) m_hists_RadHigh = + std::make_shared<PlotManager>(name + "/JetFlavorPlots_RadHigh", outputFile, wk); + if (m_doRadLow) m_hists_RadLow = std::make_shared<PlotManager>(name + "/JetFlavorPlots_RadLow", outputFile, wk); + } + if (m_config->doLooseEvents()) { + if (m_doNominal) m_hists_Loose = std::make_shared<PlotManager>(name + "/JetFlavorPlots_Loose", outputFile, wk); + if (m_doRadHigh) m_hists_RadHigh_Loose = std::make_shared<PlotManager>(name + "/JetFlavorPlots_Loose_RadHigh", + outputFile, wk); + if (m_doRadLow) m_hists_RadLow_Loose = std::make_shared<PlotManager>(name + "/JetFlavorPlots_Loose_RadLow", + outputFile, wk); + } + //handle binning + std::vector<double> ptBinning; + std::vector<double> etaBinning; + formatBinning(m_ptBins, ptBinning); + formatBinning(m_etaBins, etaBinning); + std::ostream& msgInfo = msg(MSG::Level::INFO); + msgInfo << "Here is the binning used for JETFLAVORPLOTS in selection " << name << ":\n"; + msgInfo << "pt: "; + for (auto pt:ptBinning) msgInfo << pt << " "; + msgInfo << "\n"; + msgInfo << "abseta: "; + for (auto eta:etaBinning) msgInfo << eta << " "; + msgInfo << std::endl; + + if (m_config->doTightEvents()) { + if (m_doNominal) BookHistograms(m_hists, ptBinning, etaBinning); + if (m_doRadHigh) BookHistograms(m_hists_RadHigh, ptBinning, etaBinning); + if (m_doRadLow) BookHistograms(m_hists_RadLow, ptBinning, etaBinning); + } + if (m_config->doLooseEvents()) { + if (m_doNominal) BookHistograms(m_hists_Loose, ptBinning, etaBinning); + if (m_doRadHigh) BookHistograms(m_hists_RadHigh_Loose, ptBinning, etaBinning); + if (m_doRadLow) BookHistograms(m_hists_RadLow_Loose, ptBinning, etaBinning); + } + } + + void JetFlavorPlots::BookHistograms(std::shared_ptr<PlotManager> h_ptr, std::vector<double> ptBins, + std::vector<double> etaBins) { + if (m_detailed) { + for (std::string flavour:{"gluon", "lightquark", "cquark", "bquark", "other"}) { + // vs. nJets and flavour + for (int i = 0; i <= m_nJetsMax; ++i) { + h_ptr->addHist(flavour + "_jets_njet" + std::to_string( + i) + "_" + m_jetCollection, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + } + // vs. flavour only + h_ptr->addHist(flavour + "_jets_" + m_jetCollection, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + } + // if "detailed", also making the quark_jets one + h_ptr->addHist("quark_jets_" + m_jetCollection, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + } else { + // the simplest case, one for gluon, one for quarks + h_ptr->addHist("quark_jets_" + m_jetCollection, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + h_ptr->addHist("gluon_jets_" + m_jetCollection, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + } + } + + bool JetFlavorPlots::apply(const top::Event& event) const { + //only MC + if (!top::isSimulation(event)) return true; -bool JetFlavorPlots::apply(const top::Event& event) const { // only nominal - if (event.m_hashValue != m_nominalHashValue) - return true; + if (event.m_hashValue != m_nominalHashValue) return true; + + // do loose or tight events only if requested + if (event.m_isLoose && !m_config->doLooseEvents()) return true; + + if (!event.m_isLoose && !m_config->doTightEvents()) return true; + + double nominalWeight = event.m_info->auxdata<float>("AnalysisTop_eventWeight"); - // only plot tight selection - // before, we were plotting tight and loose together - if (event.m_isLoose) - return true; + if (m_doNominal) { + double eventWeight = nominalWeight; - double eventWeight = 1.; - if (top::isSimulation(event)) -// eventWeight = event.m_info->mcEventWeight(); - eventWeight = event.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix - else // Only do this for MC - return true; + if (event.m_isLoose) FillHistograms(m_hists_Loose, eventWeight, event); + else FillHistograms(m_hists, eventWeight, event); + } + if (m_doRadHigh) { + // 2 different names are acceptable + double scaleWeight = 1.; + if (m_PMGTruthWeights->hasWeight(" muR = 0.5, muF = 0.5 ")) scaleWeight = m_PMGTruthWeights->getWeight(" muR = 0.5, muF = 0.5 "); + else if (m_PMGTruthWeights->hasWeight(" muR = 0.50, muF = 0.50 ")) scaleWeight = m_PMGTruthWeights->getWeight(" muR = 0.50, muF = 0.50 "); + else top::check(m_PMGTruthWeights->hasWeight(" muR = 0.5, muF = 0.5 "), "JetFlavorPlots::apply(): Weight \" muR = 0.5, muF = 0.5 \" not found. Please report this message!"); + top::check(m_PMGTruthWeights->hasWeight("Var3cUp"), "JetFlavorPlots::apply(): Weight \"Var3cUp\" not found. Please report this message!"); + double eventWeight = scaleWeight * m_PMGTruthWeights->getWeight("Var3cUp") / nominalWeight; + if (event.m_isLoose) FillHistograms(m_hists_RadHigh_Loose, eventWeight, event); + else FillHistograms(m_hists_RadHigh, eventWeight, event); + } + if (m_doRadLow) { + //2 different names are acceptable + double scaleWeight = 1.; + if (m_PMGTruthWeights->hasWeight(" muR = 2.0, muF = 2.0 ")) scaleWeight = m_PMGTruthWeights->getWeight(" muR = 2.0, muF = 2.0 "); + else if (m_PMGTruthWeights->hasWeight(" muR = 2.00, muF = 2.00 ")) scaleWeight = m_PMGTruthWeights->getWeight(" muR = 2.00, muF = 2.00 "); + else top::check(m_PMGTruthWeights->hasWeight(" muR = 2.0, muF = 2.0 "), "JetFlavorPlots::apply(): Weight \" muR = 2.0, muF = 2.0 \" not found. Please report this message!"); + top::check(m_PMGTruthWeights->hasWeight("Var3cUp"), "JetFlavorPlots::apply(): Weight \"Var3cUp\" not found. Please report this message!"); + top::check(m_PMGTruthWeights->hasWeight("Var3cDown"), "JetFlavorPlots::apply(): Weight \"Var3cDown\" not found. Please report this message!"); + double eventWeight = scaleWeight * m_PMGTruthWeights->getWeight("Var3cDown") / nominalWeight; + if (event.m_isLoose) FillHistograms(m_hists_RadLow_Loose, eventWeight, event); + else FillHistograms(m_hists_RadLow, eventWeight, event); + } + return true; + } + + void JetFlavorPlots::FillHistograms(std::shared_ptr<PlotManager> h_ptr, double w_event, const top::Event& event) const { + bool throwWarning = false; for (const auto* const jetPtr : event.m_jets) { int jet_flavor = -99; bool status = jetPtr->getAttribute<int>("PartonTruthLabelID", jet_flavor); if (!status) continue; - if (jet_flavor == 21) { // PDG ID for gluon is 21 - static_cast<TH2D*>(m_hists.hist("gluon_jets"))->Fill(jetPtr->pt()*toGeV, - jetPtr->eta(), - eventWeight); + + if (m_detailed) { + if ((unsigned int) m_nJetsMax >= event.m_jets.size()) { + // vs. nJets and flavour + char name[200]; + // PDG ID for gluon is 21 + if (jet_flavor == 21) sprintf(name, "gluon_jets_njet%lu_%s", event.m_jets.size(), m_jetCollection.c_str()); + // PDG ID for d,u,s is 1,2,3 + else if (jet_flavor >= 1 && jet_flavor <= 3) sprintf(name, "lightquark_jets_njet%lu_%s", event.m_jets.size(), m_jetCollection.c_str()); + // PDG ID for c is 4 + else if (jet_flavor == 4) sprintf(name, "cquark_jets_njet%lu_%s", event.m_jets.size(), m_jetCollection.c_str()); + // PDG ID for b is 5 + else if (jet_flavor == 5) sprintf(name, "bquark_jets_njet%lu_%s", event.m_jets.size(), m_jetCollection.c_str()); + else sprintf(name, "other_jets_njet%lu_%s", event.m_jets.size(), m_jetCollection.c_str()); + + static_cast<TH2D*>(h_ptr->hist(name))->Fill(jetPtr->pt() * toGeV, + jetPtr->eta(), + w_event); + + // if "detailed", also making the quark_jets one + if (jet_flavor >= 1 && jet_flavor <= 4) { + sprintf(name, "quark_jets_%s", m_jetCollection.c_str()); + + static_cast<TH2D*>(h_ptr->hist(name))->Fill(jetPtr->pt() * toGeV, + jetPtr->eta(), + w_event); + } + } else throwWarning = true; + // vs. flavour only + char shortname[200]; + // PDG ID for gluon is 21 + if (jet_flavor == 21) sprintf(shortname, "gluon_jets_%s", m_jetCollection.c_str()); + // PDG ID for d,u,s is 1,2,3 + else if (jet_flavor >= 1 && jet_flavor <= 3) sprintf(shortname, "lightquark_jets_%s", m_jetCollection.c_str()); + // PDG ID for c is 4 + else if (jet_flavor == 4) sprintf(shortname, "cquark_jets_%s", m_jetCollection.c_str()); + // PDG ID for b is 5 + else if (jet_flavor == 5) sprintf(shortname, "bquark_jets_%s", m_jetCollection.c_str()); + else sprintf(shortname, "other_jets_%s", m_jetCollection.c_str()); + + static_cast<TH2D*>(h_ptr->hist(shortname))->Fill(jetPtr->pt() * toGeV, + jetPtr->eta(), + w_event); } else { - static_cast<TH2D*>(m_hists.hist("quark_jets"))->Fill(jetPtr->pt()*toGeV, - jetPtr->eta(), - eventWeight); + // the simplest case, one for gluon, one for quarks + char name[200]; + // PDG ID for gluon is 21 + if (jet_flavor == 21) sprintf(name, "gluon_jets_%s", m_jetCollection.c_str()); + // PDG ID for d,u,s is 1,2,3 + else if (jet_flavor >= 1 && jet_flavor <= 4) sprintf(name, "quark_jets_%s", m_jetCollection.c_str()); + // We are not interested in other PDG IDs + else continue; + + static_cast<TH2D*>(h_ptr->hist(name))->Fill(jetPtr->pt() * toGeV, + jetPtr->eta(), + w_event); } } - return true; -} + if (throwWarning){ + ATH_MSG_WARNING("Warning! Number of jets in the event is " << event.m_jets.size() + << ", but histograms have been booked up to " << m_nJetsMax + << ". Exclusive histograms in number of jets have not been filled.\n"); + } + } -std::string JetFlavorPlots::name() const { - return "JETFLAVORPLOTS"; -} +// function to translate the binnings into vector of bin edges + void JetFlavorPlots::formatBinning(const std::string& str, std::vector<double>& binEdges) { + std::stringstream ss(str); + std::string tok; + char separator = ':'; + while (std::getline(ss, tok, separator)) { + binEdges.push_back(std::atof(tok.c_str())); + } + } + std::string JetFlavorPlots::name() const { + return "JETFLAVORPLOTS"; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetFtagEffPlots.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetFtagEffPlots.cxx new file mode 100644 index 000000000000..33360ac3da7d --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetFtagEffPlots.cxx @@ -0,0 +1,393 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/JetFtagEffPlots.h" + +#include <cmath> +#include <array> +#include <string> + +#include "TopEvent/EventTools.h" +#include "TopConfiguration/TopConfig.h" +#include "TopCorrections/ScaleFactorRetriever.h" + +#include "TH1.h" +#include "TH2D.h" +#include "TFile.h" + +// Systematic include(s): +#include "PATInterfaces/SystematicSet.h" + +#include "TopEventSelectionTools/MsgCategory.h" +using namespace TopEventSelectionTools; + +namespace top { + const double JetFtagEffPlots::toGeV = 0.001; + + + JetFtagEffPlots::JetFtagEffPlots(const std::string& name, + TFile* outputFile, const std::string& params, std::shared_ptr<top::TopConfig> config, + EL::Worker* wk) : + m_nominalHashValue(0), + m_CDIfile("xAODBTaggingEfficiency/13TeV/2020-21-13TeV-MC16-CDI-2020-03-11_v3.root"), + m_fill_total_hists(false), + m_histogram_suffix(""), + m_dont_use_event_weight(false), + m_use_track_jets(false), + m_doNominal(false), + m_doMuRup(false), + m_doMuRdown(false), + m_doMuFup(false), + m_doMuFdown(false), + m_doVar3cup(false), + m_doVar3cdown(false), + m_doFSRup(false), + m_doFSRdown(false), + // default pT and eta binning + m_ptBins("15:20:30:45:60:80:110:160:210:260:310:400:500:600:800:1000:1200:1500:1800:2500"), + m_etaBins("0.:0.3:0.8:1.2:2.1:2.8:3.6:4.5"), + m_max_pT(-1), + m_min_pT(-1), + m_N_pT_bins(-1), + m_max_Eta(-1), + m_min_Eta(-1), + m_N_Eta_bins(-1), + m_jetCollection(""), + m_WP("FixedCutBEff_70"), + m_tagger("DL1"), + m_config(config), + m_selection_tool("BTaggingSelectionTool/selTool"), + m_PMGTruthWeights(nullptr), + m_sfRetriever(nullptr) { + CP::SystematicSet nominal; + m_nominalHashValue = nominal.hash(); + + + const std::string truthWeightToolName = "PMGTruthWeightTool"; + if (asg::ToolStore::contains<PMGTools::PMGTruthWeightTool>(truthWeightToolName)) m_PMGTruthWeights = + asg::ToolStore::get<PMGTools::PMGTruthWeightTool>(truthWeightToolName); + else { + m_PMGTruthWeights = new PMGTools::PMGTruthWeightTool(truthWeightToolName); + top::check(m_PMGTruthWeights->initialize(), "Failed to initialize " + truthWeightToolName); + } + //decoding arguments + std::istringstream stream(params); + std::string s; + while (stream >> s) { + if (s.substr(0, 3) == "WP:") m_WP = s.substr(3, s.size() - 3); + else if (s.substr(0, 7) == "tagger:") m_tagger = s.substr(7, s.size() - 7); + else if (s.substr(0, 8) == "CDIfile:") m_CDIfile = s.substr(8, s.size() - 8); + else if (s.substr(0, 3) == "pt:" || s.substr(0, 3) == "pT:") m_ptBins = s.substr(3, s.size() - 3); + else if (s.substr(0, 7) == "abseta:") m_etaBins = s.substr(7, s.size() - 7); + else if (s.substr(0, 7) == "max_pT:") m_max_pT = std::stof(s.substr(7, s.size() - 7)); + else if (s.substr(0, 7) == "min_pT:") m_min_pT = std::stof(s.substr(7, s.size() - 7)); + else if (s.substr(0, 5) == "N_pT:") m_N_pT_bins = std::stoi(s.substr(5, s.size() - 5)); + else if (s.substr(0, 8) == "max_eta:") m_max_Eta = std::stof(s.substr(8, s.size() - 8)); + else if (s.substr(0, 8) == "min_eta:") m_min_Eta = std::stof(s.substr(8, s.size() - 8)); + else if (s.substr(0, 6) == "N_eta:") m_N_Eta_bins = std::stoi(s.substr(6, s.size() - 6)); + else if (s.substr(0, 7) == "suffix:") m_histogram_suffix = s.substr(7, s.size() - 7); + else if (s == "fill_total_hist") m_fill_total_hists = true; + else if (s == "dont_use_event_weight") m_dont_use_event_weight = true; + else if (s == "use_track_jets") m_use_track_jets = true; + else if (s == "NOMINAL") m_doNominal = true; + else if (s == "MURUP") m_doMuRup = true; + else if (s == "MURDOWN") m_doMuRdown = true; + else if (s == "MUFUP") m_doMuFup = true; + else if (s == "MUFDOWN") m_doMuFdown = true; + else if (s == "VAR3CUP") m_doVar3cup = true; + else if (s == "VAR3CDOWN") m_doVar3cdown = true; + else if (s == "FSRUP") m_doFSRup = true; + else if (s == "FSRDOWN") m_doFSRdown = true; + else { + throw std::runtime_error { + "ERROR: Can't understand argument " + s + " for JETFTAGEFFPLOTS." + }; + } + } + + // retrieve jet collection + if (!m_use_track_jets) { + m_jetCollection = m_config->sgKeyJets(); + } else { + m_jetCollection = m_config->sgKeyTrackJets(); + } + + m_sfRetriever = asg::ToolStore::get<ScaleFactorRetriever>("top::ScaleFactorRetriever"); + + // No option were set, run only nominal + if (!m_doNominal && !m_doMuRup && !m_doMuRdown && !m_doMuFup + && !m_doMuFdown && !m_doVar3cup && !m_doVar3cdown && !m_doFSRup && !m_doFSRdown) { + ATH_MSG_INFO("No variation has been set. Assuming nominal."); + m_doNominal = true; + } + + if (m_doNominal) m_hists = std::make_shared<PlotManager>(name + "/JetFtagEffPlots", outputFile, wk); + if (m_doMuRup) m_hists_muRup = std::make_shared<PlotManager>(name + "/JetFtagEffPlots_MuRup", outputFile, wk); + if (m_doMuRdown) m_hists_muRdown = std::make_shared<PlotManager>(name + "/JetFtagEffPlots_MuRdown", outputFile, wk); + + if (m_doMuFup) m_hists_muFup = std::make_shared<PlotManager>(name + "/JetFtagEffPlots_MuFup", outputFile, wk); + if (m_doMuFdown) m_hists_muFdown = std::make_shared<PlotManager>(name + "/JetFtagEffPlots_MuFdown", outputFile, wk); + + if (m_doVar3cup) m_hists_Var3cup = std::make_shared<PlotManager>(name + "/JetFtagEffPlots_Var3cup", outputFile, wk); + + if (m_doVar3cdown) m_hists_Var3cdown = std::make_shared<PlotManager>(name + "/JetFtagEffPlots_Var3cdown", outputFile, wk); + if (m_doFSRup) m_hists_FSRup = std::make_shared<PlotManager>(name + "/JetFtagEffPlots_FSRup", outputFile, wk); + if (m_doFSRup) m_hists_FSRdown = std::make_shared<PlotManager>(name + "/JetFtagEffPlots_FSRdown", outputFile, wk); + + //handle binning and book histograms + std::vector<double> ptBins; + std::vector<double> etaBins; + + if (m_N_pT_bins < 1) { + formatBinning(m_ptBins, ptBins); + formatBinning(m_etaBins, etaBins); + } + + for (std::string flavour:{"B", "C", "L", "T"}) { + if (m_fill_total_hists) { + std::string total_hist_name = flavour + "_total_" + m_jetCollection + m_histogram_suffix; + if (m_N_pT_bins < 1) { + if (m_hists) m_hists->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_muRup) m_hists_muRup->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_muRdown) m_hists_muRdown->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_muFup) m_hists_muFup->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_muFdown) m_hists_muFdown->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_Var3cup) m_hists_Var3cup->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_Var3cdown) m_hists_Var3cdown->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_FSRup) m_hists_FSRup->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_FSRdown) m_hists_FSRdown->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + } else { + if (m_hists) m_hists->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_muRup) m_hists_muRup->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_muRdown) m_hists_muRdown->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_muFup) m_hists_muFup->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_muFdown) m_hists_muFdown->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_Var3cup) m_hists_Var3cup->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_Var3cdown) m_hists_Var3cdown->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_FSRup) m_hists_FSRup->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_FSRdown) m_hists_FSRdown->addHist(total_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + } + } + + const std::string pass_hist_name = m_tagger + "_" + m_WP + "_" + m_jetCollection + "_" + flavour + "_pass" + m_histogram_suffix; + if (m_N_pT_bins < 1) { + if (m_hists) m_hists->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_muRup) m_hists_muRup->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_muRdown) m_hists_muRdown->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_muFup) m_hists_muFup->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_muFdown) m_hists_muFdown->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_Var3cup) m_hists_Var3cup->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_Var3cdown) m_hists_Var3cdown->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_FSRup) m_hists_FSRup->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + if (m_hists_FSRdown) m_hists_FSRdown->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + ptBins.size() - 1, ptBins.data(), etaBins.size() - 1, etaBins.data()); + } else { + if (m_hists) m_hists->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_muRup) m_hists_muRup->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_muRdown) m_hists_muRdown->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_muFup) m_hists_muFup->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_muFdown) m_hists_muFdown->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_Var3cup) m_hists_Var3cup->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_Var3cdown) m_hists_Var3cdown->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_FSRup) m_hists_FSRup->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + if (m_hists_FSRdown) m_hists_FSRdown->addHist(pass_hist_name, ";pT [GeV];|#eta^{jet}|;Events", + m_N_pT_bins, m_min_pT, m_max_pT, m_N_Eta_bins, m_min_Eta, m_max_Eta); + } + } + + m_selection_tool = asg::AnaToolHandle<IBTaggingSelectionTool>("BTaggingSelectionTool/BTagSelec_" + m_tagger + "_" + m_WP + "_" + m_jetCollection); + top::check(m_selection_tool.setProperty("FlvTagCutDefinitionsFileName", m_CDIfile), "failed to initialize BtagSelectionTool " + m_tagger + "_" + m_WP + "_" + m_jetCollection); + top::check(m_selection_tool.setProperty("TaggerName", m_tagger), "failed to initialize BtagSelectionTool " + m_tagger + "_" + m_WP + "_" + m_jetCollection); + top::check(m_selection_tool.setProperty("OperatingPoint", m_WP), "failed to initialize BtagSelectionTool " + m_tagger + "_" + m_WP + "_" + m_jetCollection); + top::check(m_selection_tool.setProperty("JetAuthor", m_jetCollection), "failed to initialize BtagSelectionTool " + m_tagger + "_" + m_WP + "_" + m_jetCollection); + top::check(m_selection_tool.setProperty("MinPt", m_min_pT*1e3), "failed to initialize BtagSelectionTool, failed in min jet pT"); + top::check(m_selection_tool.setProperty("MaxEta", m_max_Eta), "failed to initialize BtagSelectionTool, failed in max jet eta"); + + top::check(m_selection_tool.initialize(), "failed to initialize BtagSelectionTool " + m_tagger + "_" + m_WP + "_" + m_jetCollection); + } + + bool JetFtagEffPlots::apply(const top::Event& event) const { + //only MC + if (!top::isSimulation(event)) return true; + + // only nominal + if (event.m_hashValue != m_nominalHashValue) return true; + + // do loose or tight events only if requested + if (event.m_isLoose && !m_config->doLooseEvents()) return true; + + if (!event.m_isLoose && !m_config->doTightEvents()) return true; + + float eventWeightNominal = 1.0; + float eventWeightMuRup = 1.0; + float eventWeightMuRdown = 1.0; + float eventWeightMuFup = 1.0; + float eventWeightMuFdown = 1.0; + float eventWeightVar3cUp = 1.0; + float eventWeightVar3cDown = 1.0; + float eventWeightFSRUp = 1.0; + float eventWeightFSRDown = 1.0; + float muRup = GetPMGTruthWeight(WEIGHTTYPE::MURUP); + float muRdown = GetPMGTruthWeight(WEIGHTTYPE::MURDOWN); + float muFup = GetPMGTruthWeight(WEIGHTTYPE::MUFUP); + float muFdown = GetPMGTruthWeight(WEIGHTTYPE::MUFDOWN); + float Var3cUp = GetPMGTruthWeight(WEIGHTTYPE::VAR3CUP); + float Var3cDown = GetPMGTruthWeight(WEIGHTTYPE::VAR3CDOWN); + float FSRUp = GetPMGTruthWeight(WEIGHTTYPE::FSRUP); + float FSRDown = GetPMGTruthWeight(WEIGHTTYPE::FSRDOWN); + + float jvt_sf = event.m_jvtSF; + float pu_weight = 1.0; + if (top::ScaleFactorRetriever::hasPileupSF(event)) { + pu_weight = top::ScaleFactorRetriever::pileupSF(event); + } + float lepton_sf = m_sfRetriever->leptonSF(event, nominal); + + if (m_doNominal) { + eventWeightNominal = event.m_info->auxdataConst<float>("AnalysisTop_eventWeight") * jvt_sf * pu_weight * lepton_sf; + } + if (m_doMuRup) eventWeightMuRup = muRup * jvt_sf * pu_weight * lepton_sf; + if (m_doMuRdown) eventWeightMuRdown = muRdown * jvt_sf * pu_weight * lepton_sf; + if (m_doMuFup) eventWeightMuFup = muFup * jvt_sf * pu_weight * lepton_sf; + if (m_doMuFdown) eventWeightMuFdown = muFdown * jvt_sf * pu_weight * lepton_sf; + if (m_doVar3cup) eventWeightVar3cUp = Var3cUp * jvt_sf * pu_weight * lepton_sf; + if (m_doVar3cdown) eventWeightVar3cDown = Var3cDown * jvt_sf * pu_weight * lepton_sf; + if (m_doFSRup) eventWeightFSRUp = FSRUp * jvt_sf * pu_weight * lepton_sf; + if (m_doFSRdown) eventWeightFSRDown = FSRDown * jvt_sf * pu_weight * lepton_sf; + + if (m_dont_use_event_weight) { + eventWeightNominal = 1.0; + } + + if (m_hists) FillHistograms(m_hists, eventWeightNominal, event); + if (m_hists_muRup) FillHistograms(m_hists_muRup, eventWeightMuRup, event); + if (m_hists_muRdown) FillHistograms(m_hists_muRdown, eventWeightMuRdown, event); + if (m_hists_muFup) FillHistograms(m_hists_muFup, eventWeightMuFup, event); + if (m_hists_muFdown) FillHistograms(m_hists_muFdown, eventWeightMuFdown, event); + if (m_hists_Var3cup) FillHistograms(m_hists_Var3cup, eventWeightVar3cUp, event); + if (m_hists_Var3cdown) FillHistograms(m_hists_Var3cdown, eventWeightVar3cDown, event); + if (m_hists_FSRup) FillHistograms(m_hists_FSRup, eventWeightFSRUp, event); + if (m_hists_FSRdown) FillHistograms(m_hists_FSRdown, eventWeightFSRDown, event); + + return true; + } + + void JetFtagEffPlots::FillHistograms(std::shared_ptr<PlotManager> h_ptr, double w_event, const top::Event& event) const { + const xAOD::JetContainer* jets; + + if (!m_use_track_jets) { + jets = &event.m_jets; + } else { + jets = &event.m_trackJets; + } + + for (unsigned long jet_i = 0; jet_i < jets->size(); jet_i++) { + const xAOD::Jet* jetPtr = jets->at(jet_i); + + int jet_flavor = -99; + bool status = jetPtr->getAttribute<int>("HadronConeExclTruthLabelID", jet_flavor); + + if (!status) continue; + + std::string flav_name; + + if (jet_flavor == 5) flav_name = "B"; + + else if (jet_flavor == 4) flav_name = "C"; + + else if (jet_flavor == 0) flav_name = "L"; + + else if (jet_flavor == 15) flav_name = "T"; + + if (m_fill_total_hists) { + static_cast<TH2D*>(h_ptr->hist(flav_name + "_total_" + m_jetCollection + m_histogram_suffix))->Fill(jetPtr->pt() * toGeV, fabs(jetPtr->eta()), w_event); + } + + bool pass_cut = static_cast<bool>(m_selection_tool->accept(jetPtr)); + + if (pass_cut) { + std::string hist_name = m_tagger + "_" + m_WP + "_" + m_jetCollection + "_" + flav_name + "_pass" + m_histogram_suffix; + static_cast<TH2D*>(h_ptr->hist(hist_name))->Fill(jetPtr->pt() * toGeV, fabs(jetPtr->eta()), w_event); + } + } + } + +// function to translate the binnings into vector of bin edges + void JetFtagEffPlots::formatBinning(const std::string& str, std::vector<double>& binEdges) { + std::stringstream ss(str); + std::string tok; + char separator = ':'; + while (std::getline(ss, tok, separator)) { + binEdges.push_back(std::atof(tok.c_str())); + } + } + + float JetFtagEffPlots::GetPMGTruthWeight(WEIGHTTYPE type) const { + float result = 1; + + if (type == WEIGHTTYPE::MURUP) { + if (m_PMGTruthWeights->hasWeight(" muR = 2.0, muF = 1.0 ")) result = m_PMGTruthWeights->getWeight(" muR = 2.0, muF = 1.0 "); + else if (m_PMGTruthWeights->hasWeight(" muR = 2.00, muF = 1.00 ")) result = m_PMGTruthWeights->getWeight(" muR = 2.00, muF = 1.00 "); + } else if (type == WEIGHTTYPE::MURDOWN) { + if (m_PMGTruthWeights->hasWeight(" muR = 0.5, muF = 1.0 ")) result = m_PMGTruthWeights->getWeight(" muR = 0.5, muF = 1.0 "); + else if (m_PMGTruthWeights->hasWeight(" muR = 0.50, muF = 1.00 ")) result = m_PMGTruthWeights->getWeight(" muR = 0.50, muF = 1.00 "); + } else if (type == WEIGHTTYPE::MUFUP) { + if (m_PMGTruthWeights->hasWeight(" muR = 1.0, muF = 2.0 ")) result = m_PMGTruthWeights->getWeight(" muR = 1.0, muF = 2.0 "); + else if (m_PMGTruthWeights->hasWeight(" muR = 1.00, muF = 2.00 ")) result = m_PMGTruthWeights->getWeight(" muR = 1.00, muF = 2.00 "); + } else if (type == WEIGHTTYPE::MUFDOWN) { + if (m_PMGTruthWeights->hasWeight(" muR = 1.0, muF = 0.5 ")) result = m_PMGTruthWeights->getWeight(" muR = 1.0, muF = 0.5 "); + else if (m_PMGTruthWeights->hasWeight(" muR = 1.00, muF = 0.50 ")) result = m_PMGTruthWeights->getWeight(" muR = 1.00, muF = 0.50 "); + } else if (type == WEIGHTTYPE::VAR3CUP) { + if (m_PMGTruthWeights->hasWeight("Var3cUp")) result = m_PMGTruthWeights->getWeight("Var3cUp"); + } else if (type == WEIGHTTYPE::VAR3CDOWN) { + if (m_PMGTruthWeights->hasWeight("Var3cDown")) result = m_PMGTruthWeights->getWeight("Var3cDown"); + } else if (type == WEIGHTTYPE::FSRUP) { + if (m_PMGTruthWeights->hasWeight("isr:muRfac=1.0_fsr:muRfac=2.0")) result = m_PMGTruthWeights->getWeight("isr:muRfac=1.0_fsr:muRfac=2.0"); + else if (m_PMGTruthWeights->hasWeight("isr:muRfac=1.00_fsr:muRfac=2.00")) result = m_PMGTruthWeights->getWeight("isr:muRfac=1.00_fsr:muRfac=2.00"); + } else if (type == WEIGHTTYPE::FSRDOWN) { + if (m_PMGTruthWeights->hasWeight("isr:muRfac=1.0_fsr:muRfac=0.5")) result = m_PMGTruthWeights->getWeight("isr:muRfac=1.0_fsr:muRfac=0.5"); + else if (m_PMGTruthWeights->hasWeight("isr:muRfac=1.00_fsr:muRfac=0.50")) result = m_PMGTruthWeights->getWeight("isr:muRfac=1.00_fsr:muRfac=0.50"); + } + + return result; + } + + std::string JetFtagEffPlots::name() const { + return "JETFTAGEFFPLOTS"; + } +} // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetNGhostSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetNGhostSelector.cxx index 85124b4b7b93..decfdfbbb4e0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetNGhostSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetNGhostSelector.cxx @@ -1,87 +1,136 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Filename: JetNGhostSelector.cxx -// Description: -// Author: Fabian Wilk -// Created: Fri May 8 15:39:38 2015 + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/JetNGhostSelector.h" namespace top { + JetNGhostSelector::JetNGhostSelector(const std::string& params) + : SignValueSelector("", parseType(params)) { + switch (m_type) { + case c: m_name = "JET_N_GHOST c" + SignValueSelector::name(); + break; + + case C: m_name = "JET_N_GHOST C" + SignValueSelector::name(); + break; + + case b: m_name = "JET_N_GHOST b" + SignValueSelector::name(); + break; + + case B: m_name = "JET_N_GHOST B" + SignValueSelector::name(); + break; + + case t: m_name = "JET_N_GHOST t" + SignValueSelector::name(); + break; + + case W: m_name = "JET_N_GHOST W" + SignValueSelector::name(); + break; - JetNGhostSelector::JetNGhostSelector(const std::string& params) - : SignValueSelector( "", parseType( params ) ){ - switch ( m_type ){ - case c: m_name = "JET_N_GHOST c" + SignValueSelector::name(); break; - case C: m_name = "JET_N_GHOST C" + SignValueSelector::name(); break; - case b: m_name = "JET_N_GHOST b" + SignValueSelector::name(); break; - case B: m_name = "JET_N_GHOST B" + SignValueSelector::name(); break; - case t: m_name = "JET_N_GHOST t" + SignValueSelector::name(); break; - case W: m_name = "JET_N_GHOST W" + SignValueSelector::name(); break; - case Z: m_name = "JET_N_GHOST Z" + SignValueSelector::name(); break; - case H: m_name = "JET_N_GHOST H" + SignValueSelector::name(); break; - case tau: m_name = "JET_N_GHOST tau" + SignValueSelector::name(); break; - case Invalid: m_name = "JET_N_GHOST !!! INVALID !!"; break; - } - checkMultiplicityIsInteger(); + case Z: m_name = "JET_N_GHOST Z" + SignValueSelector::name(); + break; + + case H: m_name = "JET_N_GHOST H" + SignValueSelector::name(); + break; + + case tau: m_name = "JET_N_GHOST tau" + SignValueSelector::name(); + break; + + case Invalid: m_name = "JET_N_GHOST !!! INVALID !!"; + break; } + checkMultiplicityIsInteger(); + } + + std::string JetNGhostSelector::parseType(const std::string& params) { + // Initialise the type variable + m_type = Invalid; + // Skip leading whitespace + std::size_t pos { + 0 + }; + while (pos < params.length() - 1 && std::isspace(params[pos])) { + ++pos; + } + + // list of allowed chars + static const std::vector<char> allowedChar = { + 'c', 'C', 'b', 'B', 't', 'W', 'Z', 'H' + }; - std::string JetNGhostSelector::parseType( const std::string & params ){ - // Initialise the type variable - m_type = Invalid; - // Skip leading whitespace - std::size_t pos{ 0 }; - while ( pos < params.length() - 1 && std::isspace( params[pos] ) ) { ++pos; } - - // Check, Use a switch statement hoping that the compiler may use this - // as a hint to optimise this bit using a jump table. - switch ( params[pos] ){ - // The easy cases - case 'c': case 'C': case 'b': case 'B': case 't': case 'W': case 'Z': case 'H': { - if ( pos + 1 < params.length() && std::isspace( params[ pos + 1 ] ) ){ - m_type = static_cast<Type>( params[ pos ] ); - return params.substr( pos + 2 ); - } else if ( params.compare( pos, 4, "tau " ) == 0 ){ - m_type = tau; - return params.substr( pos + 4 ); - } - } - default: { - std::cout << "Could not parse the type from the parameter string\n"; - std::cout << " '" << params << "'\n"; - std::exit(1); - } - } + // check if the char is allowed + if (std::find(allowedChar.begin(), allowedChar.end(), params[pos]) == allowedChar.end()) { + throw std::invalid_argument { + "Cannot parse the type from the parameter string" + }; } - bool JetNGhostSelector::applyParticleLevel(const top::ParticleLevelEvent& plEvent) const { - // If any of the required collections is a nullptr (i.e. has not been - // loaded) return false. - if ( not plEvent.m_jets ){ - return false; - } - - auto func = [&](const xAOD::Jet* truJetPtr) -> bool { - switch ( m_type ){ - case c: { return truJetPtr->auxdata<int>( "GhostCQuarksFinalCount" ); } - case C: { return truJetPtr->auxdata<int>( "GhostCHadronsFinalCount" ); } - case b: { return truJetPtr->auxdata<int>( "GhostBQuarksFinalCount" ); } - case B: { return truJetPtr->auxdata<int>( "GhostBHadronsFinalCount" ); } - case t: { return truJetPtr->auxdata<int>( "GhostTQuarksFinalCount" ); } - case W: { return truJetPtr->auxdata<int>( "GhostWBosonsCount" ); } - case Z: { return truJetPtr->auxdata<int>( "GhostZBosonsCount" ); } - case H: { return truJetPtr->auxdata<int>( "GhostHBosonsCount" ); } - case tau: { return truJetPtr->auxdata<int>( "GhostTausFinalCount" ); } - default: /* No-Op */ return 0; - } - }; - auto count = std::count_if(plEvent.m_jets->begin(), plEvent.m_jets->end(), func); - return checkInt(count, value()); + // process the char + if (pos + 1 < params.length() && std::isspace(params[ pos + 1 ])) { + m_type = static_cast<Type>(params[ pos ]); + return params.substr(pos + 2); + } else if (params.compare(pos, 4, "tau ") == 0) { + m_type = tau; + return params.substr(pos + 4); + } else { + throw std::invalid_argument { + "Cannot parse the type from the parameter string for the common configuration" + }; } + } - std::string JetNGhostSelector::name() const { - return m_name; + bool JetNGhostSelector::applyParticleLevel(const top::ParticleLevelEvent& plEvent) const { + // If any of the required collections is a nullptr (i.e. has not been + // loaded) return false. + if (!plEvent.m_jets) { + return false; } + + auto func = [&](const xAOD::Jet* truJetPtr) -> bool { + switch (m_type) { + case c: { + return truJetPtr->auxdata<int>("GhostCQuarksFinalCount"); + } + + case C: { + return truJetPtr->auxdata<int>("GhostCHadronsFinalCount"); + } + + case b: { + return truJetPtr->auxdata<int>("GhostBQuarksFinalCount"); + } + + case B: { + return truJetPtr->auxdata<int>("GhostBHadronsFinalCount"); + } + + case t: { + return truJetPtr->auxdata<int>("GhostTQuarksFinalCount"); + } + + case W: { + return truJetPtr->auxdata<int>("GhostWBosonsCount"); + } + + case Z: { + return truJetPtr->auxdata<int>("GhostZBosonsCount"); + } + + case H: { + return truJetPtr->auxdata<int>("GhostHBosonsCount"); + } + + case tau: { + return truJetPtr->auxdata<int>("GhostTausFinalCount"); + } + + default: /* No-Op */ return 0; + } + }; + auto count = std::count_if(plEvent.m_jets->begin(), plEvent.m_jets->end(), func); + return checkInt(count, value()); + } + + std::string JetNGhostSelector::name() const { + return m_name; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetResponsePlots.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetResponsePlots.cxx new file mode 100644 index 000000000000..7a93fd4c263b --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/JetResponsePlots.cxx @@ -0,0 +1,152 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/JetResponsePlots.h" + +#include "AsgTools/AsgTool.h" +#include "TopEvent/Event.h" +#include "TopEvent/EventTools.h" +#include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/Tokenize.h" +#include "TopCorrections/ScaleFactorRetriever.h" +#include "PATInterfaces/SystematicSet.h" +#include "xAODJet/JetContainer.h" +#include "PMGTools/PMGTruthWeightTool.h" + +#include "TH1.h" +#include "TH2D.h" +#include "TFile.h" + +//using namespace TopEventSelectionTools; +namespace top { + + JetResponsePlots::JetResponsePlots(const std::string& name, + TFile* outputFile, + const std::string& params, + std::shared_ptr<top::TopConfig> config, + EL::Worker* wk) : + m_nominalHashValue(0), + m_deltaR(0.3), + m_bins(30), + m_min(-3), + m_max(3), + m_config(config), + m_PMGTruthWeights(nullptr) { + + CP::SystematicSet nominal; + m_nominalHashValue = nominal.hash(); + + //retrieve PMGTruthWeights + static const std::string truthWeightToolName = "PMGTruthWeightTool"; + if (asg::ToolStore::contains<PMGTools::IPMGTruthWeightTool>(truthWeightToolName)) m_PMGTruthWeights = + asg::ToolStore::get<PMGTools::IPMGTruthWeightTool>(truthWeightToolName); + else { + std::unique_ptr<PMGTools::PMGTruthWeightTool> pmgtruthtool = std::make_unique<PMGTools::PMGTruthWeightTool>(truthWeightToolName); + top::check(pmgtruthtool->initialize(), "Failed to initialize " + truthWeightToolName); + m_PMGTruthWeights = pmgtruthtool.release(); + } + //decoding arguments + std::istringstream stream(params); + std::string s; + while (stream >> s) { + if (s.substr(0,7) == "deltaR:") { + m_deltaR = std::stof(s.substr(7, s.size() - 7)); + m_config->setJetResponseMatchingDeltaR(m_deltaR); + } else if (s.substr(0,5) == "bins:") { + m_bins = std::stoi(s.substr(5, s.size() - 5)); + } else if (s.substr(0,4) == "min:") { + m_min = std::stof(s.substr(4, s.size() - 4)); + } else if (s.substr(0,4) == "max:") { + m_max = std::stof(s.substr(4, s.size() - 4)); + } else if (s.substr(0,10) == "ptBinning:") { + const std::string tmp = s.substr(10, s.size() - 4); + // split by the delimiter + std::vector<std::string> split; + tokenize(tmp, split, ","); + for (const std::string& istring : split) { + m_ptBinning.emplace_back(std::stof(istring)); + } + } else { + throw std::runtime_error{"ERROR: Can't understand argument " + s + "For JETRESPONSEPLOTS"}; + } + } + + if (m_ptBinning.size() < 2) { + throw std::invalid_argument{"pT binning (x axis) size is smaller than 2"}; + } + + m_hists = std::make_shared<PlotManager>(name + "/JetResponsePlots", outputFile, wk); + m_hists->addHist("JetResponse", ";p_{T}^{truth} [GeV];p_{T}^{reco}/p_{T}^{truth};Events", m_ptBinning.size() - 1, m_ptBinning.data(), m_bins, m_min, m_max); + m_hists->addHist("JetResponse_bb", ";p_{T}^{truth} [GeV];p_{T}^{reco}/p_{T}^{truth};Events", m_ptBinning.size() - 1, m_ptBinning.data(), m_bins, m_min, m_max); + m_hists->addHist("JetResponse_b", ";p_{T}^{truth} [GeV];p_{T}^{reco}/p_{T}^{truth};Events", m_ptBinning.size() - 1, m_ptBinning.data(), m_bins, m_min, m_max); + m_hists->addHist("JetResponse_c", ";p_{T}^{truth} [GeV];p_{T}^{reco}/p_{T}^{truth};Events", m_ptBinning.size() - 1, m_ptBinning.data(), m_bins, m_min, m_max); + m_hists->addHist("JetResponse_tau", ";p_{T}^{truth} [GeV];p_{T}^{reco}/p_{T}^{truth};Events", m_ptBinning.size() - 1, m_ptBinning.data(), m_bins, m_min, m_max); + m_hists->addHist("JetResponse_q", ";p_{T}^{truth} [GeV];p_{T}^{reco}/p_{T}^{truth};Events", m_ptBinning.size() - 1, m_ptBinning.data(), m_bins, m_min, m_max); + m_hists->addHist("JetResponse_g", ";p_{T}^{truth} [GeV];p_{T}^{reco}/p_{T}^{truth};Events", m_ptBinning.size() - 1, m_ptBinning.data(), m_bins, m_min, m_max); + m_hists->addHist("JetResponse_other",";p_{T}^{truth} [GeV];p_{T}^{reco}/p_{T}^{truth};Events", m_ptBinning.size() - 1, m_ptBinning.data(), m_bins, m_min, m_max); + } + + bool JetResponsePlots::apply(const top::Event& event) const { + //only MC + if (!top::isSimulation(event)) return true; + + // only nominal + if (event.m_hashValue != m_nominalHashValue) return true; + + // do loose or tight events only if requested + if (event.m_isLoose && !m_config->doLooseEvents()) return true; + + if (!event.m_isLoose && !m_config->doTightEvents()) return true; + + const double nominalWeight = event.m_info->auxdata<float>("AnalysisTop_eventWeight"); + + FillHistograms(nominalWeight, event); + + return true; + } + + void JetResponsePlots::FillHistograms(const double w_event, + const top::Event& event) const { + + for (const auto* const jetPtr : event.m_jets) { + int jet_flavor = -99; + bool status = jetPtr->getAttribute<int>("HadronConeExclExtendedTruthLabelID", jet_flavor); + if (!status) continue; + + float matchedPt = -9999; + status = jetPtr->getAttribute<float>("AnalysisTop_MatchedTruthJetPt", matchedPt); + if (!status) continue; + + // protection against division by zero + if (matchedPt < 1e-6) continue; + + const float response = jetPtr->pt() / matchedPt; + + static_cast<TH2D*>(m_hists->hist("JetResponse"))->Fill(matchedPt/1e3, response, w_event); + if (jet_flavor == 55) { + static_cast<TH2D*>(m_hists->hist("JetResponse_bb"))->Fill(matchedPt/1e3, response, w_event); + } else if (jet_flavor == 5 || jet_flavor == 54) { + static_cast<TH2D*>(m_hists->hist("JetResponse_b"))->Fill(matchedPt/1e3, response, w_event); + } else if (jet_flavor == 4 || jet_flavor == 44) { + static_cast<TH2D*>(m_hists->hist("JetResponse_c"))->Fill(matchedPt/1e3, response, w_event); + } else if (jet_flavor == 15) { + static_cast<TH2D*>(m_hists->hist("JetResponse_tau"))->Fill(matchedPt/1e3, response, w_event); + } else { + status = jetPtr->getAttribute<int>("PartonTruthLabelID", jet_flavor); + if (!status) continue; + if (jet_flavor >= 1 && jet_flavor <= 3) { + static_cast<TH2D*>(m_hists->hist("JetResponse_q"))->Fill(matchedPt/1e3, response, w_event); + } else if (jet_flavor == 21) { + static_cast<TH2D*>(m_hists->hist("JetResponse_g"))->Fill(matchedPt/1e3, response, w_event); + } else { + static_cast<TH2D*>(m_hists->hist("JetResponse_other"))->Fill(matchedPt/1e3, response, w_event); + } + } + } + } + + std::string JetResponsePlots::name() const { + return "JETRESPONSEPLOTS"; + } +} // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/KLFitterSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/KLFitterSelector.cxx index 793304c8da59..57f8eddaaa6f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/KLFitterSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/KLFitterSelector.cxx @@ -1,41 +1,36 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: KLFitterSelector.cxx 666816 2015-05-13 10:59:36Z morrisj $ #include "TopEventSelectionTools/KLFitterSelector.h" #include "TopEvent/Event.h" #include "TopEvent/KLFitterResult.h" -namespace top{ - +namespace top { KLFitterSelector::KLFitterSelector(const std::string& params) : - SignValueSelector("KLFitter", params) - { + SignValueSelector("KLFitter", params) { } - - bool KLFitterSelector::apply(const top::Event& event) const - { + + bool KLFitterSelector::apply(const top::Event& event) const { // check we have a xAOD::KLFitterResultContainer if (event.m_KLFitterResults == nullptr) { return false; } - + for (auto result : *event.m_KLFitterResults) { // check for errors if ( - result->minuitDidNotConverge() == 0 && - result->fitAbortedDueToNaN() == 0 && + result->minuitDidNotConverge() == 0 && + result->fitAbortedDueToNaN() == 0 && result->atLeastOneFitParameterAtItsLimit() == 0 && - result->invalidTransferFunctionAtConvergence() == 0 - ) - { - bool passPermutation = checkFloat( result->logLikelihood() , value() ); + result->invalidTransferFunctionAtConvergence() == 0 + ) { + bool passPermutation = checkFloat(result->logLikelihood(), value()); if (passPermutation) { return true; } } // check for errors - } // Loop over Permutations - if we get this far, all Permutations have failed :( return false; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/LinkDef.h index 64fef85f1b05..121ac665fe0b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/LinkDef.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/LinkDef.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/ToolLoaderBase.h" #include "TopEventSelectionTools/TopEventSelectionToolsLoader.h" diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/METMWTSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/METMWTSelector.cxx index cc2a2ccc0f28..81c442d65c9b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/METMWTSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/METMWTSelector.cxx @@ -1,53 +1,45 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/METMWTSelector.h" #include "TopEvent/EventTools.h" namespace top { + METMWTSelector::METMWTSelector(const std::string& params) : + SignValueSelector("MET+MWT", params) { + } -METMWTSelector::METMWTSelector(const std::string& params) : - SignValueSelector("MET+MWT", params) { -} - -bool METMWTSelector::apply(const top::Event& event) const { + bool METMWTSelector::apply(const top::Event& event) const { const xAOD::IParticle* lepton = 0; - if (!event.m_electrons.empty()) - lepton = event.m_electrons.front(); - else if (!event.m_muons.empty()) - lepton = event.m_muons.front(); + + if (!event.m_electrons.empty()) lepton = event.m_electrons.front(); + else if (!event.m_muons.empty()) lepton = event.m_muons.front(); else { - std::cout << "MET+MWT Tool: Not got a charged lepton" << std::endl; - exit(1); + throw std::runtime_error("METMWTSelector::apply: No charged lepton in event"); } const double metmwt = event.m_met->met() + top::mwt(*lepton, *event.m_met); return checkFloat(metmwt, value()); -} + } -bool METMWTSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool METMWTSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons - or not event.m_met ){ - return false; + if (not event.m_electrons + or not event.m_muons + or not event.m_met) { + return false; } const xAOD::IParticle* lepton = 0; - if (!event.m_electrons->empty()) - lepton = event.m_electrons->front(); - else if (!event.m_muons->empty()) - lepton = event.m_muons->front(); + if (!event.m_electrons->empty()) lepton = event.m_electrons->front(); + else if (!event.m_muons->empty()) lepton = event.m_muons->front(); else { - std::cout << "MET+MWT Tool: Not got a charged lepton" << std::endl; - exit(1); + throw std::runtime_error("METMWTSelector::applyParticleLevel: No charged lepton in event"); } const double metmwt = event.m_met->met() + top::mwt(*lepton, *event.m_met); return checkFloat(metmwt, value()); -} - - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/METSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/METSelector.cxx index 6a4c86b13bcd..4d7ff924ba3d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/METSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/METSelector.cxx @@ -1,28 +1,26 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/METSelector.h" #include "TopEvent/EventTools.h" namespace top { + METSelector::METSelector(const std::string& params) : + SignValueSelector("MET", params) { + } -METSelector::METSelector(const std::string& params) : - SignValueSelector("MET", params) { -} - -bool METSelector::apply(const top::Event& event) const { + bool METSelector::apply(const top::Event& event) const { return checkFloat(event.m_met->met(), value()); -} + } -bool METSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool METSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_met ){ - return false; + if (not event.m_met) { + return false; } return checkFloat(event.m_met->met(), value()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MLLSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MLLSelector.cxx index e23207d4e08e..64dfa0988482 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MLLSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MLLSelector.cxx @@ -1,66 +1,61 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/MLLSelector.h" #include "TopEvent/EventTools.h" namespace top { + MLLSelector::MLLSelector(const std::string& params) : + SignValueSelector("MLL", params) { + } -MLLSelector::MLLSelector(const std::string& params) : - SignValueSelector("MLL", params) { -} - -bool MLLSelector::apply(const top::Event& event) const { + bool MLLSelector::apply(const top::Event& event) const { const xAOD::IParticle* lepton0 = 0; const xAOD::IParticle* lepton1 = 0; if (event.m_electrons.size() == 2) { - lepton0 = event.m_electrons[0]; - lepton1 = event.m_electrons[1]; + lepton0 = event.m_electrons[0]; + lepton1 = event.m_electrons[1]; } else if (event.m_muons.size() == 2) { - lepton0 = event.m_muons[0]; - lepton1 = event.m_muons[1]; + lepton0 = event.m_muons[0]; + lepton1 = event.m_muons[1]; } else if (event.m_electrons.size() == 1 && event.m_muons.size() == 1) { - lepton0 = event.m_electrons[0]; - lepton1 = event.m_muons[0]; + lepton0 = event.m_electrons[0]; + lepton1 = event.m_muons[0]; } else { - std::cout << "MLL: Need two charged leptons" << std::endl; - exit(1); + throw std::runtime_error("MLLSelector::apply: Need two charge leptons"); } const double mll = top::invariantMass(*lepton0, *lepton1); return checkFloat(mll, value()); -} + } - bool MLLSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { - // If any of the required collections is a nullptr (i.e. has not been + bool MLLSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons ){ - return false; + if (not event.m_electrons + or not event.m_muons) { + return false; } const xAOD::IParticle* lepton0 = 0; const xAOD::IParticle* lepton1 = 0; if (event.m_electrons->size() == 2) { - lepton0 = (*event.m_electrons)[0]; - lepton1 = (*event.m_electrons)[1]; + lepton0 = (*event.m_electrons)[0]; + lepton1 = (*event.m_electrons)[1]; } else if (event.m_muons->size() == 2) { - lepton0 = (*event.m_muons)[0]; - lepton1 = (*event.m_muons)[1]; + lepton0 = (*event.m_muons)[0]; + lepton1 = (*event.m_muons)[1]; } else if (event.m_electrons->size() == 1 && event.m_muons->size() == 1) { - lepton0 = (*event.m_electrons)[0]; - lepton1 = (*event.m_muons)[0]; + lepton0 = (*event.m_electrons)[0]; + lepton1 = (*event.m_muons)[0]; } else { - std::cout << "MLL: Need two charged leptons" << std::endl; - exit(1); + throw std::runtime_error("MLLSelector::applyParticleLevel: Need two charged leptons"); } const double mll = top::invariantMass(*lepton0, *lepton1); return checkFloat(mll, value()); -} - - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MLLWindowSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MLLWindowSelector.cxx index a23a581b098b..d196a7335d4b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MLLWindowSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MLLWindowSelector.cxx @@ -1,68 +1,63 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/MLLWindowSelector.h" #include "TopEvent/EventTools.h" namespace top { - -MLLWindow::MLLWindow(std::string params) : - m_cutvalue0(0.), - m_cutvalue1(0.) { + MLLWindow::MLLWindow(std::string params) : + m_cutvalue0(0.), + m_cutvalue1(0.) { std::istringstream(params) >> m_cutvalue0 >> m_cutvalue1; -} + } -bool MLLWindow::apply(const top::Event& event) const { + bool MLLWindow::apply(const top::Event& event) const { const xAOD::IParticle* lepton0 = 0; const xAOD::IParticle* lepton1 = 0; if (event.m_electrons.size() == 2) { - lepton0 = event.m_electrons[0]; - lepton1 = event.m_electrons[1]; + lepton0 = event.m_electrons[0]; + lepton1 = event.m_electrons[1]; } else if (event.m_muons.size() == 2) { - lepton0 = event.m_muons[0]; - lepton1 = event.m_muons[1]; + lepton0 = event.m_muons[0]; + lepton1 = event.m_muons[1]; } else { - std::cout << "need two charged leptons of the same flavour" << std::endl; - exit(1); + throw std::runtime_error("MLLWindowSelector::apply: Need two same-flavour electrons or muons"); } const double mll = top::invariantMass(*lepton0, *lepton1); return mll < m_cutvalue0 || mll > m_cutvalue1; -} - + } -bool MLLWindow::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool MLLWindow::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons ){ - return false; + if (not event.m_electrons + or not event.m_muons) { + return false; } const xAOD::IParticle* lepton0 = 0; const xAOD::IParticle* lepton1 = 0; if (event.m_electrons->size() == 2) { - lepton0 = (*event.m_electrons)[0]; - lepton1 = (*event.m_electrons)[1]; + lepton0 = (*event.m_electrons)[0]; + lepton1 = (*event.m_electrons)[1]; } else if (event.m_muons->size() == 2) { - lepton0 = (*event.m_muons)[0]; - lepton1 = (*event.m_muons)[1]; + lepton0 = (*event.m_muons)[0]; + lepton1 = (*event.m_muons)[1]; } else { - std::cout << "need two charged leptons of the same flavour" << std::endl; - exit(1); + throw std::runtime_error("MLLWindowSelector::applyParticleLevel: Need two same-flavour electrons or muons"); } const double mll = top::invariantMass(*lepton0, *lepton1); return mll < m_cutvalue0 || mll > m_cutvalue1; -} + } -std::string MLLWindow::name() const { + std::string MLLWindow::name() const { std::stringstream ss; ss << "MLLWIN " << m_cutvalue0 << " " << m_cutvalue1; return ss.str(); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c10Selector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c10Selector.cxx index e95e5cd5e203..0b5e94069e25 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c10Selector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c10Selector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/MV2c10Selector.h" #include "TopEvent/EventTools.h" @@ -8,24 +8,23 @@ #include <algorithm> namespace top { - -MV2c10Selector::MV2c10Selector(const std::string& params) : - SignValueSelector("MV2C10_N", params, true) { + MV2c10Selector::MV2c10Selector(const std::string& params) : + SignValueSelector("MV2C10_N", params, true) { checkMultiplicityIsInteger(); -} + } -bool MV2c10Selector::apply(const top::Event& event) const { + bool MV2c10Selector::apply(const top::Event& event) const { auto func = [&](const xAOD::Jet* const jetPtr) { - double mv2c10_discriminant = 0.; - const bool hasMv2c10 = jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); - if (hasMv2c10) - return mv2c10_discriminant > value(); + double mv2c10_discriminant = 0.; + const bool hasMv2c10 = jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); + + if (hasMv2c10) return mv2c10_discriminant > value(); - return false; - }; + return false; + }; auto count = std::count_if(event.m_jets.begin(), event.m_jets.end(), func); - return checkInt(count, multiplicity()); -} + return checkInt(count, multiplicity()); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MWTSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MWTSelector.cxx index ef7bb21c5e33..56c104ffe6cf 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MWTSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MWTSelector.cxx @@ -1,53 +1,45 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/MWTSelector.h" #include "TopEvent/EventTools.h" namespace top { + MWTSelector::MWTSelector(const std::string& params) : + SignValueSelector("MWT", params) { + } -MWTSelector::MWTSelector(const std::string& params) : - SignValueSelector("MWT", params) { -} - -bool MWTSelector::apply(const top::Event& event) const { + bool MWTSelector::apply(const top::Event& event) const { const xAOD::IParticle* lepton = 0; - if (!event.m_electrons.empty()) - lepton = event.m_electrons.front(); - else if (!event.m_muons.empty()) - lepton = event.m_muons.front(); + + if (!event.m_electrons.empty()) lepton = event.m_electrons.front(); + else if (!event.m_muons.empty()) lepton = event.m_muons.front(); else { - std::cout << "MWTSelector: Not got a charged lepton" << std::endl; - exit(1); + throw std::runtime_error("MWTSelector::apply: No charged lepton in event"); } const double mwt = top::mwt(*lepton, *event.m_met); return checkFloat(mwt, value()); -} + } -bool MWTSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool MWTSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons - or not event.m_met ){ - return false; + if (not event.m_electrons + or not event.m_muons + or not event.m_met) { + return false; } const xAOD::IParticle* lepton = 0; - if (!event.m_electrons->empty()) - lepton = event.m_electrons->front(); - else if (!event.m_muons->empty()) - lepton = event.m_muons->front(); + if (!event.m_electrons->empty()) lepton = event.m_electrons->front(); + else if (!event.m_muons->empty()) lepton = event.m_muons->front(); else { - std::cout << "MWTSelector: Not got a charged lepton" << std::endl; - exit(1); + throw std::runtime_error("MWTSelector::applyParticleLevel: No charged lepton in event"); } const double mwt = top::mwt(*lepton, *event.m_met); return checkFloat(mwt, value()); -} - - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MsgCategory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MsgCategory.cxx new file mode 100644 index 000000000000..543dd0707d10 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MsgCategory.cxx @@ -0,0 +1,6 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#include "TopEventSelectionTools/MsgCategory.h" + +ANA_MSG_SOURCE(TopEventSelectionTools, "TopEventSelectionTools") diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronNMuonSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronNMuonSelector.cxx index 2405da836f70..01217aebdf67 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronNMuonSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronNMuonSelector.cxx @@ -1,41 +1,47 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NElectronNMuonSelector.h" namespace top { - -NElectronNMuonSelector::NElectronNMuonSelector(const std::string& params) : - SignValueSelector("EL_N_OR_MU_N", params, true) { + NElectronNMuonSelector::NElectronNMuonSelector(const std::string& params) : + SignValueSelector("EL_N_OR_MU_N", params, true) { checkMultiplicityIsInteger(); -} + } -bool NElectronNMuonSelector::apply(const top::Event& event) const { - auto elFunc = [&](const xAOD::Electron* elPtr){return elPtr->pt() > value();}; + bool NElectronNMuonSelector::apply(const top::Event& event) const { + auto elFunc = [&](const xAOD::Electron* elPtr) { + return elPtr->pt() > value(); + }; auto elCount = std::count_if(event.m_electrons.begin(), event.m_electrons.end(), elFunc); - auto muFunc = [&](const xAOD::Muon* muPtr){return muPtr->pt() > value();}; + auto muFunc = [&](const xAOD::Muon* muPtr) { + return muPtr->pt() > value(); + }; auto muCount = std::count_if(event.m_muons.begin(), event.m_muons.end(), muFunc); return checkInt(elCount, multiplicity()) || checkInt(muCount, multiplicity()); -} + } -bool NElectronNMuonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool NElectronNMuonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons ){ - return false; + if (not event.m_electrons + or not event.m_muons) { + return false; } - auto elFunc = [&](const xAOD::TruthParticle* truElPtr){return truElPtr->pt() > value();}; + auto elFunc = [&](const xAOD::TruthParticle* truElPtr) { + return truElPtr->pt() > value(); + }; auto elCount = std::count_if(event.m_electrons->begin(), event.m_electrons->end(), elFunc); - auto muFunc = [&](const xAOD::TruthParticle* truMuPtr){return truMuPtr->pt() > value();}; + auto muFunc = [&](const xAOD::TruthParticle* truMuPtr) { + return truMuPtr->pt() > value(); + }; auto muCount = std::count_if(event.m_muons->begin(), event.m_muons->end(), muFunc); return checkInt(elCount, multiplicity()) || checkInt(muCount, multiplicity()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronNMuonTightSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronNMuonTightSelector.cxx index bac0a91f46bc..dfc8cd0b0a83 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronNMuonTightSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronNMuonTightSelector.cxx @@ -1,41 +1,47 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NElectronNMuonTightSelector.h" namespace top { - -NElectronNMuonTightSelector::NElectronNMuonTightSelector(const std::string& params) : - SignValueSelector("EL_N_OR_MU_N_TIGHT", params, true) { + NElectronNMuonTightSelector::NElectronNMuonTightSelector(const std::string& params) : + SignValueSelector("EL_N_OR_MU_N_TIGHT", params, true) { checkMultiplicityIsInteger(); -} + } -bool NElectronNMuonTightSelector::apply(const top::Event& event) const { - auto elFunc = [&](const xAOD::Electron* elPtr){return elPtr->pt() > value() && elPtr->auxdataConst<char>("passPreORSelection");}; + bool NElectronNMuonTightSelector::apply(const top::Event& event) const { + auto elFunc = [&](const xAOD::Electron* elPtr) { + return elPtr->pt() > value() && elPtr->auxdataConst<char>("passPreORSelection"); + }; auto elCount = std::count_if(event.m_electrons.begin(), event.m_electrons.end(), elFunc); - auto muFunc = [&](const xAOD::Muon* muPtr){return muPtr->pt() > value() && muPtr->auxdataConst<char>("passPreORSelection");}; + auto muFunc = [&](const xAOD::Muon* muPtr) { + return muPtr->pt() > value() && muPtr->auxdataConst<char>("passPreORSelection"); + }; auto muCount = std::count_if(event.m_muons.begin(), event.m_muons.end(), muFunc); return checkInt(elCount, multiplicity()) || checkInt(muCount, multiplicity()); -} + } -bool NElectronNMuonTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool NElectronNMuonTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons ){ - return false; + if (not event.m_electrons + or not event.m_muons) { + return false; } - auto elFunc = [&](const xAOD::TruthParticle* truElPtr){return truElPtr->pt() > value();}; + auto elFunc = [&](const xAOD::TruthParticle* truElPtr) { + return truElPtr->pt() > value(); + }; auto elCount = std::count_if(event.m_electrons->begin(), event.m_electrons->end(), elFunc); - auto muFunc = [&](const xAOD::TruthParticle* truMuPtr){return truMuPtr->pt() > value();}; + auto muFunc = [&](const xAOD::TruthParticle* truMuPtr) { + return truMuPtr->pt() > value(); + }; auto muCount = std::count_if(event.m_muons->begin(), event.m_muons->end(), muFunc); return checkInt(elCount, multiplicity()) || checkInt(muCount, multiplicity()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronSelector.cxx index e66390ed0463..bc293da76354 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronSelector.cxx @@ -1,34 +1,37 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NElectronSelector.h" #include <algorithm> namespace top { - -NElectronSelector::NElectronSelector(const std::string& params) : - SignValueSelector("EL_N", params, true) { + NElectronSelector::NElectronSelector(const std::string& params) : + SignValueSelector("EL_N", params, true) { checkMultiplicityIsInteger(); -} + } -bool NElectronSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Electron* elPtr){return elPtr->pt() > value();}; + bool NElectronSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Electron* elPtr) { + return elPtr->pt() > value(); + }; auto count = std::count_if(event.m_electrons.begin(), event.m_electrons.end(), func); + return checkInt(count, multiplicity()); -} + } -bool NElectronSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool NElectronSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons ){ - return false; + if (!event.m_electrons) { + return false; } - auto func = [&](const xAOD::TruthParticle* truElPtr){return truElPtr->pt() > value();}; + auto func = [&](const xAOD::TruthParticle* truElPtr) { + return truElPtr->pt() > value(); + }; auto count = std::count_if(event.m_electrons->begin(), event.m_electrons->end(), func); return checkInt(count, multiplicity()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronTightSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronTightSelector.cxx index e7fb0357f64e..8dcba9f800f3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronTightSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NElectronTightSelector.cxx @@ -1,34 +1,37 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NElectronTightSelector.h" #include <algorithm> namespace top { - -NElectronTightSelector::NElectronTightSelector(const std::string& params) : - SignValueSelector("EL_N_TIGHT", params, true) { + NElectronTightSelector::NElectronTightSelector(const std::string& params) : + SignValueSelector("EL_N_TIGHT", params, true) { checkMultiplicityIsInteger(); -} + } -bool NElectronTightSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Electron* elPtr){return elPtr->pt() > value() && elPtr->auxdataConst<char>("passPreORSelection");}; + bool NElectronTightSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Electron* elPtr) { + return elPtr->pt() > value() && elPtr->auxdataConst<char>("passPreORSelection"); + }; auto count = std::count_if(event.m_electrons.begin(), event.m_electrons.end(), func); + return checkInt(count, multiplicity()); -} + } -bool NElectronTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool NElectronTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons ){ - return false; + if (not event.m_electrons) { + return false; } - auto func = [&](const xAOD::TruthParticle* truElPtr){return truElPtr->pt() > value();}; + auto func = [&](const xAOD::TruthParticle* truElPtr) { + return truElPtr->pt() > value(); + }; auto count = std::count_if(event.m_electrons->begin(), event.m_electrons->end(), func); return checkInt(count, multiplicity()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NFwdElectronSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NFwdElectronSelector.cxx new file mode 100644 index 000000000000..7849d6abac0a --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NFwdElectronSelector.cxx @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/NFwdElectronSelector.h" +#include <algorithm> + +namespace top { + NFwdElectronSelector::NFwdElectronSelector(const std::string& params) : + SignValueSelector("FWDEL_N", params, true) { + checkMultiplicityIsInteger(); + } + + bool NFwdElectronSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Electron* elPtr) { + return elPtr->pt() > value(); + }; + auto count = std::count_if(event.m_fwdElectrons.begin(), event.m_fwdElectrons.end(), func); + + return checkInt(count, multiplicity()); + } + + bool NFwdElectronSelector::applyParticleLevel(const top::ParticleLevelEvent& /*event*/) const { + return true; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NFwdElectronTightSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NFwdElectronTightSelector.cxx new file mode 100644 index 000000000000..2b6b916db120 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NFwdElectronTightSelector.cxx @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/NFwdElectronTightSelector.h" +#include <algorithm> + +#include "TopEventSelectionTools/MsgCategory.h" +using namespace TopEventSelectionTools; + +namespace top { + NFwdElectronTightSelector::NFwdElectronTightSelector(const std::string& params) : + SignValueSelector("FWDEL_N_TIGHT", params, true) { + checkMultiplicityIsInteger(); + } + + bool NFwdElectronTightSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Electron* elPtr) { + return elPtr->pt() > value() && elPtr->auxdataConst<char>("passPreORSelection"); + }; + auto count = std::count_if(event.m_fwdElectrons.begin(), event.m_fwdElectrons.end(), func); + + return checkInt(count, multiplicity()); + } + + bool NFwdElectronTightSelector::applyParticleLevel(const top::ParticleLevelEvent& /*event*/) const { + ATH_MSG_INFO("NFwdElectronTightSelector::applyParticleLevel: " + << "no separate fwdElectrons container currently defined at particleLevel" + << "FWDEL_N_TIGHT always returning true at particle level."); + return true; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NJetBtagSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NJetBtagSelector.cxx index 0efc659d09a9..75b90fcd11b2 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NJetBtagSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NJetBtagSelector.cxx @@ -1,36 +1,52 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NJetBtagSelector.h" #include "TopConfiguration/TopConfig.h" -namespace top { +#include "TopEventSelectionTools/MsgCategory.h" +using namespace TopEventSelectionTools; -NJetBtagSelector::NJetBtagSelector(const std::string& params,std::shared_ptr<top::TopConfig> config) : - SignValueSelector("JET_N_BTAG", params, true, true) { +namespace top { + NJetBtagSelector::NJetBtagSelector(const std::string& params, std::shared_ptr<top::TopConfig> config, + bool doTrackJets) : + SignValueSelector((doTrackJets ? "TJET_N_BTAG" : "JET_N_BTAG"), params, true, true, ":", "_", "DL1r"), + m_doTrackJets(doTrackJets) { checkMultiplicityIsInteger(); - // check if the provided btag WP is really available - if (std::find(config->bTagWP_available().begin(), config->bTagWP_available().end(), valueString()) == config->bTagWP_available().end()) { - std::cout << "NJetBtagSelector is confused\n"; - std::cout << "B-tagging working point " << valueString() << " doesn't seem to be supported.\n"; - std::cout << "Please provide a real one! Did you specified it in the \"BTaggingWP\" field of your cutfile?\n"; - exit(1); + // check if the provided btag WP is really available - need to replace : with _ to match the naming of variables + bool bTagWP_exists = false; + if (m_doTrackJets) bTagWP_exists = + (std::find(config->bTagWP_available_trkJet().begin(), config->bTagWP_available_trkJet().end(), + valueStringDelimReplace()) != config->bTagWP_available_trkJet().end()); + else bTagWP_exists = + (std::find(config->bTagWP_available().begin(), config->bTagWP_available().end(), + valueStringDelimReplace()) != config->bTagWP_available().end()); + + if (!bTagWP_exists) { + ATH_MSG_ERROR("NJetBtagSelector is confused\n" + << "B-tagging working point " << valueString() << " doesn't seem to be supported.\n" + << "Please note that you should provide the argument as ==> bTagAlgorithm:bTagWP now. \n " + << "Please provide a real one! Did you specified it in the \"BTaggingWP\" field of your cutfile?\n"); + throw std::runtime_error("NJetBtagSelector: Invalid btagging selector WP: " + name()); } -} + } -bool NJetBtagSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Jet* jetPtr){ - if(!jetPtr->isAvailable<char>("isbtagged_"+valueString())) { - std::cout << "NJetBtagSelector is confused\n"; - std::cout << "A jet doesn't have the necessady decoration called \"isbtagged_"+valueString()+"\".\n"; - std::cout << "Exiting...\n"; - exit(1); - } - return jetPtr->auxdataConst<char>("isbtagged_"+valueString()); - }; - auto count = std::count_if(event.m_jets.begin(), event.m_jets.end(), func); - return checkInt(count, multiplicity()); -} + bool NJetBtagSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Jet* jetPtr) { + if (!jetPtr->isAvailable<char>("isbtagged_" + valueStringDelimReplace())) { + throw std::runtime_error("NJetBtagSelector: Jet doesn't have decoration \"isbtagged_" + + valueStringDelimReplace() + "\""); + } + return jetPtr->auxdataConst<char>("isbtagged_" + valueStringDelimReplace()); + }; + int count = 0; + if (m_doTrackJets) { + count = std::count_if(event.m_trackJets.begin(), event.m_trackJets.end(), func); + } else { + count = std::count_if(event.m_jets.begin(), event.m_jets.end(), func); + } + return checkInt(count, multiplicity()); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NJetSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NJetSelector.cxx index de9c8de7df84..d929173ae37e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NJetSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NJetSelector.cxx @@ -1,32 +1,35 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NJetSelector.h" namespace top { - -NJetSelector::NJetSelector(const std::string& params) : - SignValueSelector("JET_N", params, true) { + NJetSelector::NJetSelector(const std::string& params) : + SignValueSelector("JET_N", params, true) { checkMultiplicityIsInteger(); -} + } -bool NJetSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Jet* jetPtr){return jetPtr->pt() > value();}; + bool NJetSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Jet* jetPtr) { + return jetPtr->pt() > value(); + }; auto count = std::count_if(event.m_jets.begin(), event.m_jets.end(), func); + return checkInt(count, multiplicity()); -} + } -bool NJetSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool NJetSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_jets ){ - return false; + if (not event.m_jets) { + return false; } - auto func = [&](const xAOD::Jet* truJetPtr){return truJetPtr->pt() > value();}; + auto func = [&](const xAOD::Jet* truJetPtr) { + return truJetPtr->pt() > value(); + }; auto count = std::count_if(event.m_jets->begin(), event.m_jets->end(), func); return checkInt(count, multiplicity()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NLargeJetSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NLargeJetSelector.cxx index 8670c3b0966e..8340948ad1ed 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NLargeJetSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NLargeJetSelector.cxx @@ -1,26 +1,30 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NLargeJetSelector.h" -namespace top{ - +namespace top { NLargeJetSelector::NLargeJetSelector(const std::string& params) : SignValueSelector("LJET_N", params, true) { checkMultiplicityIsInteger(); } bool NLargeJetSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Jet* jetPtr){return jetPtr->pt() > value();}; + auto func = [&](const xAOD::Jet* jetPtr) { + return jetPtr->pt() > value(); + }; auto count = std::count_if(event.m_largeJets.begin(), event.m_largeJets.end(), func); + return checkInt(count, multiplicity()); } bool NLargeJetSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { - auto func = [&](const xAOD::Jet* jetPtr){return jetPtr->pt() > value();}; + auto func = [&](const xAOD::Jet* jetPtr) { + return jetPtr->pt() > value(); + }; auto count = std::count_if(event.m_largeRJets->begin(), event.m_largeRJets->end(), func); + return checkInt(count, multiplicity()); } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NMuonSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NMuonSelector.cxx index dc1e90ddbef9..97e9fc744847 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NMuonSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NMuonSelector.cxx @@ -1,34 +1,37 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NMuonSelector.h" #include <algorithm> namespace top { - -NMuonSelector::NMuonSelector(const std::string& params) : - SignValueSelector("MU_N", params, true) { + NMuonSelector::NMuonSelector(const std::string& params) : + SignValueSelector("MU_N", params, true) { checkMultiplicityIsInteger(); -} + } -bool NMuonSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Muon* muPtr){return muPtr->pt() > value();}; + bool NMuonSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Muon* muPtr) { + return muPtr->pt() > value(); + }; auto count = std::count_if(event.m_muons.begin(), event.m_muons.end(), func); + return checkInt(count, multiplicity()); -} + } -bool NMuonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool NMuonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_muons ){ - return false; + if (not event.m_muons) { + return false; } - auto func = [&](const xAOD::TruthParticle* truMuPtr){return truMuPtr->pt() > value();}; + auto func = [&](const xAOD::TruthParticle* truMuPtr) { + return truMuPtr->pt() > value(); + }; auto count = std::count_if(event.m_muons->begin(), event.m_muons->end(), func); return checkInt(count, multiplicity()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NMuonTightSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NMuonTightSelector.cxx index 5f55ef3eb5d0..8c910717bac4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NMuonTightSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NMuonTightSelector.cxx @@ -1,34 +1,37 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NMuonTightSelector.h" #include <algorithm> namespace top { - -NMuonTightSelector::NMuonTightSelector(const std::string& params) : - SignValueSelector("MU_N_TIGHT", params, true) { + NMuonTightSelector::NMuonTightSelector(const std::string& params) : + SignValueSelector("MU_N_TIGHT", params, true) { checkMultiplicityIsInteger(); -} + } -bool NMuonTightSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Muon* muPtr){return muPtr->pt() > value() && muPtr->auxdataConst<char>("passPreORSelection");}; + bool NMuonTightSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Muon* muPtr) { + return muPtr->pt() > value() && muPtr->auxdataConst<char>("passPreORSelection"); + }; auto count = std::count_if(event.m_muons.begin(), event.m_muons.end(), func); + return checkInt(count, multiplicity()); -} + } -bool NMuonTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool NMuonTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_muons ){ - return false; + if (not event.m_muons) { + return false; } - auto func = [&](const xAOD::TruthParticle* truMuPtr){return truMuPtr->pt() > value();}; + auto func = [&](const xAOD::TruthParticle* truMuPtr) { + return truMuPtr->pt() > value(); + }; auto count = std::count_if(event.m_muons->begin(), event.m_muons->end(), func); return checkInt(count, multiplicity()); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NPhotonSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NPhotonSelector.cxx index b7f017db57d5..c48904655cf8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NPhotonSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NPhotonSelector.cxx @@ -1,28 +1,32 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NPhotonSelector.h" #include <algorithm> namespace top { - -NPhotonSelector::NPhotonSelector(const std::string& params) : - SignValueSelector("PH_N", params, true) { + NPhotonSelector::NPhotonSelector(const std::string& params) : + SignValueSelector("PH_N", params, true) { checkMultiplicityIsInteger(); -} + } -bool NPhotonSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Photon* phPtr){return phPtr->pt() > value();}; + bool NPhotonSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Photon* phPtr) { + return phPtr->pt() > value(); + }; auto count = std::count_if(event.m_photons.begin(), event.m_photons.end(), func); + return checkInt(count, multiplicity()); -} + } -bool NPhotonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { - auto func = [&](const xAOD::TruthParticle* truPhPtr){return truPhPtr->pt() > value();}; - auto count = std::count_if(event.m_photons->begin(), event.m_photons->end(), func); - return checkInt(count, multiplicity()); -} + bool NPhotonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + auto func = [&](const xAOD::TruthParticle* truPhPtr) { + return truPhPtr->pt() > value(); + }; + auto count = std::count_if(event.m_photons->begin(), event.m_photons->end(), func); + return checkInt(count, multiplicity()); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NRCJetSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NRCJetSelector.cxx new file mode 100644 index 000000000000..18683b0a3ff2 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NRCJetSelector.cxx @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/NRCJetSelector.h" + +namespace top { + NRCJetSelector::NRCJetSelector(const std::string& params) : + SignValueSelector("RCJET_N", params, true) { + checkMultiplicityIsInteger(); + } + + bool NRCJetSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Jet* jetPtr) { + return jetPtr->pt() > value(); + }; + auto count = std::count_if(event.m_RCJets.begin(), event.m_RCJets.end(), func); + + return checkInt(count, multiplicity()); + } + + bool NRCJetSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + auto func = [&](const xAOD::Jet* jetPtr) { + return jetPtr->pt() > value(); + }; + auto count = std::count_if(event.m_RCJets.begin(), event.m_RCJets.end(), func); + + return checkInt(count, multiplicity()); + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NSoftMuonSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NSoftMuonSelector.cxx new file mode 100644 index 000000000000..b3e35e59b501 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NSoftMuonSelector.cxx @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/NSoftMuonSelector.h" + +#include <algorithm> + +namespace top { + NSoftMuonSelector::NSoftMuonSelector(const std::string& params) : + SignValueSelector("SOFTMU_N", params, true) { + checkMultiplicityIsInteger(); + } + + bool NSoftMuonSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Muon* muPtr) { + return muPtr->pt() > value(); + }; + auto count = std::count_if(event.m_softmuons.begin(), event.m_softmuons.end(), func); + + return checkInt(count, multiplicity()); + } + + bool NSoftMuonSelector::applyParticleLevel(const top::ParticleLevelEvent& /*event*/) const { + // the soft muon selector at particle level is just dummy for the time being + return true; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NTauSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NTauSelector.cxx index 45ccc7000756..29e40db457d6 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NTauSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NTauSelector.cxx @@ -1,20 +1,35 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NTauSelector.h" namespace top { - -NTauSelector::NTauSelector(const std::string& params) : - SignValueSelector("TAU_N", params, true) { + NTauSelector::NTauSelector(const std::string& params) : + SignValueSelector("TAU_N", params, true) { checkMultiplicityIsInteger(); -} + } -bool NTauSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::TauJet* tauPtr){return tauPtr->pt() > value();}; + bool NTauSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::TauJet* tauPtr) { + return tauPtr->pt() > value(); + }; auto count = std::count_if(event.m_tauJets.begin(), event.m_tauJets.end(), func); + return checkInt(count, multiplicity()); -} + } + + bool NTauSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + // If any of the required collections is a nullptr (i.e. has not been + // loaded) return false. + if (!event.m_taus) { + return false; + } + auto func = [&](const xAOD::TruthParticle* truTauPtr) { + return truTauPtr->pt() > value(); + }; + auto count = std::count_if(event.m_taus->begin(), event.m_taus->end(), func); + return checkInt(count, multiplicity()); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NTauTightSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NTauTightSelector.cxx index 445ecb8a4245..3a378e488f77 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NTauTightSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NTauTightSelector.cxx @@ -1,20 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NTauTightSelector.h" namespace top { - -NTauTightSelector::NTauTightSelector(const std::string& params) : - SignValueSelector("TAU_N_TIGHT", params, true) { + NTauTightSelector::NTauTightSelector(const std::string& params) : + SignValueSelector("TAU_N_TIGHT", params, true) { checkMultiplicityIsInteger(); -} + } -bool NTauTightSelector::apply(const top::Event& event) const { - auto func = [&](const xAOD::TauJet* tauPtr){return tauPtr->pt() > value() && tauPtr->auxdataConst<char>("passPreORSelection");}; + bool NTauTightSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::TauJet* tauPtr) { + return tauPtr->pt() > value() && tauPtr->auxdataConst<char>("passPreORSelection"); + }; auto count = std::count_if(event.m_tauJets.begin(), event.m_tauJets.end(), func); - return checkInt(count, multiplicity()); -} + return checkInt(count, multiplicity()); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NVarRCJetSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NVarRCJetSelector.cxx new file mode 100644 index 000000000000..9d450af68440 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NVarRCJetSelector.cxx @@ -0,0 +1,40 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/NVarRCJetSelector.h" +#include "TopEvent/EventTools.h" +#include <iostream> + +namespace top { + NVarRCJetSelector::NVarRCJetSelector(const std::string& name, const std::string& params) : + SignValueSelector("VRCJET_N " + name, params, true), + m_name(name) { + checkMultiplicityIsInteger(); + } + + bool NVarRCJetSelector::apply(const top::Event& event) const { + auto func = [&](const xAOD::Jet* jetPtr) { + return jetPtr->pt() > value(); + }; + + top::check(event.m_VarRCJets.find( + m_name) != event.m_VarRCJets.end(), + "Error in NVarRCJetSelector: Variable-R reclustered jets with parameter " + m_name + " not defined!"); + std::unordered_map< std::string, std::shared_ptr<xAOD::JetContainer> > VarRCJets = event.m_VarRCJets; + auto count = std::count_if(VarRCJets[m_name]->begin(), VarRCJets[m_name]->end(), func); + return checkInt(count, multiplicity()); + } + + bool NVarRCJetSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + auto func = [&](const xAOD::Jet* jetPtr) { + return jetPtr->pt() > value(); + }; + + top::check(event.m_VarRCJets.find( + m_name) != event.m_VarRCJets.end(), + "Error in NVarRCJetSelector: Variable-R reclustered jets with parameter " + m_name + " not defined!"); + auto count = std::count_if(event.m_VarRCJets[m_name]->begin(), event.m_VarRCJets[m_name]->end(), func); + return checkInt(count, multiplicity()); + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NoBadMuonSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NoBadMuonSelector.cxx index 9211a78d394a..742a31aaab33 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NoBadMuonSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/NoBadMuonSelector.cxx @@ -1,32 +1,33 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/NoBadMuonSelector.h" #include "TopEvent/EventTools.h" +#include "TopConfiguration/TopConfig.h" namespace top { - - NoBadMuonSelector::NoBadMuonSelector() : - m_muonSelectionTool("CP::MuonSelectionTool") - { - top::check( m_muonSelectionTool.retrieve() , "Failed to retrieve muonSelectionTool" ); + NoBadMuonSelector::NoBadMuonSelector(std::shared_ptr<top::TopConfig> config) : + m_config(config) { + if (!m_config->isTruthDxAOD()) { + m_muonSelectionTool = ToolHandle<CP::IMuonSelectionTool>("CP::MuonSelectionTool"); + top::check(m_muonSelectionTool.retrieve(), "Failed to retrieve muonSelectionTool"); + } } - bool NoBadMuonSelector::apply(const top::Event& event) const - { + bool NoBadMuonSelector::apply(const top::Event& event) const { + if (m_config->isTruthDxAOD()) return true; + for (const auto* const muPtr : event.m_muons) { if (m_muonSelectionTool->isBadMuon(*muPtr)) { - event.m_info->auxdecor<char>("AnalysisTop_HASBADMUON") = 1 ; - return false; + event.m_info->auxdecor<char>("AnalysisTop_HASBADMUON") = 1; + return false; } } return true; } - std::string NoBadMuonSelector::name() const - { + std::string NoBadMuonSelector::name() const { return "NOBADMUON"; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/OSLeptonSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/OSLeptonSelector.cxx index 0ea7add9c1c5..60762edc5512 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/OSLeptonSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/OSLeptonSelector.cxx @@ -1,59 +1,49 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/OSLeptonSelector.h" #include "TopEvent/EventTools.h" namespace top { - -bool OSLeptonSelector::apply(const top::Event& event) const { + bool OSLeptonSelector::apply(const top::Event& event) const { unsigned int negative_counter = 0; unsigned int positive_counter = 0; for (const auto* const elPtr : event.m_electrons) - if (elPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + if (elPtr->charge() > 0) ++positive_counter; + else ++negative_counter; for (const auto* const muPtr : event.m_muons) - if (muPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + if (muPtr->charge() > 0) ++positive_counter; + else ++negative_counter; return positive_counter > 0 && negative_counter > 0; -} + } -bool OSLeptonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool OSLeptonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons ){ - return false; + if (not event.m_electrons + or not event.m_muons) { + return false; } unsigned int negative_counter = 0; unsigned int positive_counter = 0; - for (const auto elPtr : * event.m_electrons) - if (elPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + for (const auto elPtr : *event.m_electrons) + if (elPtr->charge() > 0) ++positive_counter; + else ++negative_counter; - for (const auto muPtr : * event.m_muons) - if (muPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + for (const auto muPtr : *event.m_muons) + if (muPtr->charge() > 0) ++positive_counter; + else ++negative_counter; return positive_counter > 0 && negative_counter > 0; -} + } -std::string OSLeptonSelector::name() const { + std::string OSLeptonSelector::name() const { return "OS"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/OSLeptonTightSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/OSLeptonTightSelector.cxx index ec7f4756cc3e..6f3fb5bf1b3e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/OSLeptonTightSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/OSLeptonTightSelector.cxx @@ -1,59 +1,49 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/OSLeptonTightSelector.h" #include "TopEvent/EventTools.h" namespace top { - -bool OSLeptonTightSelector::apply(const top::Event& event) const { + bool OSLeptonTightSelector::apply(const top::Event& event) const { unsigned int negative_counter = 0; unsigned int positive_counter = 0; for (const auto* const elPtr : event.m_electrons) - if (elPtr->charge() > 0 && elPtr->auxdataConst<char>("passPreORSelection")) - ++positive_counter; - else if (elPtr->charge() < 0 && elPtr->auxdataConst<char>("passPreORSelection")) - ++negative_counter; + if (elPtr->charge() > 0 && elPtr->auxdataConst<char>("passPreORSelection")) ++positive_counter; + else if (elPtr->charge() < 0 && elPtr->auxdataConst<char>("passPreORSelection")) ++negative_counter; for (const auto* const muPtr : event.m_muons) - if (muPtr->charge() > 0 && muPtr->auxdataConst<char>("passPreORSelection")) - ++positive_counter; - else if (muPtr->charge() < 0 && muPtr->auxdataConst<char>("passPreORSelection")) - ++negative_counter; + if (muPtr->charge() > 0 && muPtr->auxdataConst<char>("passPreORSelection")) ++positive_counter; + else if (muPtr->charge() < 0 && muPtr->auxdataConst<char>("passPreORSelection")) ++negative_counter; return positive_counter > 0 && negative_counter > 0; -} + } -bool OSLeptonTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool OSLeptonTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons ){ - return false; + if (not event.m_electrons + or not event.m_muons) { + return false; } unsigned int negative_counter = 0; unsigned int positive_counter = 0; - for (const auto elPtr : * event.m_electrons) - if (elPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + for (const auto elPtr : *event.m_electrons) + if (elPtr->charge() > 0) ++positive_counter; + else ++negative_counter; - for (const auto muPtr : * event.m_muons) - if (muPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + for (const auto muPtr : *event.m_muons) + if (muPtr->charge() > 0) ++positive_counter; + else ++negative_counter; return positive_counter > 0 && negative_counter > 0; -} + } -std::string OSLeptonTightSelector::name() const { + std::string OSLeptonTightSelector::name() const { return "OS_TIGHT"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ParticleLevelSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ParticleLevelSelector.cxx index d4ca789831e2..60353c83f06f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ParticleLevelSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ParticleLevelSelector.cxx @@ -1,32 +1,19 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Filename: ParticleLevelSelector.cxx -// Description: -// Author: Fabian Wilk -// Created: Tue Oct 27 13:29:16 2015 -// -// (c) by Fabian Wilk -// -// This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 -// International License. -// -// You should have received a copy of the license along with this work. -// If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/ParticleLevelSelector.h" namespace top { - bool ParticleLevelSelector::apply(const top::Event&) const { - return false; - } + bool ParticleLevelSelector::apply(const top::Event&) const { + return false; + } - bool ParticleLevelSelector::applyParticleLevel(const top::ParticleLevelEvent&) const { - return true; - } + bool ParticleLevelSelector::applyParticleLevel(const top::ParticleLevelEvent&) const { + return true; + } - std::string ParticleLevelSelector::name() const { - return "PARTICLE_LEVEL"; - } + std::string ParticleLevelSelector::name() const { + return "PARTICLE_LEVEL"; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PlotManager.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PlotManager.cxx index e4d37838d33a..a31343eb92fc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PlotManager.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PlotManager.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "EventLoop/Worker.h" @@ -15,108 +15,173 @@ #include <iostream> namespace top { - -PlotManager::PlotManager(const std::string& name, TFile* outputFile, EL::Worker* wk) : + PlotManager::PlotManager(const std::string& name, TFile* outputFile, EL::Worker* wk) : m_wk(wk), m_name(name), m_plotDir(nullptr) { - if (!m_wk) { m_plotDir = outputFile->GetDirectory(m_name.c_str()); - if (!m_plotDir) - m_plotDir = outputFile->mkdir(m_name.c_str()); + if (!m_plotDir) m_plotDir = outputFile->mkdir(m_name.c_str()); + m_plotDir = outputFile->GetDirectory(m_name.c_str());// this is needed if the name contains a sub-directory m_plotDir->cd(); } -} + } -PlotManager::PlotManager(const std::string& sample,const std::string& channel,const std::string& syst,TFile* outputFile) : - m_wk(nullptr), - m_name("SetMe"), - m_plotDir(nullptr) -{ - outputFile->cd(); - gDirectory->cd("/"); - - if( !gDirectory->GetKey(sample.c_str()) ){gDirectory->mkdir(sample.c_str());} - gDirectory->cd(sample.c_str()); - - if( !gDirectory->GetKey(channel.c_str()) ){gDirectory->mkdir(channel.c_str());} - gDirectory->cd(channel.c_str()); - - if( !gDirectory->GetKey(syst.c_str()) ){gDirectory->mkdir(syst.c_str());} - gDirectory->cd(syst.c_str()); - - TString plotDirName = sample + "/" + channel + "/" + syst; - - m_plotDir = outputFile->GetDirectory(plotDirName); - m_plotDir->cd(); -} + PlotManager::PlotManager(const std::string& sample, const std::string& channel, const std::string& syst, + TFile* outputFile) : + m_wk(nullptr), + m_name("SetMe"), + m_plotDir(nullptr) { + outputFile->cd(); + gDirectory->cd("/"); + + if (!gDirectory->GetKey(sample.c_str())) { + gDirectory->mkdir(sample.c_str()); + } + gDirectory->cd(sample.c_str()); -void PlotManager::addHist(const std::string& hname, const std::string& title, int bins, double start, double end) const { + if (!gDirectory->GetKey(channel.c_str())) { + gDirectory->mkdir(channel.c_str()); + } + gDirectory->cd(channel.c_str()); + + if (!gDirectory->GetKey(syst.c_str())) { + gDirectory->mkdir(syst.c_str()); + } + gDirectory->cd(syst.c_str()); + + TString plotDirName = sample + "/" + channel + "/" + syst; + + m_plotDir = outputFile->GetDirectory(plotDirName); + m_plotDir->cd(); + } + + void PlotManager::addHist(const std::string& hname, const std::string& title, int bins, double start, + double end) const { TH1D* h = nullptr; + if (!m_wk) { - m_plotDir->cd(); - h = new TH1D(hname.c_str(), title.c_str(), bins, start, end); - } - else { - std::string pathname = m_name + "/" + hname; - h = new TH1D(pathname.c_str(), title.c_str(), bins, start, end); - m_wk->addOutput(h); + m_plotDir->cd(); + h = new TH1D(hname.c_str(), title.c_str(), bins, start, end); + } else { + std::string pathname = m_name + "/" + hname; + h = new TH1D(pathname.c_str(), title.c_str(), bins, start, end); + m_wk->addOutput(h); } - if (m_histograms.find(hname) != m_histograms.end()) { - std::cout << "ERROR: Running addHist with " << hname << std::endl; - std::cout << "but that histogram already exists" << std::endl; - std::cout << "will not continue" << std::endl; - exit(1); + checkDuplicate(hname); + + h->Sumw2(); + m_histograms.insert(make_pair(hname, h)); + } + + void PlotManager::addHist(const std::string& hname, const std::string& title, int bins, double* binArray) const { + TH1D* h = nullptr; + + if (!m_wk) { + m_plotDir->cd(); + h = new TH1D(hname.c_str(), title.c_str(), bins, binArray); + } else { + std::string pathname = m_name + "/" + hname; + h = new TH1D(pathname.c_str(), title.c_str(), bins, binArray); + m_wk->addOutput(h); } + checkDuplicate(hname); + h->Sumw2(); m_histograms.insert(make_pair(hname, h)); -} + } -void PlotManager::addHist(const std::string& hname, const std::string& title, - int xbins, double xstart, double xend, - int ybins, double ystart, double yend) const { + void PlotManager::addHist(const std::string& hname, const std::string& title, + int xbins, double xstart, double xend, + int ybins, double ystart, double yend) const { TH2D* h = nullptr; + if (!m_wk) { - m_plotDir->cd(); - h = new TH2D(hname.c_str(), title.c_str(), - xbins, xstart, xend, - ybins, ystart, yend); + m_plotDir->cd(); + h = new TH2D(hname.c_str(), title.c_str(), + xbins, xstart, xend, + ybins, ystart, yend); + } else { + std::string pathname = m_name + "/" + hname; + h = new TH2D(pathname.c_str(), title.c_str(), + xbins, xstart, xend, + ybins, ystart, yend); + m_wk->addOutput(h); } - else { - std::string pathname = m_name + "/" + hname; - h = new TH2D(pathname.c_str(), title.c_str(), - xbins, xstart, xend, - ybins, ystart, yend); - m_wk->addOutput(h); + + checkDuplicate(hname); + + h->Sumw2(); + m_histograms.insert(make_pair(hname, h)); + } + + void PlotManager::addHist(const std::string& hname, const std::string& title, + int xbins, double* xbinArray, + int ybins, double* ybinArray) const { + TH2D* h = nullptr; + + if (!m_wk) { + m_plotDir->cd(); + h = new TH2D(hname.c_str(), title.c_str(), + xbins, xbinArray, + ybins, ybinArray); + } else { + std::string pathname = m_name + "/" + hname; + h = new TH2D(pathname.c_str(), title.c_str(), + xbins, xbinArray, + ybins, ybinArray); + m_wk->addOutput(h); } - if (m_histograms.find(hname) != m_histograms.end()) { - std::cout << "ERROR: Running addHist with " << hname << std::endl; - std::cout << "but that histogram already exists" << std::endl; - std::cout << "will not continue" << std::endl; - exit(1); + checkDuplicate(hname); + + h->Sumw2(); + m_histograms.insert(make_pair(hname, h)); + } + + void PlotManager::addHist(const std::string& hname, const std::string& title, + int xbins, double* xbinArray, + int ybins, double ystart, double yend) const { + TH2D* h = nullptr; + + if (!m_wk) { + m_plotDir->cd(); + h = new TH2D(hname.c_str(), title.c_str(), + xbins, xbinArray, + ybins, ystart, yend); + } else { + std::string pathname = m_name + "/" + hname; + h = new TH2D(pathname.c_str(), title.c_str(), + xbins, xbinArray, + ybins, ystart, yend); + m_wk->addOutput(h); } + checkDuplicate(hname); + h->Sumw2(); m_histograms.insert(make_pair(hname, h)); -} + } -TH1* PlotManager::hist(const std::string& name) const { + TH1* PlotManager::hist(const std::string& name) const { if (m_histograms.find(name) == m_histograms.end()) { - std::cout << "Histogram doesn\'t exist: " << name << std::endl; - exit(1); + throw std::runtime_error("PlotManager::hist: Histogram " + name + " does not exist."); } return m_histograms[name]; -} + } -void PlotManager::scaleHistograms(double sf) const { + void PlotManager::scaleHistograms(double sf) const { for (std::unordered_map<std::string, TH1*>::iterator it = begin(m_histograms); it != end(m_histograms); ++it) - it->second->Scale(sf); -} + it->second->Scale(sf); + } + void PlotManager::checkDuplicate(const std::string& hname) const { + if (m_histograms.find(hname) != m_histograms.end()) { + throw std::runtime_error("PlotManager::addHist: Histogram " + hname + " to add already exists."); + } + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PrimaryVertexSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PrimaryVertexSelector.cxx index e4cadfe007aa..f218df9a65cc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PrimaryVertexSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PrimaryVertexSelector.cxx @@ -1,18 +1,15 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/PrimaryVertexSelector.h" #include "TopEvent/EventTools.h" namespace top { - - PrimaryVertexSelector::PrimaryVertexSelector() - { + PrimaryVertexSelector::PrimaryVertexSelector() { } - bool PrimaryVertexSelector::apply(const top::Event& event) const - { + bool PrimaryVertexSelector::apply(const top::Event& event) const { if (event.m_info->isAvailable<char>("AnalysisTop_PRIVTX")) { if (event.m_info->auxdataConst<char>("AnalysisTop_PRIVTX") == 1) { return true; @@ -21,9 +18,7 @@ namespace top { return false; } - std::string PrimaryVertexSelector::name() const - { + std::string PrimaryVertexSelector::name() const { return "PRIVTX"; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PrintEventSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PrintEventSelector.cxx index 39ea8edd6434..c507db4e245a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PrintEventSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/PrintEventSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/PrintEventSelector.h" @@ -8,23 +8,23 @@ #include "TopCorrections/ScaleFactorRetriever.h" -namespace top { +#include "TopEventSelectionTools/MsgCategory.h" +using namespace TopEventSelectionTools; -bool PrintEventSelector::apply(const top::Event& event) const { +namespace top { + bool PrintEventSelector::apply(const top::Event& event) const { //print some stuff about the event - std::cout << event << std::endl; - - //print the SF if calculated and if MC -// if (top::isSimulation(event)) { -// top::ScaleFactorRetriever::print(event); -// std::cout << std::endl; -// } + ATH_MSG_INFO(event); + return true; + } + bool PrintEventSelector::applyParticleLevel(const top::ParticleLevelEvent& plEvent) const { + //print some stuff about the event + ATH_MSG_INFO("Particle Level\n" << plEvent); return true; -} + } -std::string PrintEventSelector::name() const { + std::string PrintEventSelector::name() const { return "PRINT"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/RecoLevelSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/RecoLevelSelector.cxx index 0fe8468d0c68..2169e48e6696 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/RecoLevelSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/RecoLevelSelector.cxx @@ -1,32 +1,19 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Filename: RecoLevelSelector.cxx -// Description: -// Author: Fabian Wilk -// Created: Tue Oct 27 13:28:22 2015 -// -// (c) by Fabian Wilk -// -// This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 -// International License. -// -// You should have received a copy of the license along with this work. -// If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/RecoLevelSelector.h" namespace top { - bool RecoLevelSelector::apply(const top::Event&) const { - return true; - } + bool RecoLevelSelector::apply(const top::Event&) const { + return true; + } - bool RecoLevelSelector::applyParticleLevel(const top::ParticleLevelEvent&) const { - return false; - } + bool RecoLevelSelector::applyParticleLevel(const top::ParticleLevelEvent&) const { + return false; + } - std::string RecoLevelSelector::name() const { - return "RECO_LEVEL"; - } + std::string RecoLevelSelector::name() const { + return "RECO_LEVEL"; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/RunNumberSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/RunNumberSelector.cxx index 334f6ad4753a..78dcb60d05b1 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/RunNumberSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/RunNumberSelector.cxx @@ -1,33 +1,29 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/RunNumberSelector.h" #include "TopEvent/EventTools.h" #include "TopConfiguration/TopConfig.h" namespace top { + RunNumberSelector::RunNumberSelector(const std::string& params, std::shared_ptr<top::TopConfig> config) : + SignValueSelector("RUN_NUMBER", params) { + m_config = config; + } -RunNumberSelector::RunNumberSelector(const std::string& params,std::shared_ptr<top::TopConfig> config) : - SignValueSelector("RUN_NUMBER", params) { - m_config = config; -} - -bool RunNumberSelector::apply(const top::Event& event) const { + bool RunNumberSelector::apply(const top::Event& event) const { unsigned int number = 0; - if (!m_config->isMC()) - number = event.m_info -> runNumber(); + + if (!m_config->isMC()) number = event.m_info->runNumber(); else { - if (event.m_info->isAvailable<unsigned int>("RandomRunNumber")) - number = event.m_info->auxdataConst<unsigned int>("RandomRunNumber"); - else { - std::cout << "RunNumberSelector: can't find random Run Number - did you setup the pile-up reweighting tool?" << std::endl; - exit(1); - } + if (event.m_info->isAvailable<unsigned int>("RandomRunNumber")) number = event.m_info->auxdataConst<unsigned int>( + "RandomRunNumber"); + else { + throw std::runtime_error("RunNumberSelector: RandomRunNumber EventInfo decoration not available. Indicates issue with PRW tool."); + } } return checkInt(number, value()); -} - - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SSLeptonSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SSLeptonSelector.cxx index 80b7462dc54e..bcebd48d74f4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SSLeptonSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SSLeptonSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/SSLeptonSelector.h" #include "TopEvent/EventTools.h" @@ -12,55 +12,44 @@ // Need to support applying SF to leptons with different quality/isolation at once namespace top { - -bool SSLeptonSelector::apply(const top::Event& event) const { + bool SSLeptonSelector::apply(const top::Event& event) const { unsigned int negative_counter = 0; unsigned int positive_counter = 0; for (const auto* const elPtr : event.m_electrons) - if (elPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + if (elPtr->charge() > 0) ++positive_counter; + else ++negative_counter; for (const auto* const muPtr : event.m_muons) - if (muPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + if (muPtr->charge() > 0) ++positive_counter; + else ++negative_counter; return positive_counter > 1 || negative_counter > 1; -} + } -bool SSLeptonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool SSLeptonSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons ){ - return false; + if (not event.m_electrons + or not event.m_muons) { + return false; } unsigned int negative_counter = 0; unsigned int positive_counter = 0; - for (const auto elPtr : * event.m_electrons) - if (elPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + for (const auto elPtr : *event.m_electrons) + if (elPtr->charge() > 0) ++positive_counter; + else ++negative_counter; - for (const auto muPtr : * event.m_muons) - if (muPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + for (const auto muPtr : *event.m_muons) + if (muPtr->charge() > 0) ++positive_counter; + else ++negative_counter; return positive_counter > 1 || negative_counter > 1; -} + } - -std::string SSLeptonSelector::name() const { + std::string SSLeptonSelector::name() const { return "SS"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SSLeptonTightSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SSLeptonTightSelector.cxx index d045f741cf1f..96960dceb097 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SSLeptonTightSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SSLeptonTightSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/SSLeptonTightSelector.h" #include "TopEvent/EventTools.h" @@ -12,55 +12,44 @@ // Need to support applying SF to leptons with different quality/isolation at once namespace top { - -bool SSLeptonTightSelector::apply(const top::Event& event) const { + bool SSLeptonTightSelector::apply(const top::Event& event) const { unsigned int negative_counter = 0; unsigned int positive_counter = 0; for (const auto* const elPtr : event.m_electrons) - if (elPtr->charge() > 0 && elPtr->auxdataConst<char>("passPreORSelection")) - ++positive_counter; - else if (elPtr->charge() < 0 && elPtr->auxdataConst<char>("passPreORSelection")) - ++negative_counter; + if (elPtr->charge() > 0 && elPtr->auxdataConst<char>("passPreORSelection")) ++positive_counter; + else if (elPtr->charge() < 0 && elPtr->auxdataConst<char>("passPreORSelection")) ++negative_counter; for (const auto* const muPtr : event.m_muons) - if (muPtr->charge() > 0 && muPtr->auxdataConst<char>("passPreORSelection")) - ++positive_counter; - else if (muPtr->charge() < 0 && muPtr->auxdataConst<char>("passPreORSelection")) - ++negative_counter; + if (muPtr->charge() > 0 && muPtr->auxdataConst<char>("passPreORSelection")) ++positive_counter; + else if (muPtr->charge() < 0 && muPtr->auxdataConst<char>("passPreORSelection")) ++negative_counter; return positive_counter > 1 || negative_counter > 1; -} + } -bool SSLeptonTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { + bool SSLeptonTightSelector::applyParticleLevel(const top::ParticleLevelEvent& event) const { // If any of the required collections is a nullptr (i.e. has not been // loaded) return false. - if ( not event.m_electrons - or not event.m_muons ){ - return false; + if (not event.m_electrons + or not event.m_muons) { + return false; } unsigned int negative_counter = 0; unsigned int positive_counter = 0; - for (const auto elPtr : * event.m_electrons) - if (elPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + for (const auto elPtr : *event.m_electrons) + if (elPtr->charge() > 0) ++positive_counter; + else ++negative_counter; - for (const auto muPtr : * event.m_muons) - if (muPtr->charge() > 0) - ++positive_counter; - else - ++negative_counter; + for (const auto muPtr : *event.m_muons) + if (muPtr->charge() > 0) ++positive_counter; + else ++negative_counter; return positive_counter > 1 || negative_counter > 1; -} + } - -std::string SSLeptonTightSelector::name() const { + std::string SSLeptonTightSelector::name() const { return "SS_TIGHT"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SaveEventSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SaveEventSelector.cxx index 66dedd6b06c7..5ae8bc86568c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SaveEventSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SaveEventSelector.cxx @@ -1,17 +1,15 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/SaveEventSelector.h" namespace top { - -bool SaveEventSelector::apply(const top::Event&) const { + bool SaveEventSelector::apply(const top::Event&) const { return true; -} + } -std::string SaveEventSelector::name() const { + std::string SaveEventSelector::name() const { return "SAVE"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SignValueSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SignValueSelector.cxx index dc760cfbb5f9..0bd353b3554d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SignValueSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/SignValueSelector.cxx @@ -1,18 +1,23 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/SignValueSelector.h" +#include "TopConfiguration/Tokenize.h" -namespace top { +#include "TopEventSelectionTools/MsgCategory.h" +using namespace TopEventSelectionTools; -SignValueSelector::SignValueSelector(const std::string& name, std::string params, bool multiplicityMode, bool cutValueMode) : - m_sign(signNOIDEA), - m_cutvalue(0), - m_cutvalueString(""), - m_multiplicity(-1) { +namespace top { + SignValueSelector::SignValueSelector(const std::string& name, std::string params, bool multiplicityMode, + bool cutValueMode) : + m_sign(signNOIDEA), + m_cutvalue(0), + m_cutvalueString(""), + m_multiplicity(-1) { + m_cutvalueStringDelimReplace = ""; //cutValueMode always set to false if multiplicityMode is false - if (!multiplicityMode) cutValueMode=false; + if (!multiplicityMode) cutValueMode = false; //get the sign and remove it from the params text m_sign = decodesign(params); if (!cutValueMode) std::istringstream(params) >> m_cutvalue >> m_multiplicity; @@ -20,144 +25,187 @@ SignValueSelector::SignValueSelector(const std::string& name, std::string params //form the name string for the tool std::stringstream ss; - if (!multiplicityMode) - ss << name << " " << signstring() << " " << m_cutvalue; + if (!multiplicityMode) ss << name << " " << signstring() << " " << m_cutvalue; else { - if (m_multiplicity < 0) { - std::cout << "Cut value and multiplicity must be set for " << name << std::endl; - exit(1); - } - - if (!cutValueMode) - ss << name << " " << m_cutvalue << " " << signstring() << " " << m_multiplicity; - else - ss << name << " " << m_cutvalueString << " " << signstring() << " " << m_multiplicity; + if (m_multiplicity < 0) { + throw std::runtime_error("Cut value and multiplicity must be set for " + name); + } + + if (!cutValueMode) ss << name << " " << m_cutvalue << " " << signstring() << " " << m_multiplicity; + else ss << name << " " << m_cutvalueString << " " << signstring() << " " << m_multiplicity; } m_name = ss.str(); -} + } + + SignValueSelector::SignValueSelector(const std::string& name, std::string params, bool multiplicityMode, + bool cutValueMode, std::string delim, std::string replace, + std::string default_prefix) : + SignValueSelector(name, params, multiplicityMode, cutValueMode) { + // This function is only if we need a bit of additional string manipulation + // Required for the btagging selector when we start doing "alg:wp" + // If string is empty, do the split, otherwise just return the stored value + + std::vector<std::string> tokens; + tokenize(m_cutvalueString, tokens, delim); + if (tokens.size() > 1) { + for (auto cutString : tokens) { + m_cutvalueStringDelimReplace += cutString; + m_cutvalueStringDelimReplace += replace; + } + // Tidy up the end of the string + m_cutvalueStringDelimReplace = m_cutvalueStringDelimReplace.substr(0, + m_cutvalueStringDelimReplace.length() - + replace.length()); + } + // We are kind, and keep some backwards compatablity, so incase you did not know the syntax changed, hopefully we + // provided the most likely default + else { + ATH_MSG_INFO("SignValueSelector :: We are using a default_prefix as we could not split on a delimiter."); + m_cutvalueStringDelimReplace = default_prefix + replace + m_cutvalueString; + ATH_MSG_INFO("SignValueSelector :: The final result is " << m_cutvalueStringDelimReplace); + } + } -std::string SignValueSelector::name() const { + std::string SignValueSelector::name() const { return m_name; -} + } -void SignValueSelector::checkValueIsInteger() { + void SignValueSelector::checkValueIsInteger() { if (value() != floor(value())) { - std::cout << "The number " << value() << " is not an integer\n"; - std::cout << "As defined in " << name() << "\n"; - std::cout << "Please fix and try again\n"; - exit(1); + ATH_MSG_ERROR("The number " << value() << " is not an integer\n" + << "As defined in " << name() << "\n"); + throw std::runtime_error("Failed parsing value for SignValueSelector"); } -} + } -void SignValueSelector::checkMultiplicityIsInteger() { + void SignValueSelector::checkMultiplicityIsInteger() { if (multiplicity() != floor(multiplicity())) { - std::cout << "The number " << value() << " is not an integer\n"; - std::cout << "As defined in " << name() << "\n"; - std::cout << "Please fix and try again\n"; - exit(1); + ATH_MSG_ERROR("The number " << multiplicity() << " is not an integer\n" + << "As defined in " << name() << "\n"); + throw std::runtime_error("Failed parsing multiplicity cut for SignValueSelector"); } -} + } -SignValueSelector::Sign SignValueSelector::sign() const { + SignValueSelector::Sign SignValueSelector::sign() const { return m_sign; -} + } -double SignValueSelector::value() const { + double SignValueSelector::value() const { return m_cutvalue; -} + } -std::string SignValueSelector::valueString() const { + std::string SignValueSelector::valueString() const { return m_cutvalueString; -} + } + + std::string SignValueSelector::valueStringDelimReplace() const { + return m_cutvalueStringDelimReplace; + } -double SignValueSelector::multiplicity() const { + double SignValueSelector::multiplicity() const { return m_multiplicity; -} + } -SignValueSelector::Sign SignValueSelector::decodesign(std::string& params) { + SignValueSelector::Sign SignValueSelector::decodesign(std::string& params) { Sign tempsign(signNOIDEA); + if (params.find("==") != std::string::npos) { - tempsign = signEQ; - params.erase(params.find("=="), 2); + tempsign = signEQ; + params.erase(params.find("=="), 2); } else if (params.find("<=") != std::string::npos) { - tempsign = signLTEQ; - params.erase(params.find("<="), 2); + tempsign = signLTEQ; + params.erase(params.find("<="), 2); } else if (params.find(">=") != std::string::npos) { - tempsign = signGTEQ; - params.erase(params.find(">="), 2); + tempsign = signGTEQ; + params.erase(params.find(">="), 2); } else if (params.find("<") != std::string::npos) { - tempsign = signLT; - params.erase(params.find("<"), 1); + tempsign = signLT; + params.erase(params.find("<"), 1); } else if (params.find(">") != std::string::npos) { - tempsign = signGT; - params.erase(params.find(">"), 1); + tempsign = signGT; + params.erase(params.find(">"), 1); } return tempsign; -} + } -bool SignValueSelector::checkFloat(double value, double cut) const { + bool SignValueSelector::checkFloat(double value, double cut) const { switch (m_sign) { case signNOIDEA: { - std::cout << "Do not recognise the sign\n"; - exit(1); - } case signEQ: { - std::cout << "Can't compare floats with ==\n"; - exit(1); - } case signLT: - return value < cut; + throw std::runtime_error("SignValueSelector::checkFloat: Can't recognise the sign"); + } + + case signEQ: { + throw std::runtime_error("SignValueSelector::checkFloat: Can't compare floats with =="); + } + + case signLT: + return value < cut; + case signGT: - return value > cut; + return value > cut; + case signLTEQ: - return value <= cut; + return value <= cut; + case signGTEQ: - return value >= cut; + return value >= cut; } return false; -} + } -bool SignValueSelector::checkInt(int value, int cut) const { + bool SignValueSelector::checkInt(int value, int cut) const { switch (m_sign) { case signNOIDEA: { - std::cout << "Do not recognise the sign\n"; - exit(1); - } case signEQ: - return value == cut; + throw std::runtime_error("SignValueSelector::checkInt: Can't recognise the sign"); + } + + case signEQ: + return value == cut; + case signLT: - return value < cut; + return value < cut; + case signGT: - return value > cut; + return value > cut; + case signLTEQ: - return value <= cut; + return value <= cut; + case signGTEQ: - return value >= cut; + return value >= cut; } return false; -} + } -const std::string SignValueSelector::signstring() const { + const std::string SignValueSelector::signstring() const { switch (m_sign) { case signNOIDEA: { - std::cout << "SignValueSelector is confused\n"; - std::cout << "Please check your cuts have all the correct cuts\n"; - std::cout << "e.g. ==, >, >=, <, <=\n"; - exit(1); - } case signEQ: - return "=="; + ATH_MSG_ERROR("SignValueSelector is confused\n" + << "Check that your cuts have one of: " + << "==, >, >=, <, <=\n"); + throw std::runtime_error("SignValueSelector::signstring: Can't recognise the comparison operator"); + } + + case signEQ: + return "=="; + case signLT: - return "<"; + return "<"; + case signGT: - return ">"; + return ">"; + case signLTEQ: - return "<="; + return "<="; + case signGTEQ: - return ">="; + return ">="; } return ""; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TopEventSelectionToolsLoader.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TopEventSelectionToolsLoader.cxx index e66ba923a428..4af018b1e456 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TopEventSelectionToolsLoader.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TopEventSelectionToolsLoader.cxx @@ -1,36 +1,43 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "AsgMessaging/MessageCheck.h" #include "TopEventSelectionTools/TopEventSelectionToolsLoader.h" #include "TopEventSelectionTools/ExamplePlots.h" #include "TopEventSelectionTools/JetFlavorPlots.h" +#include "TopEventSelectionTools/JetResponsePlots.h" +#include "TopEventSelectionTools/JetFtagEffPlots.h" #include "TopEventSelectionTools/FakesMMConfigs.h" +#include "TopEventSelectionTools/GlobalTrigDecisionSelector.h" +#include "TopEventSelectionTools/GlobalTrigMatchSelector.h" #include "TopEventSelectionTools/GRLSelector.h" #include "TopEventSelectionTools/GoodCaloSelector.h" #include "TopEventSelectionTools/HTSelector.h" -#include "TopEventSelectionTools/IP3DSV1Selector.h" #include "TopEventSelectionTools/InitialSelector.h" #include "TopEventSelectionTools/JetCleaningSelector.h" +#include "TopEventSelectionTools/TrackJetCleaningSelector.h" #include "TopEventSelectionTools/JetNGhostSelector.h" #include "TopEventSelectionTools/KLFitterSelector.h" #include "TopEventSelectionTools/METMWTSelector.h" #include "TopEventSelectionTools/METSelector.h" #include "TopEventSelectionTools/MLLSelector.h" #include "TopEventSelectionTools/MLLWindowSelector.h" -#include "TopEventSelectionTools/MV1Selector.h" -#include "TopEventSelectionTools/MV2c20Selector.h" #include "TopEventSelectionTools/MV2c10Selector.h" #include "TopEventSelectionTools/MWTSelector.h" #include "TopEventSelectionTools/NElectronNMuonSelector.h" #include "TopEventSelectionTools/NElectronNMuonTightSelector.h" #include "TopEventSelectionTools/NElectronSelector.h" #include "TopEventSelectionTools/NElectronTightSelector.h" +#include "TopEventSelectionTools/NFwdElectronSelector.h" +#include "TopEventSelectionTools/NFwdElectronTightSelector.h" #include "TopEventSelectionTools/NJetSelector.h" #include "TopEventSelectionTools/NJetBtagSelector.h" #include "TopEventSelectionTools/NMuonSelector.h" +#include "TopEventSelectionTools/NSoftMuonSelector.h" #include "TopEventSelectionTools/NoBadMuonSelector.h" #include "TopEventSelectionTools/NMuonTightSelector.h" #include "TopEventSelectionTools/NPhotonSelector.h" @@ -46,9 +53,13 @@ #include "TopEventSelectionTools/SSLeptonTightSelector.h" #include "TopEventSelectionTools/SaveEventSelector.h" #include "TopEventSelectionTools/TrigDecisionSelector.h" +#include "TopEventSelectionTools/TrigDecisionLooseSelector.h" +#include "TopEventSelectionTools/TrigDecisionTightSelector.h" #include "TopEventSelectionTools/TrigMatchSelector.h" #include "TopEventSelectionTools/RunNumberSelector.h" #include "TopEventSelectionTools/NLargeJetSelector.h" +#include "TopEventSelectionTools/NRCJetSelector.h" +#include "TopEventSelectionTools/NVarRCJetSelector.h" #include "TopConfiguration/TopConfig.h" @@ -57,8 +68,10 @@ #include "TFile.h" namespace top { - - top::EventSelectorBase* TopEventSelectionToolsLoader::initTool(const std::string& name, const std::string& line, TFile* outputFile,std::shared_ptr<top::TopConfig> config, EL::Worker* wk) { + top::EventSelectorBase* TopEventSelectionToolsLoader::initTool(const std::string& name, const std::string& line, + TFile* outputFile, + std::shared_ptr<top::TopConfig> config, + EL::Worker* wk) { //get the first bit of the string and store it in toolname std::istringstream iss(line); std::string toolname; @@ -66,100 +79,76 @@ namespace top { //any parameters? std::string param; - if (line.size() > toolname.size()) - param = line.substr(toolname.size() + 1); + if (line.size() > toolname.size()) param = line.substr(toolname.size() + 1); - if (toolname == "JET_N") - return new top::NJetSelector(param); - else if (toolname == "JET_N_BTAG") - return new top::NJetBtagSelector(param,config); - else if (toolname == "LJET_N") - return new top::NLargeJetSelector(param); - else if (toolname == "MV1_N") - return new top::MV1Selector(param); - else if (toolname == "MV2C20_N") - return new top::MV2c20Selector(param); - else if (toolname == "MV2C10_N") - return new top::MV2c10Selector(param); - else if (toolname == "IP3DSV1_N") - return new top::IP3DSV1Selector(param); - else if (toolname == "EL_N_OR_MU_N") - return new top::NElectronNMuonSelector(param); - else if (toolname == "EL_N_OR_MU_N_TIGHT") - return new top::NElectronNMuonTightSelector(param); - else if (toolname == "EL_N") - return new top::NElectronSelector(param); - else if (toolname == "EL_N_TIGHT") - return new top::NElectronTightSelector(param); - else if (toolname == "MU_N") - return new top::NMuonSelector(param); - else if (toolname == "MU_N_TIGHT") - return new top::NMuonTightSelector(param); - else if (toolname == "PH_N") - return new top::NPhotonSelector(param); - else if (toolname == "TAU_N") - return new top::NTauSelector(param); - else if (toolname == "TAU_N_TIGHT") - return new top::NTauTightSelector(param); - else if (toolname == "MET+MWT") - return new top::METMWTSelector(param); - else if (toolname == "MET") - return new top::METSelector(param); - else if (toolname == "MWT") - return new top::MWTSelector(param); - else if (toolname == "MLLWIN") - return new top::MLLWindow(param); - else if (toolname == "MLL") - return new top::MLLSelector(param); - else if (toolname == "HT") - return new top::HTSelector(param); + if (toolname == "JET_N") return new top::NJetSelector(param); + else if (toolname == "JET_N_BTAG") return new top::NJetBtagSelector(param, config, false); + else if (toolname == "TJET_N_BTAG") return new top::NJetBtagSelector(param, config, true); + else if (toolname == "LJET_N") return new top::NLargeJetSelector(param); + else if (toolname == "RCJET_N") return new top::NRCJetSelector(param); + else if (toolname == "VRCJET_N") { + std::istringstream is(param); + std::string name; + getline(is, name, ' '); + return new top::NVarRCJetSelector(name, param.substr(name.size() + 1)); + } else if (toolname == "MV2C10_N") return new top::MV2c10Selector(param); + else if (toolname == "EL_N_OR_MU_N") return new top::NElectronNMuonSelector(param); + else if (toolname == "EL_N_OR_MU_N_TIGHT") return new top::NElectronNMuonTightSelector(param); + else if (toolname == "EL_N") return new top::NElectronSelector(param); + else if (toolname == "EL_N_TIGHT") return new top::NElectronTightSelector(param); + else if (toolname == "FWDEL_N") return new top::NFwdElectronSelector(param); + else if (toolname == "FWDEL_N_TIGHT") return new top::NFwdElectronTightSelector(param); + else if (toolname == "MU_N") return new top::NMuonSelector(param); + else if (toolname == "SOFTMU_N") return new top::NSoftMuonSelector(param); + else if (toolname == "MU_N_TIGHT") return new top::NMuonTightSelector(param); + else if (toolname == "PH_N") return new top::NPhotonSelector(param); + else if (toolname == "TAU_N") return new top::NTauSelector(param); + else if (toolname == "TAU_N_TIGHT") return new top::NTauTightSelector(param); + else if (toolname == "MET+MWT") return new top::METMWTSelector(param); + else if (toolname == "MET") return new top::METSelector(param); + else if (toolname == "MWT") return new top::MWTSelector(param); + else if (toolname == "MLLWIN") return new top::MLLWindow(param); + else if (toolname == "MLL") return new top::MLLSelector(param); + else if (toolname == "HT") return new top::HTSelector(param); else if (toolname == "NOBADMUON") - return new top::NoBadMuonSelector(); - else if (toolname == "OS") - return new top::OSLeptonSelector(); - else if (toolname == "OS_TIGHT") - return new top::OSLeptonTightSelector(); - else if (toolname == "SS") - return new top::SSLeptonSelector(); - else if (toolname == "SS_TIGHT") - return new top::SSLeptonTightSelector(); - else if (toolname == "INITIAL") - return new top::InitialSelector; - else if (toolname == "SAVE") - return new top::SaveEventSelector; - else if (toolname == "PRINT") - return new top::PrintEventSelector; - else if (toolname == "EXAMPLEPLOTS") - return new top::ExamplePlots(name, outputFile, wk, config); - else if (toolname == "JETFLAVORPLOTS") - return new top::JetFlavorPlots(name, outputFile, wk); - else if (toolname == "GRL") - return new top::GRLSelector(); - else if (toolname == "TRIGDEC") - return new top::TrigDecisionSelector(name,config); - else if (toolname == "TRIGMATCH") - return new top::TrigMatchSelector(name,config); - else if (toolname == "JETCLEAN") - return new top::JetCleaningSelector(param,config); - else if (toolname == "KLFITTER") - return new top::KLFitterSelector(param); - else if (toolname == "JET_N_GHOST") - return new top::JetNGhostSelector(param); - else if (toolname == "GOODCALO") - return new top::GoodCaloSelector(); - else if (toolname == "PRIVTX") - return new top::PrimaryVertexSelector(); - else if (toolname == "RECO_LEVEL") - return new top::RecoLevelSelector(); - else if (toolname == "PARTICLE_LEVEL") - return new top::ParticleLevelSelector(); - else if (toolname == "FAKESMMCONFIGS") - return new top::FakesMMConfigs(param); - else if (toolname == "RUN_NUMBER") - return new top::RunNumberSelector(param,config); + { + if(!config->useMuons()) + { + asg::msgUserCode::ATH_MSG_ERROR("NOBADMUON selection cannot be used if the muon collection is not defined"); + return 0; + } + return new top::NoBadMuonSelector(config); + } + else if (toolname == "OS") return new top::OSLeptonSelector(); + else if (toolname == "OS_TIGHT") return new top::OSLeptonTightSelector(); + else if (toolname == "SS") return new top::SSLeptonSelector(); + else if (toolname == "SS_TIGHT") return new top::SSLeptonTightSelector(); + else if (toolname == "INITIAL") return new top::InitialSelector; + else if (toolname == "SAVE") return new top::SaveEventSelector; + else if (toolname == "PRINT") return new top::PrintEventSelector; + else if (toolname == "EXAMPLEPLOTS") return new top::ExamplePlots(name, outputFile, wk, config); + else if (toolname == "JETFLAVORPLOTS") return new top::JetFlavorPlots(name, outputFile, param, config, wk); + else if (toolname == "JETRESPONSEPLOTS") return new top::JetResponsePlots(name, outputFile, param, config, wk); + else if (toolname == "JETFTAGEFFPLOTS") return new top::JetFtagEffPlots(name, outputFile, param, config, wk); + else if (toolname == "GRL") return new top::GRLSelector(); + else if (toolname == "GTRIGDEC") return new top::GlobalTrigDecisionSelector(); + else if (toolname == "GTRIGMATCH") return new top::GlobalTrigMatchSelector(); + else if (toolname == "TRIGDEC") return new top::TrigDecisionSelector(name, config); + else if (toolname == "TRIGDEC_LOOSE") return new top::TrigDecisionLooseSelector(name, config); + else if (toolname == "TRIGDEC_TIGHT") return new top::TrigDecisionTightSelector(name, config); + else if (toolname == "TRIGMATCH") return new top::TrigMatchSelector(name, config); + else if (toolname == "JETCLEAN") return new top::JetCleaningSelector(param, config); + else if (toolname == "TRACKJETCLEAN") return new top::TrackJetCleaningSelector(config); + else if (toolname == "KLFITTER") return new top::KLFitterSelector(param); + else if (toolname == "JET_N_GHOST") return new top::JetNGhostSelector(param); + else if (toolname == "GOODCALO") return new top::GoodCaloSelector(); + else if (toolname == "PRIVTX") return new top::PrimaryVertexSelector(); + else if (toolname == "RECO_LEVEL") return new top::RecoLevelSelector(); + else if (toolname == "PARTICLE_LEVEL") return new top::ParticleLevelSelector(); + else if (toolname == "FAKESMMCONFIGS") return new top::FakesMMConfigs(param); + else if (toolname == "RUN_NUMBER") return new top::RunNumberSelector(param, config); return nullptr; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrackJetCleaningSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrackJetCleaningSelector.cxx new file mode 100644 index 000000000000..4b63e31ac38b --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrackJetCleaningSelector.cxx @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/TrackJetCleaningSelector.h" +#include "TopEvent/EventTools.h" +#include "xAODJet/JetContainer.h" +#include "TopConfiguration/TopConfig.h" + +namespace top { + TrackJetCleaningSelector::TrackJetCleaningSelector(std::shared_ptr<top::TopConfig> config) : + m_config(config) { + } + + bool TrackJetCleaningSelector::apply(const top::Event& event) const { + // Selection is applied only if Variable-R track jets are used + if (m_config->sgKeyTrackJetsType() == "AntiKtVR30Rmax4Rmin02TrackJets") { + static SG::AuxElement::Accessor<char> acc_passDRcut("passDRcut"); + for (const xAOD::Jet* jet : event.m_trackJets) { + top::check(acc_passDRcut.isAvailable( + *jet), "passDRcut info not found in variable-R track jet. Needed for cleaning algorithm."); + if (!acc_passDRcut(*jet)) return false; + } + } + return true; + } + + std::string TrackJetCleaningSelector::name() const { + return "TRACKJETCLEAN"; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TreeManager.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TreeManager.cxx index 5cec34634396..b6a953bb90fd 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TreeManager.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TreeManager.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/TreeManager.h" @@ -8,135 +8,152 @@ #include <iostream> -namespace top { +#include "TopEventSelectionTools/MsgCategory.h" +using namespace TopEventSelectionTools; -TreeManager::TreeManager() : - m_name("NULL"), - m_tree(nullptr) { -} +namespace top { + TreeManager::TreeManager() : + m_name("NULL"), + m_tree(nullptr) { + } -TreeManager::TreeManager(const std::string& name, TFile* outputFile,const bool setAutoFlushZero) : + TreeManager::TreeManager(const std::string& name, TFile* outputFile, const int nEventAutoFlush, + const int basketSizePrimitive, const int basketSizeVector) : m_name(name), m_tree(nullptr) { outputFile->cd(); m_tree = new TTree(name.c_str(), "tree"); - if (setAutoFlushZero) { - // Fix for ANALYSISTO-44 - m_tree->SetAutoFlush(0); - m_tree->SetAutoSave(0); - } -} + m_tree->SetAutoFlush(nEventAutoFlush); + m_tree->SetAutoSave(0); + m_basketSizePrimitive = basketSizePrimitive; + m_basketSizeVector = basketSizeVector; + } -TreeManager::TreeManager(const TreeManager&& rhs) : + TreeManager::TreeManager(const TreeManager&& rhs) : m_name(std::move(rhs.m_name)), m_tree(std::move(rhs.m_tree)), m_outputVarPointers(std::move(rhs.m_outputVarPointers)) { -} + } -void TreeManager::initialize(const std::string& name, TFile* outputFile,const bool setAutoFlushZero) { + void TreeManager::initialize(const std::string& name, TFile* outputFile, const int nEventAutoFlush, + const int basketSizePrimitive, const int basketSizeVector) { if (m_tree) { - std::cerr << "Tried to call initialize, but tree is already created. Doing nothing." << std::endl; - return; + ATH_MSG_WARNING("Tried to call initialize, but tree is already created. Doing nothing."); + return; } outputFile->cd(); m_tree = new TTree(name.c_str(), "tree"); - if (setAutoFlushZero) { - // Fix for ANALYSISTO-44 - m_tree->SetAutoFlush(0); - m_tree->SetAutoSave(0); - } -} + m_tree->SetAutoFlush(nEventAutoFlush); + m_tree->SetAutoSave(0); + m_basketSizePrimitive = basketSizePrimitive; + m_basketSizeVector = basketSizeVector; + } -void TreeManager::fill() { + void TreeManager::fill() { m_tree->Fill(); -} + } -const std::string& TreeManager::name() const -{ - return m_name; -} - -const char* TreeManager::RootType(const char* typeid_type) { + const std::string& TreeManager::name() const { + return m_name; + } + const char* TreeManager::RootType(const char* typeid_type) { // Check that we received a reasonable input: - if( strlen( typeid_type ) != 1 ) { - // SLogger m_logger( "SCycleBaseNTuple" ); - // REPORT_ERROR( "Received a complex object description: " << typeid_type ); - // throw SError( "SCycleBaseNTuple::RootType received complex object " - // "description", SError::StopExecution ); + if (strlen(typeid_type) != 1) { + // SLogger m_logger( "SCycleBaseNTuple" ); + // REPORT_ERROR( "Received a complex object description: " << typeid_type ); + // throw SError( "SCycleBaseNTuple::RootType received complex object " + // "description", SError::StopExecution ); } // Do the hard-coded translation: - switch( typeid_type[ 0 ] ) { - + switch (typeid_type[ 0 ]) { case 'c': - return "B"; - break; + return "B"; + + break; + case 'h': - return "b"; - break; + return "b"; + + break; + case 's': - return "S"; - break; + return "S"; + + break; + case 't': - return "s"; - break; + return "s"; + + break; + case 'i': - return "I"; - break; + return "I"; + + break; + case 'j': - return "i"; - break; + return "i"; + + break; + case 'f': - return "F"; - break; + return "F"; + + break; + case 'd': - return "D"; - break; + return "D"; + + break; + case 'x': - return "L"; - break; + return "L"; + + break; + case 'y': - return "l"; - break; + return "l"; + + break; + case 'b': - return "O"; - break; + return "O"; + break; } return ""; -} - -const char* TreeManager::TypeidType(const char* root_type) { + } + const char* TreeManager::TypeidType(const char* root_type) { // Do the hard-coded translation: - if( ! strcmp( root_type, "Char_t" ) ) { - return "c"; - } else if( ! strcmp( root_type, "UChar_t" ) ) { - return "h"; - } else if( ! strcmp( root_type, "Short_t" ) ) { - return "s"; - } else if( ! strcmp( root_type, "UShort_t" ) ) { - return "t"; - } else if( ! strcmp( root_type, "Int_t" ) ) { - return "i"; - } else if( ! strcmp( root_type, "UInt_t" ) ) { - return "j"; - } else if( ! strcmp( root_type, "Float_t" ) ) { - return "f"; - } else if( ! strcmp( root_type, "Double_t" ) ) { - return "d"; - } else if( ! strcmp( root_type, "Long64_t" ) ) { - return "x"; - } else if( ! strcmp( root_type, "ULong64_t" ) ) { - return "y"; - } else if( ! strcmp( root_type, "Bool_t" ) ) { - return "b"; + if (!strcmp(root_type, "Char_t")) { + return "c"; + } else if (!strcmp(root_type, "UChar_t")) { + return "h"; + } else if (!strcmp(root_type, "Short_t")) { + return "s"; + } else if (!strcmp(root_type, "UShort_t")) { + return "t"; + } else if (!strcmp(root_type, "Int_t")) { + return "i"; + } else if (!strcmp(root_type, "UInt_t")) { + return "j"; + } else if (!strcmp(root_type, "Float_t")) { + return "f"; + } else if (!strcmp(root_type, "Double_t")) { + return "d"; + } else if (!strcmp(root_type, "Long64_t")) { + return "x"; + } else if (!strcmp(root_type, "ULong64_t")) { + return "y"; + } else if (!strcmp(root_type, "Bool_t")) { + return "b"; } return ""; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionLooseSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionLooseSelector.cxx new file mode 100644 index 000000000000..e40f0f127305 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionLooseSelector.cxx @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/TrigDecisionLooseSelector.h" +#include "TopEvent/Event.h" +#include "TopConfiguration/TopConfig.h" + +#include <sstream> +#include <iostream> + +namespace top { + TrigDecisionLooseSelector::TrigDecisionLooseSelector(const std::string& selectorName, + std::shared_ptr<top::TopConfig> config) { + m_triggers = config->allTriggers_Loose(selectorName); + } + + bool TrigDecisionLooseSelector::apply(const top::Event& event) const { + // this selector does nothing for non-loose events + bool loose = event.m_isLoose; + + if (!loose) return true; + + bool orOfAllTriggers(false); + for (const auto& trigger : m_triggers) { + bool passThisTrigger(false); + if (event.m_info->isAvailable<char>("TRIGDEC_" + trigger)) { + if (event.m_info->auxdataConst<char>("TRIGDEC_" + trigger) == 1) { + passThisTrigger = true; + } + } + + orOfAllTriggers |= passThisTrigger; + } + + return orOfAllTriggers; + } + + std::string TrigDecisionLooseSelector::name() const { + std::string name = "TRIGDEC_LOOSE "; + for (auto trigger : m_triggers) + name += " " + trigger; + + return name; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionSelector.cxx index d4155381ea18..0e3b06d80d06 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/TrigDecisionSelector.h" #include "TopEvent/Event.h" @@ -10,23 +10,16 @@ #include <iostream> namespace top { - - TrigDecisionSelector::TrigDecisionSelector(const std::string& selectorName,std::shared_ptr<top::TopConfig> config) - { - m_triggers = config->allTriggers(selectorName); - - std::cout<<"Triggers for selector = "<<selectorName<<std::endl; - for (auto s : m_triggers) { - std::cout << "--" << s << "--" << std::endl; - } - + TrigDecisionSelector::TrigDecisionSelector(const std::string& selectorName, std::shared_ptr<top::TopConfig> config) { + m_triggers = config->allTriggers_Tight(selectorName); + for (auto s: config->allTriggers_Loose(selectorName)) + if (std::find(m_triggers.begin(), m_triggers.end(), s) == m_triggers.end()) m_triggers.push_back(s); } - bool TrigDecisionSelector::apply(const top::Event& event) const - { - + bool TrigDecisionSelector::apply(const top::Event& event) const { bool orOfAllTriggers(false); - for (const auto& trigger : m_triggers){ + + for (const auto& trigger : m_triggers) { bool passThisTrigger(false); if (event.m_info->isAvailable<char>("TRIGDEC_" + trigger)) { if (event.m_info->auxdataConst<char>("TRIGDEC_" + trigger) == 1) { @@ -43,9 +36,8 @@ namespace top { std::string TrigDecisionSelector::name() const { std::string name = "TRIGDEC "; for (auto trigger : m_triggers) - name += " " + trigger; + name += " " + trigger; return name; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionTightSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionTightSelector.cxx new file mode 100644 index 000000000000..44d4c0df3e48 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigDecisionTightSelector.cxx @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopEventSelectionTools/TrigDecisionTightSelector.h" +#include "TopEvent/Event.h" +#include "TopConfiguration/TopConfig.h" + +#include <sstream> +#include <iostream> + +namespace top { + TrigDecisionTightSelector::TrigDecisionTightSelector(const std::string& selectorName, + std::shared_ptr<top::TopConfig> config) { + m_triggers = config->allTriggers_Tight(selectorName); + } + + bool TrigDecisionTightSelector::apply(const top::Event& event) const { + // this selector does nothing for loose events + bool loose = event.m_isLoose; + + if (loose) return true; + + bool orOfAllTriggers(false); + for (const auto& trigger : m_triggers) { + bool passThisTrigger(false); + if (event.m_info->isAvailable<char>("TRIGDEC_" + trigger)) { + if (event.m_info->auxdataConst<char>("TRIGDEC_" + trigger) == 1) { + passThisTrigger = true; + } + } + + orOfAllTriggers |= passThisTrigger; + } + + return orOfAllTriggers; + } + + std::string TrigDecisionTightSelector::name() const { + std::string name = "TRIGDEC_TIGHT "; + for (auto trigger : m_triggers) + name += " " + trigger; + + return name; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigMatchSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigMatchSelector.cxx index 2565d134261e..8f1b02428a1c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigMatchSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/TrigMatchSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopEventSelectionTools/TrigMatchSelector.h" #include "TopEvent/Event.h" @@ -10,37 +10,33 @@ #include <iostream> namespace top { - - TrigMatchSelector::TrigMatchSelector(const std::string& selectorName,std::shared_ptr<top::TopConfig> config) - { - m_electronTriggers = config->electronTriggers(selectorName); - m_muonTriggers = config->muonTriggers(selectorName); - m_tauTriggers = config->tauTriggers(selectorName); - - std::cout<<"Triggers Matching for selector = "<<selectorName<<std::endl; - for (auto s : m_electronTriggers) { - std::cout << "--Electron Trigger = " << s << "--" << std::endl; - } - for (auto s : m_muonTriggers) { - std::cout << "--Muon Trigger = " << s << "--" << std::endl; - } - for (auto s : m_tauTriggers) { - std::cout << "--Tau Trigger = " << s << "--" << std::endl; - } + TrigMatchSelector::TrigMatchSelector(const std::string& selectorName, std::shared_ptr<top::TopConfig> config) { + m_electronTriggers_Tight = config->electronTriggers_Tight(selectorName); + m_muonTriggers_Tight = config->muonTriggers_Tight(selectorName); + m_tauTriggers_Tight = config->tauTriggers_Tight(selectorName); + m_electronTriggers_Loose = config->electronTriggers_Loose(selectorName); + m_muonTriggers_Loose = config->muonTriggers_Loose(selectorName); + m_tauTriggers_Loose = config->tauTriggers_Loose(selectorName); } - bool TrigMatchSelector::apply(const top::Event& event) const - { + bool TrigMatchSelector::apply(const top::Event& event) const { + // different treatment depending if it's a loose or tight top::Event + bool loose = event.m_isLoose; + // if no trigger menu us associated to this selection, return true // no effect of TRIGMATCH if TRIGDEC wasn't used - if (m_electronTriggers.size()+m_muonTriggers.size()+m_tauTriggers.size() == 0) return true; - + if (!loose) { + if (m_electronTriggers_Tight.size() + m_muonTriggers_Tight.size() + m_tauTriggers_Tight.size() == 0) return true; + } else { + if (m_electronTriggers_Loose.size() + m_muonTriggers_Loose.size() + m_tauTriggers_Loose.size() == 0) return true; + } + bool trigMatch(false); - + // Loop over electrons for (const auto* const elPtr : event.m_electrons) { - // Loop over triggers - for (const auto& trigger : m_electronTriggers) { + // Loop over triggers; loose ones for loose events, tight ones for tight events + for (const auto& trigger : loose ? m_electronTriggers_Loose : m_electronTriggers_Tight) { std::string trig = "TRIGMATCH_" + trigger; if (elPtr->isAvailable<char>(trig)) { if (elPtr->auxdataConst<char>(trig) == 1) { @@ -49,12 +45,12 @@ namespace top { } } // decoration isAvailable } // Loop over triggers - } // Loop over electrons - + } // Loop over electrons + // Loop over muons for (const auto* const muPtr : event.m_muons) { - // Loop over triggers - for (const auto& trigger : m_muonTriggers) { + // Loop over triggers; loose ones for loose events, tight ones for tight events + for (const auto& trigger : loose ? m_muonTriggers_Loose : m_muonTriggers_Tight) { std::string trig = "TRIGMATCH_" + trigger; if (muPtr->isAvailable<char>(trig)) { if (muPtr->auxdataConst<char>(trig) == 1) { @@ -68,8 +64,8 @@ namespace top { // Loop over taus for (const auto* const tauPtr : event.m_tauJets) { - // Loop over triggers - for (const auto& trigger : m_tauTriggers) { + // Loop over triggers; loose ones for loose events, tight ones for tight events + for (const auto& trigger : loose ? m_tauTriggers_Loose : m_tauTriggers_Tight) { std::string trig = "TRIGMATCH_" + trigger; if (tauPtr->isAvailable<char>(trig)) { if (tauPtr->auxdataConst<char>(trig) == 1) { @@ -79,13 +75,12 @@ namespace top { } // decoration isAvailable } // Loop over triggers } // Loop over taus - + return trigMatch; } - + std::string TrigMatchSelector::name() const { std::string name = "TRIGMATCH"; return name; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/EventSelectorBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/EventSelectorBase.h index b673ca4cb9f8..2edf5a586fd4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/EventSelectorBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/EventSelectorBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTSELECTORBASE_H_ #define EVENTSELECTORBASE_H_ @@ -10,7 +10,6 @@ #include "TopParticleLevel/ParticleLevelEvent.h" namespace top { - /** * @brief This should apply event-level cuts and perform simple plotting on * top::Event objects. @@ -18,8 +17,8 @@ namespace top { * This is the base class, and all classes that do stuff * to events should inherit from it. */ -class EventSelectorBase { -public: + class EventSelectorBase { + public: /** * @brief Default constructor, doesn't do anything. */ @@ -43,7 +42,7 @@ public: /** * @brief Assignment is not allowed. */ - EventSelectorBase& operator=(const EventSelectorBase &) = delete; + EventSelectorBase& operator = (const EventSelectorBase&) = delete; /** * @brief This does stuff based on the information in an event. @@ -71,7 +70,7 @@ public: * @param true if the event should be kept (i.e. it passed the selector * criteria), false otherwise. */ - virtual bool applyParticleLevel( const top::ParticleLevelEvent & ) const { return true; } + virtual bool applyParticleLevel(const top::ParticleLevelEvent&) const {return true;} /** * @brief A human readable name. @@ -80,8 +79,7 @@ public: * implemented for each tool. */ virtual std::string name() const = 0; -}; - + }; } //namespace top #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ExamplePlots.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ExamplePlots.h index d8047e737057..27f7b3eb0acd 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ExamplePlots.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ExamplePlots.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef EXAMPLEPLOTS_H_ #define EXAMPLEPLOTS_H_ @@ -11,18 +11,18 @@ class TFile; namespace EL { -class Worker; + class Worker; } namespace top { -class TopConfig; + class TopConfig; /** * @brief An example of how to quickly make some plots at a certain point in * the cutflow. */ -class ExamplePlots : public EventSelectorBase { -public: + class ExamplePlots: public EventSelectorBase { + public: /** * @brief Setup some example plots. * @@ -34,7 +34,8 @@ public: * so that we can attach the files. * @param wk Only used by EventLoop, ok as nullptr as default. */ - ExamplePlots(const std::string& name, TFile* outputFile, EL::Worker* wk = nullptr, std::shared_ptr<top::TopConfig> config = nullptr); + ExamplePlots(const std::string& name, TFile* outputFile, EL::Worker* wk = nullptr, + std::shared_ptr<top::TopConfig> config = nullptr); /** * @brief Fill the histograms. @@ -49,20 +50,18 @@ public: * @return The word EXAMPLEPLOTS. */ std::string name() const override; - -private: + private: ///File units are MeV and normally people like plots in GeV. static const double toGeV; ///Easy access to histograms. PlotManager m_hists; - + // Nominal hash value std::size_t m_nominalHashValue; std::shared_ptr<top::TopConfig> m_config; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/FakesMMConfigs.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/FakesMMConfigs.h index f7788592963b..d4276e47a66a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/FakesMMConfigs.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/FakesMMConfigs.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef FAKESMMCONFIG_H_ #define FAKESMMCONFIG_H_ @@ -10,13 +10,12 @@ class TFile; namespace top { - /** * @brief An example of how to quickly make some plots at a certain point in * the cutflow. */ -class FakesMMConfigs : public EventSelectorBase { -public: + class FakesMMConfigs: public EventSelectorBase { + public: /** * @brief Setup the matrix-method configurations. * @@ -40,12 +39,10 @@ public: * @return The MM weight configurations. */ std::vector<std::string> configurations() const {return m_configurations;}; - -private: + private: // Nominal hash value std::vector<std::string> m_configurations; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GRLSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GRLSelector.h index 8d3a1637ce85..dd9d960f4993 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GRLSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GRLSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef GRLSELECTOR_H_ #define GRLSELECTOR_H_ @@ -8,32 +8,30 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** - * @brief Select events if they are on a GRL specified by the parameter - * GRLFilename in the configuration file. MC simulation events are always - * accepted. - */ - class GRLSelector : public EventSelectorBase { - public: - GRLSelector(); - virtual ~GRLSelector(){}; - - /** - * @brief MC simulation passes, data is checked against the GRL. - * - * @param event The event in question - * @return True for MC simulation, or if the data event is on the GRL. - */ - virtual bool apply(const top::Event& event) const override; - - /** - * @brief The name of the tool. - * - * @return The name of the tool for humans to see. - */ - std::string name() const override; - + * @brief Select events if they are on a GRL specified by the parameter + * GRLFilename in the configuration file. MC simulation events are always + * accepted. + */ + class GRLSelector: public EventSelectorBase { + public: + GRLSelector(); + virtual ~GRLSelector() {}; + + /** + * @brief MC simulation passes, data is checked against the GRL. + * + * @param event The event in question + * @return True for MC simulation, or if the data event is on the GRL. + */ + virtual bool apply(const top::Event& event) const override; + + /** + * @brief The name of the tool. + * + * @return The name of the tool for humans to see. + */ + std::string name() const override; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GlobalTrigDecisionSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GlobalTrigDecisionSelector.h new file mode 100644 index 000000000000..a29bd4e1caee --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GlobalTrigDecisionSelector.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef GLOBALTRIGDECISIONSELECTOR_H_ +#define GLOBALTRIGDECISIONSELECTOR_H_ + +#include "TopEventSelectionTools/EventSelectorBase.h" + +#include <memory> + +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +#include "TriggerAnalysisInterfaces/ITrigGlobalEfficiencyCorrectionTool.h" + + +namespace top { + class Event; + class TopConfig; + + class GlobalTrigDecisionSelector: public EventSelectorBase { + public: + GlobalTrigDecisionSelector(); + + bool apply(top::Event const& event) const override; + std::string name() const override; + private: + mutable ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerSF; + mutable ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerSFLoose; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GlobalTrigMatchSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GlobalTrigMatchSelector.h new file mode 100644 index 000000000000..35051c8a6a95 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GlobalTrigMatchSelector.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef GLOBALTRIGMATCHSELECTOR_H_ +#define GLOBALTRIGMATCHSELECTOR_H_ + +#include "TopEventSelectionTools/EventSelectorBase.h" + +#include <memory> + +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +#include "TriggerAnalysisInterfaces/ITrigGlobalEfficiencyCorrectionTool.h" + + +namespace top { + class Event; + + class GlobalTrigMatchSelector: public EventSelectorBase { + public: + GlobalTrigMatchSelector(); + + bool apply(top::Event const& event) const override; + + std::string name() const override; + private: + mutable ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerSF; + mutable ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerSFLoose; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GoodCaloSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GoodCaloSelector.h index 76ea93cf59ef..5cde1f5cd288 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GoodCaloSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/GoodCaloSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef GOODCALOSELECTOR_H_ #define GOODCALOSELECTOR_H_ @@ -8,31 +8,29 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** - * @brief Select data events with good Tile and LAr calorimeters. - * MC simulation events are always accepted. - */ - class GoodCaloSelector : public EventSelectorBase { - public: - GoodCaloSelector(); - virtual ~GoodCaloSelector(){}; - - /** - * @brief MC simulation passes, data is checked against the GRL. - * - * @param event The event in question - * @return True for MC simulation, or if the data event is on the GRL. - */ - virtual bool apply(const top::Event& event) const override; - - /** - * @brief The name of the tool. - * - * @return The name of the tool for humans to see. - */ - std::string name() const override; - + * @brief Select data events with good Tile and LAr calorimeters. + * MC simulation events are always accepted. + */ + class GoodCaloSelector: public EventSelectorBase { + public: + GoodCaloSelector(); + virtual ~GoodCaloSelector() {}; + + /** + * @brief MC simulation passes, data is checked against the GRL. + * + * @param event The event in question + * @return True for MC simulation, or if the data event is on the GRL. + */ + virtual bool apply(const top::Event& event) const override; + + /** + * @brief The name of the tool. + * + * @return The name of the tool for humans to see. + */ + std::string name() const override; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/HTSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/HTSelector.h index a6ff79cc18c7..11c69bc7e2a2 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/HTSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/HTSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef HTSELECTOR_H_ #define HTSELECTOR_H_ @@ -8,21 +8,19 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief Apply a cut on the event HT. * * The calculation is done by top::ht(). */ -class HTSelector : public SignValueSelector { -public: + class HTSelector: public SignValueSelector { + public: explicit HTSelector(const std::string& params); virtual bool apply(const top::Event& event) const override; virtual bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/InitialSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/InitialSelector.h index 3cc955122487..37cbb8f32702 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/InitialSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/InitialSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef INITIALSELECTOR_H_ #define INITIALSELECTOR_H_ @@ -8,14 +8,13 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** * @brief A cut that accepts all events, more useful than you might think. * * Very simple tool that accepts all events so you can see the starting * number of events in the cutflow. */ -class InitialSelector : public EventSelectorBase { + class InitialSelector: public EventSelectorBase { /** * @brief Accept every event * @@ -29,8 +28,7 @@ class InitialSelector : public EventSelectorBase { * @return The word INITIAL. */ virtual std::string name() const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetCleaningSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetCleaningSelector.h index f86e0e401089..dac38c57fc44 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetCleaningSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetCleaningSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ #ifndef JETCLEANINGSELECTOR_H_ #define JETCLEANINGSELECTOR_H_ @@ -10,6 +10,7 @@ #include "AsgTools/AsgTool.h" #include "AsgTools/ToolHandle.h" #include "JetInterface/IJetSelector.h" +#include "JetSelectorTools/IEventCleaningTool.h" namespace top { class TopConfig; @@ -24,8 +25,8 @@ namespace top { * passed the event selection are marked as bad. Probably should check that * this is okay after overlap removal. */ -class JetCleaningSelector : public EventSelectorBase { -public: + class JetCleaningSelector: public EventSelectorBase { + public: /** * @brief Setup the jet group's cleaning tool. * @@ -50,19 +51,30 @@ public: * at. */ std::string name() const override; + private: + /** + * @brief A helper function to check if the event passes BadBatman cleaning + * in a specified range (from config) of RunNUmbers + * + * @return true if event passes + */ + bool checkBadBatman(const top::Event& event) const; -private: ///The jet cleaning tools ToolHandle<IJetSelector> m_jetCleaningToolLooseBad; - ToolHandle<IJetSelector> m_jetCleaningToolTightBad; + ToolHandle<IJetSelector> m_jetCleaningToolTightBad; + + ///The jet event cleaning tools + ToolHandle<ECUtils::IEventCleaningTool> m_jetEventCleaningToolLooseBad; + ToolHandle<ECUtils::IEventCleaningTool> m_jetEventCleaningToolTightBad; ///The level to configure to, so we can print it in the name. std::string m_level; bool m_useLooseBad; + bool m_useEventLevelJetCleaningTool; std::shared_ptr<top::TopConfig> m_config; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetFlavorPlots.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetFlavorPlots.h index d0f6f11c138c..383a2547715e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetFlavorPlots.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetFlavorPlots.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPEVENTSELECTIONTOOLS_JETFLAVORPLOTS_H_ #define TOPEVENTSELECTIONTOOLS_JETFLAVORPLOTS_H_ @@ -9,60 +9,101 @@ #include "TopEventSelectionTools/EventSelectorBase.h" #include "TopEventSelectionTools/PlotManager.h" +#include "PMGTools/PMGTruthWeightTool.h" class TFile; namespace EL { -class Worker; + class Worker; } namespace top { + class TopConfig; /** * @brief An example of how to quickly make some plots at a certain point in * the cutflow. */ -class JetFlavorPlots : public EventSelectorBase { - public: - /** - * @brief Setup some example plots. - * - * Add a bunch of histograms. - * - * @param name The name of the directory to store histograms in, in the - * output file. e.g. you might have ee, mumu and emu. - * @param outputFile The output file. Needs setting up at the very start - * so that we can attach the files. - * @param wk Only used by EventLoop, ok as nullptr as default. - */ - JetFlavorPlots(const std::string& name, TFile* outputFile, - EL::Worker* wk = nullptr); - - /** - * @brief Fill the histograms. - * - * @return True because it doesn't select any events. - */ - bool apply(const top::Event& event) const override; - - /** - * @brief Return the name for the cutflow table. - * - * @return The word JETFLAVORPLOTS. - */ - std::string name() const override; - - private: - // File units are MeV and normally people like plots in GeV. - static const double toGeV; - - // Easy access to histograms. - PlotManager m_hists; - - // Nominal hash value - std::size_t m_nominalHashValue; -}; + class JetFlavorPlots: public EventSelectorBase { + public: + /** + * @brief Setup some example plots. + * + * Add a bunch of histograms. + * + * @param name The name of the directory to store histograms in, in the + * output file. e.g. you might have ee, mumu and emu. + * @param outputFile The output file. Needs setting up at the very start + * so that we can attach the files. + * @param params The arguments, e.g. for the binning of the plots. + * @param config Instance of TopConfig + * @param wk Only used by EventLoop, ok as nullptr as default. + */ + JetFlavorPlots(const std::string& name, TFile* outputFile, const std::string& params, + std::shared_ptr<top::TopConfig> config, + EL::Worker* wk = nullptr); + + /** + * @brief Fill the histograms. + * + * @return True because it doesn't select any events. + */ + bool apply(const top::Event& event) const override; + + /** + * @brief Return the name for the cutflow table. + * + * @return The word JETFLAVORPLOTS. + */ + std::string name() const override; + private: + // File units are MeV and normally people like plots in GeV. + static const double toGeV; + + // Easy access to histograms. + std::shared_ptr<PlotManager> m_hists = nullptr; + std::shared_ptr<PlotManager> m_hists_Loose = nullptr; + std::shared_ptr<PlotManager> m_hists_RadHigh = nullptr; + std::shared_ptr<PlotManager> m_hists_RadHigh_Loose = nullptr; + std::shared_ptr<PlotManager> m_hists_RadLow = nullptr; + std::shared_ptr<PlotManager> m_hists_RadLow_Loose = nullptr; + + // Nominal hash value + std::size_t m_nominalHashValue; + + // for detailed plots (e.g. vs. Njets) + bool m_detailed; + + // to choose between radiation varied and nominal plots + bool m_doNominal; + bool m_doRadHigh; + bool m_doRadLow; + + // pT and eta bin edges, separated by colons + std::string m_ptBins; + std::string m_etaBins; + + // max value for nJets, when doing the plots vs. nJets + int m_nJetsMax; + + // name of the jet collection - this is needed for the names of the histograms + std::string m_jetCollection; + + // shared pointed to instance of TopConfig + std::shared_ptr<top::TopConfig> m_config; + + //PMGTruthWeights + PMGTools::PMGTruthWeightTool* m_PMGTruthWeights; + // function to translate the binnings into vector of bin edges + void formatBinning(const std::string& str, std::vector<double>& binEdges); + //helper function to book histograms + void BookHistograms(std::shared_ptr<PlotManager> h_ptr, std::vector<double> ptBins, std::vector<double> etaBins); + //helper function to fill histograms + void FillHistograms(std::shared_ptr<PlotManager> h_ptr, double w_event, const top::Event& event) const; + //This is to suppress excessive printout + mutable std::atomic<bool> m_throwwarningPMG; + }; } // namespace top #endif // TOPEVENTSELECTIONTOOLS_JETFLAVORPLOTS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetFtagEffPlots.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetFtagEffPlots.h new file mode 100644 index 000000000000..b943cceed7d3 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetFtagEffPlots.h @@ -0,0 +1,123 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TOPEVENTSELECTIONTOOLS_JETFTAGEFFPLOTS_H_ +#define TOPEVENTSELECTIONTOOLS_JETFTAGEFFPLOTS_H_ + +#include <string> + +#include "TopEventSelectionTools/EventSelectorBase.h" +#include "TopEventSelectionTools/PlotManager.h" +#include "PMGTools/PMGTruthWeightTool.h" +#include <AsgTools/AnaToolHandle.h> +#include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h" +#include "TopCorrections/ScaleFactorRetriever.h" +#include "PMGTools/PMGTruthWeightTool.h" + + +class TFile; + +namespace EL { + class Worker; +} + +namespace { + enum class WEIGHTTYPE { + MURUP, MURDOWN, MUFUP, MUFDOWN, VAR3CUP, VAR3CDOWN, FSRUP, FSRDOWN + }; +} + +namespace top { + class TopConfig; + +/** + * @brief An example of how to quickly make some plots at a certain point in + * the cutflow. + */ + class JetFtagEffPlots: public EventSelectorBase { + public: + JetFtagEffPlots(const std::string& name, TFile* outputFile, const std::string& params, + std::shared_ptr<top::TopConfig> config, + EL::Worker* wk = nullptr); + + + bool apply(const top::Event& event) const override; + + + std::string name() const override; + private: + // File units are MeV and normally people like plots in GeV. + static const double toGeV; + + // Easy access to histograms. + std::shared_ptr<PlotManager> m_hists = nullptr; + std::shared_ptr<PlotManager> m_hists_muRup = nullptr; + std::shared_ptr<PlotManager> m_hists_muRdown = nullptr; + std::shared_ptr<PlotManager> m_hists_muFup = nullptr; + std::shared_ptr<PlotManager> m_hists_muFdown = nullptr; + std::shared_ptr<PlotManager> m_hists_Var3cup = nullptr; + std::shared_ptr<PlotManager> m_hists_Var3cdown = nullptr; + std::shared_ptr<PlotManager> m_hists_FSRup = nullptr; + std::shared_ptr<PlotManager> m_hists_FSRdown = nullptr; + + + // Nominal hash value + std::size_t m_nominalHashValue; + + std::string m_CDIfile; + + bool m_fill_total_hists; + + //optional suffix you can add to your histogram + std::string m_histogram_suffix; + bool m_dont_use_event_weight; + bool m_use_track_jets; + bool m_doNominal; + bool m_doMuRup; + bool m_doMuRdown; + bool m_doMuFup; + bool m_doMuFdown; + bool m_doVar3cup; + bool m_doVar3cdown; + bool m_doFSRup; + bool m_doFSRdown; + + // pT and eta bin edges + std::string m_ptBins; + std::string m_etaBins; + + float m_max_pT; + float m_min_pT; + int m_N_pT_bins; + + float m_max_Eta; + float m_min_Eta; + int m_N_Eta_bins; + + // name of the jet collection - this is needed for the names of the histograms + std::string m_jetCollection; + std::string m_WP; + std::string m_tagger; + // shared pointed to instance of TopConfig + std::shared_ptr<top::TopConfig> m_config; + + + asg::AnaToolHandle<IBTaggingSelectionTool> m_selection_tool; + + PMGTools::PMGTruthWeightTool* m_PMGTruthWeights; + + top::ScaleFactorRetriever* m_sfRetriever; + + // function to translate the binnings into vector of bin edges + void formatBinning(const std::string& str, std::vector<double>& binEdges); + + //helper function to fill histograms + void FillHistograms(std::shared_ptr<PlotManager> h_ptr, double w_event, const top::Event& event) const; + + /// A helper function to get the correct truth weight + float GetPMGTruthWeight(WEIGHTTYPE type) const; + }; +} // namespace top + +#endif // TOPEVENTSELECTIONTOOLS_JETFTAGEFFPLOTS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetNGhostSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetNGhostSelector.h index 7a4756df830e..abe630f45409 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetNGhostSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetNGhostSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: JetNGhostSelector.h // Description: @@ -13,48 +13,45 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - - class JetNGhostSelector : public SignValueSelector { - public: - explicit JetNGhostSelector(const std::string& params); - - /*! - * @brief Apply on reco level. - * There is no sensible application for a ghost tagging selector at reco - * level, hence return true for any input. - */ - bool apply(const top::Event&) const override { return true; } - - /*! - * @brief Apply on particle level. - * Will calculate the number of ghost tagged jet for the requested type. - * Will return true if that number is equal to order larger than the cut - * value, false otherwise. - */ - bool applyParticleLevel(const top::ParticleLevelEvent& plEvent) const override; - - std::string name() const override; - private: - std::string parseType( const std::string & params ); - - enum Type { - c = static_cast<int>( 'c' ), - C = static_cast<int>( 'C' ), - b = static_cast<int>( 'b' ), - B = static_cast<int>( 'B' ), - t = static_cast<int>( 't' ), - W = static_cast<int>( 'W' ), - Z = static_cast<int>( 'Z' ), - H = static_cast<int>( 'H' ), - tau, - Invalid - }; - Type m_type; - - std::string m_name; + class JetNGhostSelector: public SignValueSelector { + public: + explicit JetNGhostSelector(const std::string& params); + + /*! + * @brief Apply on reco level. + * There is no sensible application for a ghost tagging selector at reco + * level, hence return true for any input. + */ + bool apply(const top::Event&) const override {return true;} + + /*! + * @brief Apply on particle level. + * Will calculate the number of ghost tagged jet for the requested type. + * Will return true if that number is equal to order larger than the cut + * value, false otherwise. + */ + bool applyParticleLevel(const top::ParticleLevelEvent& plEvent) const override; + + std::string name() const override; + private: + std::string parseType(const std::string& params); + + enum Type { + c = static_cast<int>('c'), + C = static_cast<int>('C'), + b = static_cast<int>('b'), + B = static_cast<int>('B'), + t = static_cast<int>('t'), + W = static_cast<int>('W'), + Z = static_cast<int>('Z'), + H = static_cast<int>('H'), + tau, + Invalid }; + Type m_type; - + std::string m_name; + }; } #endif /* _JETNGHOSTSELECTOR_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetResponsePlots.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetResponsePlots.h new file mode 100644 index 000000000000..ba9832783ba6 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/JetResponsePlots.h @@ -0,0 +1,96 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TOPEVENTSELECTIONTOOLS_JETRESPONSEPLOTS_H_ +#define TOPEVENTSELECTIONTOOLS_JETRESPONSEPLOTS_H_ + +#include "TopEventSelectionTools/EventSelectorBase.h" +#include "TopEventSelectionTools/PlotManager.h" +#include "PMGAnalysisInterfaces/IPMGTruthWeightTool.h" +#include "PMGTools/PMGTruthWeightTool.h" +#include "AsgTools/ToolHandle.h" +#include "AsgTools/ToolHandleArray.h" +#include "AsgTools/AnaToolHandle.h" + +#include <string> + +class TFile; + +namespace EL { + class Worker; +} + +namespace top { + class TopConfig; + +/** + * @brief An example of how to quickly make some plots at a certain point in + * the cutflow. + */ + class JetResponsePlots: public EventSelectorBase { + public: + /** + * @brief Setup some example plots. + * + * Add a bunch of histograms. + * + * @param name The name of the directory to store histograms in, in the + * output file. e.g. you might have ee, mumu and emu. + * @param outputFile The output file. Needs setting up at the very start + * so that we can attach the files. + * @param params The arguments, e.g. for the binning of the plots. + * @param config Instance of TopConfig + * @param wk Only used by EventLoop, ok as nullptr as default. + */ + JetResponsePlots(const std::string& name, + TFile* outputFile, + const std::string& params, + std::shared_ptr<top::TopConfig> config, + EL::Worker* wk = nullptr); + + /** + * @brief Fill the histograms. + * + * @return True because it doesn't select any events. + */ + bool apply(const top::Event& event) const override; + + /** + * @brief Helper function to fill the histograms + * + */ + void FillHistograms(const double w_event, + const top::Event& event) const; + + /** + * @brief Return the name for the cutflow table. + * + * @return The word JETRESPONSEPLOTS. + */ + std::string name() const override; + private: + + // Easy access to histograms. + std::shared_ptr<PlotManager> m_hists; + + // Nominal hash value + std::size_t m_nominalHashValue; + + // deltaR used for jet matching + float m_deltaR; + int m_bins; + float m_min; + float m_max; + std::vector<double> m_ptBinning; + + // shared pointed to instance of TopConfig + std::shared_ptr<top::TopConfig> m_config; + + //PMGTruthWeights + ToolHandle<PMGTools::IPMGTruthWeightTool> m_PMGTruthWeights; + + }; +} // namespace top + +#endif // TOPEVENTSELECTIONTOOLS_JETRESPONSEPLOTS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/KLFitterSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/KLFitterSelector.h index 98536f770bbb..e7fcc3452e50 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/KLFitterSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/KLFitterSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: KLFitterSelector.h 665436 2015-05-06 19:10:23Z morrisj $ #ifndef ANALYSISTOP_TOPEVENTSELECTIONTOOLS_KLFITTERSELECTOR_H @@ -8,19 +8,18 @@ #include "TopEventSelectionTools/SignValueSelector.h" -namespace top{ - +namespace top { /** * @brief Apply a cut on the KLFitter Results */ - + // Forward declare class Event; - - class KLFitterSelector : public SignValueSelector { - public: - explicit KLFitterSelector(const std::string& params); - bool apply(const top::Event&) const override; + + class KLFitterSelector: public SignValueSelector { + public: + explicit KLFitterSelector(const std::string& params); + bool apply(const top::Event&) const override; }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/METMWTSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/METMWTSelector.h index 6cea661a59e3..888150279010 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/METMWTSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/METMWTSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef METMWTSELECTOR_H_ #define METMWTSELECTOR_H_ @@ -8,19 +8,17 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief Allows a cut on the sum of MET and MWT. */ -class METMWTSelector : public SignValueSelector { -public: + class METMWTSelector: public SignValueSelector { + public: explicit METMWTSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/METSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/METSelector.h index 4d3dd53103bc..5d3fcdf9bfb9 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/METSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/METSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef METSELECTOR_H_ #define METSELECTOR_H_ @@ -8,19 +8,17 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief Apply a cut on the event MET. */ -class METSelector : public SignValueSelector { -public: + class METSelector: public SignValueSelector { + public: explicit METSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MLLSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MLLSelector.h index 6efd0903f6e8..adb1fe3e88d8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MLLSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MLLSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef MLLSELECTOR_H_ #define MLLSELECTOR_H_ @@ -8,20 +8,18 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief Put a cut on the invariant mass of two same flavour leptons. If you * want to veto a window (say for the Z mass) you instead want MLLWindow. */ -class MLLSelector : public SignValueSelector { -public: + class MLLSelector: public SignValueSelector { + public: explicit MLLSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MLLWindowSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MLLWindowSelector.h index 5721b9d9ab92..143e260f6fe6 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MLLWindowSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MLLWindowSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef MLLWINDOW_H_ #define MLLWINDOW_H_ @@ -8,12 +8,11 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief Reject events in the invariant mass (of two charged leptons) window. */ -class MLLWindow : public EventSelectorBase { -public: + class MLLWindow: public EventSelectorBase { + public: explicit MLLWindow(std::string params); bool apply(const top::Event& event) const override; @@ -21,12 +20,10 @@ public: bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; std::string name() const override; - -private: + private: double m_cutvalue0; double m_cutvalue1; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV2c10Selector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV2c10Selector.h index fe1af683f59f..c1972f98f4bc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV2c10Selector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV2c10Selector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef MV2C10SELECTOR_H_ #define MV2C10SELECTOR_H_ @@ -8,12 +8,11 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief Should count how many jets have an mv2c10 weight above some value. */ -class MV2c10Selector : public SignValueSelector { -public: + class MV2c10Selector: public SignValueSelector { + public: explicit MV2c10Selector(const std::string& params); /** @@ -28,8 +27,7 @@ public: * @return True if the event passes the cut, false otherwise. */ bool apply(const top::Event& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MWTSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MWTSelector.h index 6658fe250f46..0f790a6e875d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MWTSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MWTSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef MWTSELECTOR_H_ #define MWTSELECTOR_H_ @@ -8,20 +8,18 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief Apply a cut on the transverse W mass (taken from the electron or muon * and MET). */ -class MWTSelector : public SignValueSelector { -public: + class MWTSelector: public SignValueSelector { + public: explicit MWTSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MsgCategory.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MsgCategory.h new file mode 100644 index 000000000000..07ee615c2a72 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MsgCategory.h @@ -0,0 +1,10 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#ifndef TOPEVENTSELECTIONTOOLS_MSG_CATEGORY_H_ +#define TOPEVENTSELECTIONTOOLS_MSG_CATEGORY_H_ +#include <AsgMessaging/MessageCheck.h> + +ANA_MSG_HEADER(TopEventSelectionTools) + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronNMuonSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronNMuonSelector.h index 97249a0a86a6..55a6fab7e00b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronNMuonSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronNMuonSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NELECTRONNMUONSELECTOR_H_ #define NELECTRONNMUONSELECTOR_H_ @@ -8,12 +8,11 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief To accept an event based on a check of electrons and muons. */ -class NElectronNMuonSelector : public SignValueSelector { -public: + class NElectronNMuonSelector: public SignValueSelector { + public: /** * @brief Select events based on multiplicity, which should be an integer. */ @@ -27,13 +26,12 @@ public: bool apply(const top::Event& event) const override; /*! - * @brief The 'OR' of a check against electrons and muons. + * @brief The 'OR' of a check against electrons and muons. * * @return True to keep the event, false otherwise. */ bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronNMuonTightSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronNMuonTightSelector.h index d3f72175d8d9..62dd308bbb1f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronNMuonTightSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronNMuonTightSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NELECTRONNMUONTIGHTSELECTOR_H_ #define NELECTRONNMUONTIGHTSELECTOR_H_ @@ -8,13 +8,12 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief To accept an event based on a check of tight electrons and muons. * This is identical to NElectronNMuonSelector in the case of tight selection, so only relevant for loose selection. */ -class NElectronNMuonTightSelector : public SignValueSelector { -public: + class NElectronNMuonTightSelector: public SignValueSelector { + public: /** * @brief Select events based on multiplicity, which should be an integer. */ @@ -28,13 +27,12 @@ public: bool apply(const top::Event& event) const override; /*! - * @brief The 'OR' of a check against electrons and muons. + * @brief The 'OR' of a check against electrons and muons. * * @return True to keep the event, false otherwise. */ bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronSelector.h index 15b89e60b31f..f21d3600682a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NELECTRONSELECTOR_H_ #define NELECTRONSELECTOR_H_ @@ -8,19 +8,17 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief A tool that selects events with a certain number of good electrons. */ -class NElectronSelector : public SignValueSelector { -public: + class NElectronSelector: public SignValueSelector { + public: explicit NElectronSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronTightSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronTightSelector.h index 1c71d916e2d0..0c767a2c7a64 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronTightSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NElectronTightSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NELECTRONTIGHTSELECTOR_H_ #define NELECTRONTIGHTSELECTOR_H_ @@ -8,20 +8,18 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief A tool that selects events with a certain number of good tight electrons. * This is identical to NElectronSelector in the case of tight selection, so only relevant for loose selection. */ -class NElectronTightSelector : public SignValueSelector { -public: + class NElectronTightSelector: public SignValueSelector { + public: explicit NElectronTightSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NFwdElectronSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NFwdElectronSelector.h new file mode 100644 index 000000000000..fe4f87e38d55 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NFwdElectronSelector.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef NFWDELECTRONSELECTOR_H_ +#define NFWDELECTRONSELECTOR_H_ + +#include "TopEventSelectionTools/SignValueSelector.h" + +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" +#include "AsgTools/AnaToolHandle.h" + +namespace top { +/** + * @brief A tool that selects events with a certain number of good forward electrons. + */ + class NFwdElectronSelector: public SignValueSelector { + public: + explicit NFwdElectronSelector(const std::string& params); + + bool apply(const top::Event& event) const override; + + bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NFwdElectronTightSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NFwdElectronTightSelector.h new file mode 100644 index 000000000000..9fa056f75736 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NFwdElectronTightSelector.h @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef NFWDELECTRONTIGHTSELECTOR_H_ +#define NFWDELECTRONTIGHTSELECTOR_H_ + +#include "TopEventSelectionTools/SignValueSelector.h" + +namespace top { +/** + * @brief A tool that selects events with a certain number of good tight electrons. + * This is identical to NElectronSelector in the case of tight selection, so only relevant for loose selection. + */ + class NFwdElectronTightSelector: public SignValueSelector { + public: + explicit NFwdElectronTightSelector(const std::string& params); + + bool apply(const top::Event& event) const override; + + bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NJetBtagSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NJetBtagSelector.h index 1c440e79d239..045e92c31d54 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NJetBtagSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NJetBtagSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NJETBTAGSELECTOR_H_ #define NJETBTAGSELECTOR_H_ @@ -13,13 +13,16 @@ namespace top { /** * @brief A tool that selects events with a certain number of good jets. */ -class NJetBtagSelector : public SignValueSelector { -public: - explicit NJetBtagSelector(const std::string& params,std::shared_ptr<top::TopConfig> config); + class NJetBtagSelector: public SignValueSelector { + public: + explicit NJetBtagSelector(const std::string& params, std::shared_ptr<top::TopConfig> config, bool doTrackJets); bool apply(const top::Event& event) const override; -}; + const std::string getFullCutName() {return SignValueSelector::valueStringDelimReplace();}; + private: + bool m_doTrackJets; + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NJetSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NJetSelector.h index 1b66a8f7a080..01fc1306bf72 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NJetSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NJetSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NJETSELECTOR_H_ #define NJETSELECTOR_H_ @@ -8,19 +8,17 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief A tool that selects events with a certain number of good jets. */ -class NJetSelector : public SignValueSelector { -public: + class NJetSelector: public SignValueSelector { + public: explicit NJetSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NLargeJetSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NLargeJetSelector.h index 5aff1598bf69..8bbc365deb28 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NLargeJetSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NLargeJetSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NLARGEJETSELECTOR_H_ #define NLARGEJETSELECTOR_H_ @@ -9,17 +9,13 @@ namespace top { - - class NLargeJetSelector : public top::SignValueSelector { - + class NLargeJetSelector: public top::SignValueSelector { public: - explicit NLargeJetSelector(const std::string& params); bool apply(const top::Event& event) const override; - bool applyParticleLevel( const top::ParticleLevelEvent & ) const override; + bool applyParticleLevel(const top::ParticleLevelEvent&) const override; }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NMuonSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NMuonSelector.h index 6dedd2cf3af6..9d8dc6368c47 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NMuonSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NMuonSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NMUONSELECTOR_H_ #define NMUONSELECTOR_H_ @@ -8,19 +8,17 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief A tool that selects events with a certain number of good muons. */ -class NMuonSelector : public SignValueSelector { -public: + class NMuonSelector: public SignValueSelector { + public: explicit NMuonSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NMuonTightSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NMuonTightSelector.h index 196485c6aa1d..af3b37db65e8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NMuonTightSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NMuonTightSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NMUONTIGHTSELECTOR_H_ #define NMUONTIGHTSELECTOR_H_ @@ -8,20 +8,18 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief A tool that selects events with a certain number of good tight muons. * This is identical to NMuonSelector in the case of tight selection, so only relevant for loose selection. */ -class NMuonTightSelector : public SignValueSelector { -public: + class NMuonTightSelector: public SignValueSelector { + public: explicit NMuonTightSelector(const std::string& params); bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NPhotonSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NPhotonSelector.h index 77210fa93710..7cfa1595bd13 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NPhotonSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NPhotonSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NPHOTONSELECTOR_H_ #define NPHOTONSELECTOR_H_ @@ -8,19 +8,17 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief A tool that selects events with a certain number of good photons. */ -class NPhotonSelector : public SignValueSelector { -public: + class NPhotonSelector: public SignValueSelector { + public: explicit NPhotonSelector(const std::string& params); bool apply(const top::Event& event) const override; - bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; -}; - + bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NRCJetSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NRCJetSelector.h new file mode 100644 index 000000000000..22aa918520f6 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NRCJetSelector.h @@ -0,0 +1,21 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef NRCJETSELECTOR_H_ +#define NRCJETSELECTOR_H_ + +#include "TopEventSelectionTools/SignValueSelector.h" + + +namespace top { + class NRCJetSelector: public top::SignValueSelector { + public: + explicit NRCJetSelector(const std::string& params); + + bool apply(const top::Event& event) const override; + bool applyParticleLevel(const top::ParticleLevelEvent&) const override; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NSoftMuonSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NSoftMuonSelector.h new file mode 100644 index 000000000000..5f9e8fa5a3c3 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NSoftMuonSelector.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef NSOFTMUONSELECTOR_H_ +#define NSOFTMUONSELECTOR_H_ + +#include "TopEventSelectionTools/SignValueSelector.h" + +namespace top { +/** + * @brief A tool that selects events with a certain number of good muons. + */ + class NSoftMuonSelector: public SignValueSelector { + public: + explicit NSoftMuonSelector(const std::string& params); + + bool apply(const top::Event& event) const override; + + bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NTauSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NTauSelector.h index 6459759dbfab..4c9442fd8837 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NTauSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NTauSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NTAUSELECTOR_H_ #define NTAUSELECTOR_H_ @@ -8,17 +8,17 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief A tool that selects events with a certain number of good taus. */ -class NTauSelector : public SignValueSelector { -public: + class NTauSelector: public SignValueSelector { + public: explicit NTauSelector(const std::string& params); bool apply(const top::Event& event) const override; -}; + bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NTauTightSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NTauTightSelector.h index 42432ccb6b81..aed9d7bfad4b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NTauTightSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NTauTightSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NTAUTIGHTSELECTOR_H_ #define NTAUTIGHTSELECTOR_H_ @@ -8,17 +8,15 @@ #include "TopEventSelectionTools/SignValueSelector.h" namespace top { - /** * @brief A tool that selects events with a certain number of good taus. */ -class NTauTightSelector : public SignValueSelector { -public: + class NTauTightSelector: public SignValueSelector { + public: explicit NTauTightSelector(const std::string& params); bool apply(const top::Event& event) const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NVarRCJetSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NVarRCJetSelector.h new file mode 100644 index 000000000000..27d084742851 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NVarRCJetSelector.h @@ -0,0 +1,22 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef NVARRCJETSELECTOR_H_ +#define NVARRCJETSELECTOR_H_ + +#include "TopEventSelectionTools/SignValueSelector.h" + + +namespace top { + class NVarRCJetSelector: public top::SignValueSelector { + std::string m_name; + public: + explicit NVarRCJetSelector(const std::string& name, const std::string& params); + + bool apply(const top::Event& event) const override; + bool applyParticleLevel(const top::ParticleLevelEvent&) const override; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NoBadMuonSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NoBadMuonSelector.h index c0bef23a8488..91df0fc04e33 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NoBadMuonSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/NoBadMuonSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NOBADMUONSELECTOR_H_ #define NOBADMUONSELECTOR_H_ @@ -11,22 +11,22 @@ #include "MuonAnalysisInterfaces/IMuonSelectionTool.h" namespace top { + class TopConfig; /** * @brief A tool that selects events containing no bad muons * https://twiki.cern.ch/twiki/bin/view/Atlas/MuonSelectionTool#is_BadMuon_Flag_Event_Veto * */ - class NoBadMuonSelector : public EventSelectorBase { -public: - + class NoBadMuonSelector: public EventSelectorBase { + public: /** * @brief Event selection if bad muon detected using the official muon selector tool. * * Call the muon selector tool and reject the event if any of the muons that * passed the event selection are marked as bad. */ - explicit NoBadMuonSelector(); + explicit NoBadMuonSelector(std::shared_ptr<top::TopConfig> m_config); /** * @brief Events with a muon flagged bad are rejected @@ -42,12 +42,11 @@ public: * @return The name of the tool for humans to see. */ std::string name() const override; - -private: + private: ToolHandle<CP::IMuonSelectionTool> m_muonSelectionTool; -}; - + std::shared_ptr<top::TopConfig> m_config; + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/OSLeptonSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/OSLeptonSelector.h index 7cf17c830e35..e157ee334b5a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/OSLeptonSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/OSLeptonSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef OSSELECTOR_H_ #define OSSELECTOR_H_ @@ -8,22 +8,20 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** * @brief Keep only events that have at least one opposite sign lepton pair. * * Try to find at least one lepton (el, mu) with positive charge, * and at least one with negative charge. */ -class OSLeptonSelector : public EventSelectorBase { -public: + class OSLeptonSelector: public EventSelectorBase { + public: bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; std::string name() const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/OSLeptonTightSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/OSLeptonTightSelector.h index fc6c0a2986c8..a68975f030f3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/OSLeptonTightSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/OSLeptonTightSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef OSTIGHTSELECTOR_H_ #define OSTIGHTSELECTOR_H_ @@ -8,7 +8,6 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** * @brief Keep only events that have at least one opposite sign tight lepton pair. * This is identical to OSLeptonSelector in the case of tight selection, so only relevant for loose selection. @@ -16,15 +15,14 @@ namespace top { * Try to find at least one lepton (el, mu) with positive charge, * and at least one with negative charge. */ -class OSLeptonTightSelector : public EventSelectorBase { -public: + class OSLeptonTightSelector: public EventSelectorBase { + public: bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; std::string name() const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ParticleLevelSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ParticleLevelSelector.h index a78700637a94..0cd63139c969 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ParticleLevelSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ParticleLevelSelector.h @@ -1,19 +1,11 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelSelector.h // Description: // Author: Fabian Wilk // Created: Tue Oct 27 13:26:19 2015 -// -// (c) by Fabian Wilk -// -// This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 -// International License. -// -// You should have received a copy of the license along with this work. -// If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. #ifndef _PARTICLELEVELSELECTOR_H_ #define _PARTICLELEVELSELECTOR_H_ @@ -21,35 +13,32 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - + /** + * @brief An event selector that accepts all particle level events and rejects all + * reco level events. + * + * This can be used to define event selections that shall be applied only to + * particle level events. + */ + class ParticleLevelSelector: public EventSelectorBase { /** - * @brief An event selector that accepts all particle level events and rejects all - * reco level events. - * - * This can be used to define event selections that shall be applied only to - * particle level events. + * @brief Reject every event. + * @return Always false. */ - class ParticleLevelSelector : public EventSelectorBase { - /** - * @brief Reject every event. - * @return Always false. - */ - virtual bool apply(const top::Event&) const override; - - /** - * @brief Accept every event. - * @return Always true. - */ - virtual bool applyParticleLevel(const top::ParticleLevelEvent&) const override; + virtual bool apply(const top::Event&) const override; - /** - * @brief The name printed in the cutflow. - * @return The word PARTICLE_LEVEL - */ - virtual std::string name() const override; - }; + /** + * @brief Accept every event. + * @return Always true. + */ + virtual bool applyParticleLevel(const top::ParticleLevelEvent&) const override; + /** + * @brief The name printed in the cutflow. + * @return The word PARTICLE_LEVEL + */ + virtual std::string name() const override; + }; } #endif /* _PARTICLELEVELSELECTOR_H_ */ - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PlotManager.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PlotManager.h index f9eb92198376..77c88cbb9e1f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PlotManager.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PlotManager.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #ifndef PLOTMANAGER_H_ #define PLOTMANAGER_H_ @@ -17,14 +17,13 @@ namespace EL { } namespace top { - /** * @brief A map that lets you create a bunch of histograms and get hold of them * via a string name. It takes care of writing them to the outputfile too - if * you have one. */ -class PlotManager { -public: + class PlotManager { + public: /** * @brief A name for the selection. Plots will be stored in a folder * with this name in the output file. e.g. ejets, mujets etc. @@ -34,11 +33,11 @@ public: * of a folder because... well... ROOT! */ explicit PlotManager(const std::string& name, TFile* outputFile = nullptr, EL::Worker* wk = nullptr); - - PlotManager(const std::string& sample,const std::string& channel,const std::string& syst,TFile* outputFile); + + PlotManager(const std::string& sample, const std::string& channel, const std::string& syst, TFile* outputFile); /** - * @brief Add a histogram to the output file. + * @brief Add a 1D histogram to the output file. * * @param hname A unique name, notice that we automatically add the name * of the analysis on to this with an underscore. @@ -49,6 +48,17 @@ public: */ void addHist(const std::string& hname, const std::string& title, int bins, double start, double end) const; + /** + * @brief Add a 1D histogram with variable bin size to the output file. + * + * @param hname A unique name, notice that we automatically add the name + * of the analysis on to this with an underscore. + * @param title The histogram title, as root expects. + * @param bins The number of bins, passed directly to root. + * @param binArray The array with bin edges + */ + void addHist(const std::string& hname, const std::string& title, int bins, double* binArray) const; + /** * @brief Add a 2D histogram to the output file. * @@ -58,13 +68,44 @@ public: * @param xbins The number of x-bins, passed directly to root. * @param xstart The starting x-value, passed directly to root. * @param xend The ending x-value, passed directly to root. - * @param xbins The number of y-bins, passed directly to root. - * @param xstart The starting y-value, passed directly to root. - * @param xend The ending y-value, passed directly to root. + * @param ybins The number of y-bins, passed directly to root. + * @param ystart The starting y-value, passed directly to root. + * @param yend The ending y-value, passed directly to root. */ void addHist(const std::string& hname, const std::string& title, - int xbins, double xstart, double xend, - int ybins, double ystart, double yend) const; + int xbins, double xstart, double xend, + int ybins, double ystart, double yend) const; + + /** + * @brief Add a 2D histogram with variable bin size to the output file. + * + * @param hname A unique name, notice that we automatically add the name + * of the analysis on to this with an underscore. + * @param title The histogram title, as root expects. + * @param xbins The number of x-bins, passed directly to root. + * @param xbinArray The array with x-bin edges, passed directly to root. + * @param ybins The number of y-bins, passed directly to root. + * @param ybinArray The array with y-bin edges, passed directly to root. + */ + void addHist(const std::string& hname, const std::string& title, + int xbins, double* xbinArray, + int ybins, double* ybinArray) const; + + /** + * @brief Add a 2D histogram with variable bin size to the output file. + * + * @param hname A unique name, notice that we automatically add the name + * of the analysis on to this with an underscore. + * @param title The histogram title, as root expects. + * @param xbins The number of x-bins, passed directly to root. + * @param xbinArray The array with x-bin edges, passed directly to root. + * @param ybins The number of y-bins, passed directly to root. + * @param ystart The starting y-value, passed directly to root. + * @param yend The ending y-value, passed directly to root. + */ + void addHist(const std::string& hname, const std::string& title, + int xbins, double* xbinArray, + int ybins, double ystart, double yend) const; /** * @brief Recover an existing histogram, to fill it for example. @@ -82,8 +123,17 @@ public: * on each histogram. I'm assuming you have an open file already. */ void scaleHistograms(double sf = 1.) const; + private: + /** + * @brief Helper method to check for duplicates when adding histogram. + * + * If duplicate histogram exists with same name as hname, print + * error message and throw std::runtime_error + * + * @param hname Name of the histogram to check against duplicates. + */ + void checkDuplicate(const std::string& hname) const; -private: EL::Worker* m_wk; ///Name of the folder to store the plots in, in the output file. @@ -93,8 +143,7 @@ private: mutable std::unordered_map<std::string, TH1*> m_histograms; mutable TDirectory* m_plotDir; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PrimaryVertexSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PrimaryVertexSelector.h index 0d8a6976f837..9ad1c4e91fb9 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PrimaryVertexSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PrimaryVertexSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef PRIMARYVERTEXSELECTOR_H_ #define PRIMARYVERTEXSELECTOR_H_ @@ -8,33 +8,31 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** - * @brief Select data events with good Primary vertices - * following: - * https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/InDetTrackingPerformanceGuidelines#Vertexing - * - */ - class PrimaryVertexSelector : public EventSelectorBase { - public: - PrimaryVertexSelector(); - virtual ~PrimaryVertexSelector(){}; - - /** - * @brief MC simulation passes, data is checked against the GRL. - * - * @param event The event in question - * @return True for MC simulation, or if the data event is on the GRL. - */ - virtual bool apply(const top::Event& event) const override; - - /** - * @brief The name of the tool. - * - * @return The name of the tool for humans to see. - */ - std::string name() const override; - + * @brief Select data events with good Primary vertices + * following: + * https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/InDetTrackingPerformanceGuidelines#Vertexing + * + */ + class PrimaryVertexSelector: public EventSelectorBase { + public: + PrimaryVertexSelector(); + virtual ~PrimaryVertexSelector() {}; + + /** + * @brief MC simulation passes, data is checked against the GRL. + * + * @param event The event in question + * @return True for MC simulation, or if the data event is on the GRL. + */ + virtual bool apply(const top::Event& event) const override; + + /** + * @brief The name of the tool. + * + * @return The name of the tool for humans to see. + */ + std::string name() const override; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PrintEventSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PrintEventSelector.h index 6ece5e33bf21..f53b48745793 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PrintEventSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/PrintEventSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef PRINTEVENTSELECTOR_H_ #define PRINTEVENTSELECTOR_H_ @@ -8,27 +8,26 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** - * @brief Print some information about the event to the screen using cout. + * @brief Print some information about the event to the screen. * * Prints the run number, event number, mu, and lists of 4-vectors for good * electrons, muons and jets and the event missing ET. */ -class PrintEventSelector : public EventSelectorBase { + class PrintEventSelector: public EventSelectorBase { /** * @brief For each event print some information about it to the terminal. * * @return Also marks the event as passed. */ bool apply(const top::Event& event) const override; + bool applyParticleLevel(const top::ParticleLevelEvent& plEvent) const override; /** * @brief The word PRINT. */ std::string name() const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/RecoLevelSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/RecoLevelSelector.h index 30767fd60de0..ea6aef429700 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/RecoLevelSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/RecoLevelSelector.h @@ -1,19 +1,11 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: RecoLevelSelector.h // Description: // Author: Fabian Wilk // Created: Tue Oct 27 12:07:02 2015 -// -// (c) by Fabian Wilk -// -// This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 -// International License. -// -// You should have received a copy of the license along with this work. -// If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. #ifndef _RECOLEVELSELECTOR_H_ #define _RECOLEVELSELECTOR_H_ @@ -21,35 +13,32 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - + /** + * @brief An event selector that accepts all reco level events and rejects all + * particle level events. + * + * This can be used to define event selections that shall be applied only to + * reco level events. + */ + class RecoLevelSelector: public EventSelectorBase { /** - * @brief An event selector that accepts all reco level events and rejects all - * particle level events. - * - * This can be used to define event selections that shall be applied only to - * reco level events. + * @brief Accept every event. + * @return Always true. */ - class RecoLevelSelector : public EventSelectorBase { - /** - * @brief Accept every event. - * @return Always true. - */ - virtual bool apply(const top::Event&) const override; - - /** - * @brief Reject every event. - * @return Always false. - */ - virtual bool applyParticleLevel(const top::ParticleLevelEvent&) const override; + virtual bool apply(const top::Event&) const override; - /** - * @brief The name printed in the cutflow. - * @return The word RECO_LEVEL - */ - virtual std::string name() const override; - }; + /** + * @brief Reject every event. + * @return Always false. + */ + virtual bool applyParticleLevel(const top::ParticleLevelEvent&) const override; + /** + * @brief The name printed in the cutflow. + * @return The word RECO_LEVEL + */ + virtual std::string name() const override; + }; } #endif /* _RECOLEVELSELECTOR_H_ */ - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/RunNumberSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/RunNumberSelector.h index 034c084136af..c536617dd76d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/RunNumberSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/RunNumberSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef RUNNUMBERSELECTOR_H_ #define RUNNUMBERSELECTOR_H_ @@ -9,21 +9,19 @@ namespace top { -class TopConfig; + class TopConfig; /** * @brief Apply a cut on the (random) run number. */ -class RunNumberSelector : public SignValueSelector { -public: - explicit RunNumberSelector(const std::string& params,std::shared_ptr<top::TopConfig> config); + class RunNumberSelector: public SignValueSelector { + public: + explicit RunNumberSelector(const std::string& params, std::shared_ptr<top::TopConfig> config); bool apply(const top::Event& event) const override; - -private: + private: std::shared_ptr<top::TopConfig> m_config; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SSLeptonSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SSLeptonSelector.h index ccc6ca901731..43c26866718c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SSLeptonSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SSLeptonSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SSSELECTOR_H_ #define SSSELECTOR_H_ @@ -8,20 +8,18 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** * @brief Keep only events that have at least one same sign lepton pair. * */ -class SSLeptonSelector : public EventSelectorBase{ -public: + class SSLeptonSelector: public EventSelectorBase { + public: bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; std::string name() const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SSLeptonTightSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SSLeptonTightSelector.h index eba687dc27d1..4abbac685246 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SSLeptonTightSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SSLeptonTightSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SSTIGHTSELECTOR_H_ #define SSTIGHTSELECTOR_H_ @@ -8,21 +8,19 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** * @brief Keep only events that have at least one same sign tight lepton pair. * This is identical to SSLeptonSelector in the case of tight selection, so only relevant for loose selection. * */ -class SSLeptonTightSelector : public EventSelectorBase{ -public: + class SSLeptonTightSelector: public EventSelectorBase { + public: bool apply(const top::Event& event) const override; bool applyParticleLevel(const top::ParticleLevelEvent& event) const override; std::string name() const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SaveEventSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SaveEventSelector.h index 5100a9a24998..7b98e5174510 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SaveEventSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SaveEventSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SAVEEVENTSELECTOR_H_ #define SAVEEVENTSELECTOR_H_ @@ -8,7 +8,6 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** * @brief Save this event in the output file. * @@ -16,7 +15,7 @@ namespace top { * selection, but it will also write out the selected objects to the output * file in the CollectionTree. */ -class SaveEventSelector : public EventSelectorBase { + class SaveEventSelector: public EventSelectorBase { /** * @brief Accept every event * @@ -31,8 +30,7 @@ class SaveEventSelector : public EventSelectorBase { * @return The word SAVE. */ std::string name() const override; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SignValueSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SignValueSelector.h index f84a7fa55a6d..7509b9e8c128 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SignValueSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/SignValueSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SIGNVALUESELECTOR_H_ #define SIGNVALUESELECTOR_H_ @@ -8,26 +8,25 @@ #include "TopEventSelectionTools/EventSelectorBase.h" namespace top { - /** * @brief Many of the tools need a sign (>=) and a value (2). For example, if * we want at least two leptons. This is an intermediate 'base' class that * implements all the functionality these tools need in one place. */ -class SignValueSelector : public EventSelectorBase { -public: + class SignValueSelector: public EventSelectorBase { + public: /** * @brief Many of the tools will be supplied with an equality (or inequality) by * the user. They're decoded from the text input and saved in this 'sign' * format. */ enum Sign { - signNOIDEA, //the user clearly did something wrong, expect to exit / crash - signEQ, // == - signLT, // < - signGT, // > - signLTEQ, // <= - signGTEQ // >= + signNOIDEA, //the user clearly did something wrong, expect to exit / crash + signEQ, // == + signLT, // < + signGT, // > + signLTEQ, // <= + signGTEQ // >= }; /** @@ -46,14 +45,24 @@ public: * The default behaviour is false (the cut value is not a string). Note that * cutValueMode = true only makes sense if multiplicityMode = true */ - SignValueSelector(const std::string& name, std::string params, bool multiplicityMode = false, bool cutValueMode = false); + SignValueSelector(const std::string& name, std::string params, bool multiplicityMode = false, + bool cutValueMode = false); + /** + * @brief Overloaded constructor with additional options to do string splitting on delimiter and concatantion with a + *new string + * @param delim - delimiter to split with + * @param replace - string to replace the delimiter when concatanating + * @param default_prefix - if it was not possible to split, the code was probably expecting something to be + *prepended to the string so cover this + */ + SignValueSelector(const std::string& name, std::string params, bool multiplicityMode, bool cutValueMode, + std::string delim, std::string replace, std::string default_prefix); /** * @brief The name is generated in the constructor for this kind of tool. */ virtual std::string name() const override; - -protected: + protected: /** * @brief Integers are annoying in C++. * @@ -92,6 +101,12 @@ protected: */ std::string valueString() const; + + /** + * @brief valueString which is manipulated to replace delimiter with new string + */ + std::string valueStringDelimReplace() const; + /** * @brief Get the cut multiplicity assigned in the constructor. * @@ -148,8 +163,7 @@ protected: * @return A short string version of the name */ const std::string signstring() const; - -private: + private: ///Hold the name of the tool, filled by the constructor. std::string m_name; @@ -164,8 +178,10 @@ private: ///The multiplicity for cuts that take both a value and a multiplicity e.g. EL_N 25000 >= 2 double m_multiplicity; -}; + ///The value of the cut when it is a string, with replacement of delimiter with a replacement substring + std::string m_cutvalueStringDelimReplace; + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ToolLoaderBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ToolLoaderBase.h index da968a368a03..1be42ac25c44 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ToolLoaderBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/ToolLoaderBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOOLLOADERBASE_H_ #define TOOLLOADERBASE_H_ @@ -13,7 +13,7 @@ class TFile; namespace EL { -class Worker; + class Worker; } namespace top { @@ -30,8 +30,8 @@ namespace top { * should act as a good reference. Basically you want an if (blah == "mytool") * then new MyTool(). */ -class ToolLoaderBase { -public: + class ToolLoaderBase { + public: ///Constructor doesn't do anything. ToolLoaderBase() {} @@ -56,11 +56,11 @@ public: * the name was not found (since this might not be the only tool loader in * the program). */ - virtual top::EventSelectorBase* initTool(const std::string& name, const std::string& line, TFile* outputFile, std::shared_ptr<top::TopConfig> config,EL::Worker* wk = nullptr) = 0; + virtual top::EventSelectorBase* initTool(const std::string& name, const std::string& line, TFile* outputFile, + std::shared_ptr<top::TopConfig> config, EL::Worker* wk = nullptr) = 0; ClassDef(top::ToolLoaderBase, 0); -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TopEventSelectionToolsLoader.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TopEventSelectionToolsLoader.h index 16799d188300..4d2ac4b39bcb 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TopEventSelectionToolsLoader.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TopEventSelectionToolsLoader.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef EVENTSELECTIONTOOLLOADER_H_ #define EVENTSELECTIONTOOLLOADER_H_ @@ -8,7 +8,6 @@ #include "TopEventSelectionTools/ToolLoaderBase.h" namespace top { - /** * @brief This is used to load tools in this package in a factory like way. It * has one important function. After that has been called, you can dispose of @@ -19,8 +18,8 @@ namespace top { * you'll be glad to hear that it's fine but we're not there yet. * 2) Don't put any xAOD headers in here. Same reason. */ -class TopEventSelectionToolsLoader : public ToolLoaderBase { -public: + class TopEventSelectionToolsLoader: public ToolLoaderBase { + public: /** * @brief Convert the string name into a tool-object. * @@ -44,11 +43,11 @@ public: * the name was not found (since this might not be the only tool loader in * the program). */ - top::EventSelectorBase* initTool(const std::string& name, const std::string& line, TFile* outputFile, std::shared_ptr<top::TopConfig> config,EL::Worker* wk = nullptr); + top::EventSelectorBase* initTool(const std::string& name, const std::string& line, TFile* outputFile, + std::shared_ptr<top::TopConfig> config, EL::Worker* wk = nullptr); ClassDef(top::TopEventSelectionToolsLoader, 0) -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrackJetCleaningSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrackJetCleaningSelector.h new file mode 100644 index 000000000000..658771ea1baf --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrackJetCleaningSelector.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TRACKJETCLEANINGSELECTOR_H_ +#define TRACKJETCLEANINGSELECTOR_H_ + +#include "TopEventSelectionTools/EventSelectorBase.h" + +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" +#include "JetInterface/IJetSelector.h" +#include "JetSelectorTools/IEventCleaningTool.h" + +namespace top { + class TopConfig; + + class TrackJetCleaningSelector: public EventSelectorBase { + public: + explicit TrackJetCleaningSelector(std::shared_ptr<top::TopConfig> config); + + bool apply(const top::Event& event) const override; + + std::string name() const override; + private: + std::shared_ptr<top::TopConfig> m_config; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TreeManager.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TreeManager.h index 62c76f601c30..0a0c7595f5a9 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TreeManager.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TreeManager.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TREEMANAGER_H_ #define TREEMANAGER_H_ @@ -16,7 +16,6 @@ class TFile; namespace top { - /** * @brief A class that hopefully makes making a flat ntuple tree a bit easier * since you don't need to worry about what type to make the branches and stuff. @@ -24,8 +23,8 @@ namespace top { * Almost all this code is stolen from SFrame: * http://sourceforge.net/p/sframe */ -class TreeManager { -public: + class TreeManager { + public: /** * @brief Default constructor - note need to initialize the class if you use this. */ @@ -38,40 +37,40 @@ public: * @param file The file to write the tree to. * @param name The name of the tree (e.g. nominal, systematic1 etc). */ - TreeManager(const std::string& name, TFile* outputFile,const bool setAutoFlushZero = false); + TreeManager(const std::string& name, TFile* outputFile, const int, const int, const int); ///We do allow you to move it TreeManager(const TreeManager&& rhs); ///But not to copy it. - TreeManager(const TreeManager&)= delete; + TreeManager(const TreeManager&) = delete; ///Or assign it. - TreeManager& operator=(TreeManager const&) = delete; + TreeManager& operator = (TreeManager const&) = delete; /** * @brief Initialize the class with a new output file */ - void initialize(const std::string& name, TFile* outputFile,const bool setAutoFlushZero = false); + void initialize(const std::string& name, TFile* outputFile, const int, const int, const int); /** * @brief Calls TTree::Fill. Needed to fill the tree. */ void fill(); - + /** * @brief name of the TTree */ const std::string& name() const; /** @brief function object type used for branch filters */ - typedef std::function<int(TreeManager const *, std::string const &)> BranchFilter; + typedef std::function<int (TreeManager const*, std::string const&)> BranchFilter; /** @copydoc TreeManager::m_branchFilters */ - std::vector<BranchFilter> & branchFilters() { return m_branchFilters; } + std::vector<BranchFilter>& branchFilters() {return m_branchFilters;} /** @copydoc TreeManager::m_branchFilters */ - std::vector<BranchFilter> const & branchFilters() const { return m_branchFilters; } + std::vector<BranchFilter> const& branchFilters() const {return m_branchFilters;} /** * @brief The idea is to simplify the creation of branches so that you don't @@ -87,32 +86,30 @@ public: */ template<class T> void makeOutputVariable(T& obj, const std::string name) { - for (auto branchFilter : branchFilters()) { - int status = branchFilter(this, name); - if (status > 0) - break; - if (status == 0) - return; - } - const char* type_name = typeid(obj).name(); - if (strlen( type_name ) == 1) { - std::ostringstream leaflist; - leaflist << name << "/" << RootType( type_name ); - m_tree->Branch(name.c_str(), &obj, leaflist.str().c_str()); - } else { - m_outputVarPointers.push_back( &obj ); - T** pointer = reinterpret_cast< T** >( &m_outputVarPointers.back() ); - m_tree->Branch( name.c_str(), pointer ); - } + for (auto branchFilter : branchFilters()) { + int status = branchFilter(this, name); + if (status > 0) break; + if (status == 0) return; + } + const char* type_name = typeid(obj).name(); + if (strlen(type_name) == 1) { + std::ostringstream leaflist; + leaflist << name << "/" << RootType(type_name); + m_tree->Branch(name.c_str(), &obj, leaflist.str().c_str(), m_basketSizePrimitive); + } else { + m_outputVarPointers.push_back(&obj); + T** pointer = reinterpret_cast< T** >(&m_outputVarPointers.back()); + m_tree->Branch(name.c_str(), pointer, m_basketSizeVector); + } } -private: - /** + private: + /** * name of the tree */ std::string m_name; - - + + /** * @brief Stolen from SFrame code. * @@ -171,8 +168,10 @@ private: */ std::vector<BranchFilter> m_branchFilters; -}; - + // Two member variables to manage the size of the tree branch baskets + int m_basketSizePrimitive; + int m_basketSizeVector; + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionLooseSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionLooseSelector.h new file mode 100644 index 000000000000..858fbf230f5d --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionLooseSelector.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TRIGDECISIONLOOSESELECTOR_H_ +#define TRIGDECISIONLOOSESELECTOR_H_ + +#include "TopEventSelectionTools/EventSelectorBase.h" +#include <memory> + + +namespace top { + // Forward declare + class Event; + class TopConfig; + /** + * @brief Sometimes you may want to select events that pass a certain trigger, + * or triggers. + * + * This code only accepts the event if it passes at least one of the triggers + * that it was configured with. It does an 'OR' of all the trigger decisions. + * + * This will only be applied on the loose trees (i.e. those with "_Loose" in their names) + * + * For example: + * + * @code + * TRIGDEC HLT_e24_tight_L1EM20V HLT_e60_medium1 + * @endcode + * + * Would select the event if either of those passes. + */ + class TrigDecisionLooseSelector: public EventSelectorBase { + public: + /** + * @brief A tool to select events that pass a certain trigger (or any + * trigger in a list). + * + * @param name The name of the current event selection - e.g. ee + * @param config - this will give use a std::vector<std::string> of triggers to check + */ + TrigDecisionLooseSelector(const std::string& selectorName, std::shared_ptr<top::TopConfig> config); + + /** + * @brief Select events based on the 'OR' of a few user defined triggers. + * The thinking is you might want to pass e25i or e30 so "TRIGDEC e25i e30". + * + * @param event The event in question. Not used by the trigger decision + * tool. I guess it finds out the information some other, internal, way. + * + * @return True if at least one of the triggers in the string list passed. + */ + virtual bool apply(const top::Event& event) const override; + + ///TRIGDEC because we might have a tool for trigger matching too at some point + std::string name() const override; + private: + ///List of triggers to 'or' together for each event. If any one passes, the event passes + std::vector<std::string> m_triggers; + }; +} + +#endif /* TRIGDECISIONLOOSESELECTOR_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionSelector.h index f28926146e7c..f89d01a7b28b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TRIGDECISIONSELECTOR_H_ #define TRIGDECISIONSELECTOR_H_ @@ -11,51 +11,50 @@ namespace top { // Forward declare - class Event; + class Event; class TopConfig; /** - * @brief Sometimes you may want to select events that pass a certain trigger, - * or triggers. - * - * This code only accepts the event if it passes at least one of the triggers - * that it was configured with. It does an 'OR' of all the trigger decisions. - * - * For example: - * - * @code - * TRIGDEC HLT_e24_tight_L1EM20V HLT_e60_medium1 - * @endcode - * - * Would select the event if either of those passes. - */ - class TrigDecisionSelector : public EventSelectorBase { - public: - /** - * @brief A tool to select events that pass a certain trigger (or any - * trigger in a list). - * - * @param name The name of the current event selection - e.g. ee - * @param config - this will give use a std::vector<std::string> of triggers to check - */ - TrigDecisionSelector(const std::string& selectorName,std::shared_ptr<top::TopConfig> config); - - /** - * @brief Select events based on the 'OR' of a few user defined triggers. - * The thinking is you might want to pass e25i or e30 so "TRIGDEC e25i e30". - * - * @param event The event in question. Not used by the trigger decision - * tool. I guess it finds out the information some other, internal, way. - * - * @return True if at least one of the triggers in the string list passed. - */ - virtual bool apply(const top::Event& event) const override; - - ///TRIGDEC because we might have a tool for trigger matching too at some point - std::string name() const override; - - private: - ///List of triggers to 'or' together for each event. If any one passes, the event passes - std::vector<std::string> m_triggers; + * @brief Sometimes you may want to select events that pass a certain trigger, + * or triggers. + * + * This code only accepts the event if it passes at least one of the triggers + * that it was configured with. It does an 'OR' of all the trigger decisions. + * + * For example: + * + * @code + * TRIGDEC HLT_e24_tight_L1EM20V HLT_e60_medium1 + * @endcode + * + * Would select the event if either of those passes. + */ + class TrigDecisionSelector: public EventSelectorBase { + public: + /** + * @brief A tool to select events that pass a certain trigger (or any + * trigger in a list). + * + * @param name The name of the current event selection - e.g. ee + * @param config - this will give use a std::vector<std::string> of triggers to check + */ + TrigDecisionSelector(const std::string& selectorName, std::shared_ptr<top::TopConfig> config); + + /** + * @brief Select events based on the 'OR' of a few user defined triggers. + * The thinking is you might want to pass e25i or e30 so "TRIGDEC e25i e30". + * + * @param event The event in question. Not used by the trigger decision + * tool. I guess it finds out the information some other, internal, way. + * + * @return True if at least one of the triggers in the string list passed. + */ + virtual bool apply(const top::Event& event) const override; + + ///TRIGDEC because we might have a tool for trigger matching too at some point + std::string name() const override; + private: + ///List of triggers to 'or' together for each event. If any one passes, the event passes + std::vector<std::string> m_triggers; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionTightSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionTightSelector.h new file mode 100644 index 000000000000..ccafb865bae1 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigDecisionTightSelector.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TRIGDECISIONTIGHTSELECTOR_H_ +#define TRIGDECISIONTIGHTSELECTOR_H_ + +#include "TopEventSelectionTools/EventSelectorBase.h" +#include <memory> + + +namespace top { + // Forward declare + class Event; + class TopConfig; + /** + * @brief Sometimes you may want to select events that pass a certain trigger, + * or triggers. + * + * This code only accepts the event if it passes at least one of the triggers + * that it was configured with. It does an 'OR' of all the trigger decisions. + * + * This will only be applied on the tight trees, not the loose ones (i.e. not those with "_Loose" in their names) + * + * For example: + * + * @code + * TRIGDEC_TIGHT HLT_e24_tight_L1EM20V HLT_e60_medium1 + * @endcode + * + * Would select the event if either of those passes. + */ + class TrigDecisionTightSelector: public EventSelectorBase { + public: + /** + * @brief A tool to select events that pass a certain trigger (or any + * trigger in a list). + * + * @param name The name of the current event selection - e.g. ee + * @param config - this will give use a std::vector<std::string> of triggers to check + */ + TrigDecisionTightSelector(const std::string& selectorName, std::shared_ptr<top::TopConfig> config); + + /** + * @brief Select events based on the 'OR' of a few user defined triggers. + * The thinking is you might want to pass e25i or e30 so "TRIGDEC e25i e30". + * + * @param event The event in question. Not used by the trigger decision + * tool. I guess it finds out the information some other, internal, way. + * + * @return True if at least one of the triggers in the string list passed. + */ + virtual bool apply(const top::Event& event) const override; + + ///TRIGDEC because we might have a tool for trigger matching too at some point + std::string name() const override; + private: + ///List of triggers to 'or' together for each event. If any one passes, the event passes + std::vector<std::string> m_triggers; + }; +} + +#endif /* TRIGDECISIONTIGHTSELECTOR_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigMatchSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigMatchSelector.h index 7c59a84f7be3..a8289514396f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigMatchSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/TrigMatchSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TRIGMATCHSELECTOR_H_ #define TRIGMATCHSELECTOR_H_ @@ -8,29 +8,30 @@ #include "TopEventSelectionTools/EventSelectorBase.h" #include <memory> -namespace top { +namespace top { // Forward declare - class Event; + class Event; class TopConfig; /** - * @brief Match offline object to trigger. - * - */ - class TrigMatchSelector : public EventSelectorBase { - public: - - TrigMatchSelector(const std::string& selectorName,std::shared_ptr<top::TopConfig> config); - - virtual bool apply(const top::Event& event) const override; - - std::string name() const override; - - private: - ///List of triggers to 'or' together for each event. If any one passes, the event passes - std::vector<std::string> m_electronTriggers; - std::vector<std::string> m_muonTriggers; - std::vector<std::string> m_tauTriggers; + * @brief Match offline object to trigger. + * + */ + class TrigMatchSelector: public EventSelectorBase { + public: + TrigMatchSelector(const std::string& selectorName, std::shared_ptr<top::TopConfig> config); + + virtual bool apply(const top::Event& event) const override; + + std::string name() const override; + private: + ///List of triggers to 'or' together for each event. If any one passes, the event passes + std::vector<std::string> m_electronTriggers_Tight; + std::vector<std::string> m_muonTriggers_Tight; + std::vector<std::string> m_tauTriggers_Tight; + std::vector<std::string> m_electronTriggers_Loose; + std::vector<std::string> m_muonTriggers_Loose; + std::vector<std::string> m_tauTriggers_Loose; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt index fb7a8522b0a0..726bf4fb359a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt @@ -95,5 +95,9 @@ atlas_add_executable( mini-to-plots PathResolver ${ROOT_LIBRARIES} TopExamples ) +atlas_add_executable( combineATOutputs + util/combineATOutputs.cxx + LINK_LIBRARIES ${ROOT_LIBRARIES} + TopExamples ) atlas_install_scripts( scripts/* ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/README.md b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/README.md new file mode 100644 index 000000000000..40ca8b1e65d5 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/README.md @@ -0,0 +1,40 @@ +This package can be used to submit grid jobs with AnalysisTop and TOPQ datasets. +If you're looking for a tutorial on how to submit a grid job, you might like to try + * https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21 + +The classes are flexible enough to allow the user to define new sample/derivation lists in a few lines. + +Usage (for submitting grid jobs) + +> `getExamples` +# This will copy the scripts using PathResolver to ${PWD}/grid + +> `lsetup rucio pyami panda` +# These tools need to be available for the TopExample scripts to function + +> `./01SubmitToGrid.py` +# This will run through the preconfigured list of samples and submit grid jobs +# You will want to edit this file to specify your own grid name, your own job suffixes and point to your cut file +# You may also want to define new samples (see MC16.py to see how they are added to the classes) + +> `./02DownloadFromGrid.py` +> `./03LocalAnalysis.py --run` +> `./04Plot.py` + +Usage (for making histograms) + +``` +- top::NoSelectionAnalysis: If the grid part didn't do any selection, use me! +- top::DileptonAnalysis: If the grid part did ee, mumu and emu, use me! +- top::LJetsAnalysis: For e+jets and mu+jets use me! +- top::LJetsTtresAnalysis: Includes largeR jets! +``` + +All the codes above use (mostly) the same histograms which are added and filled by using DefaultPlots.h. +The event loop is run by mini-to-plots.cxx, something like this: + +``` +./mini-to-plots Dilepton /path/to/file/grid_datasetname/input.txt +``` + +The word Dilepton tells it to load the top::DileptonAnalysis. You can see how this works in AnalysisTools.h addPlots(). The grid tag is extracted from the path, so that's important to keep in. diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/AnalysisTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/AnalysisTools.cxx index da3fe026d52c..6f33a13f8361 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/AnalysisTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/AnalysisTools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/AnalysisTools.h" #include "TopExamples/NoSelectionAnalysis.h" @@ -27,38 +27,35 @@ #include <memory> namespace top { - -std::unique_ptr<top::AnalysisBase> loadAnalysis(const std::string& name, TFile* outputFile, EL::Worker* wk) { - if (name == "Dilepton") - return std::unique_ptr<top::AnalysisBase>(new top::DileptonAnalysis(outputFile, wk)); - else if (name == "LJets") - return std::unique_ptr<top::AnalysisBase>(new top::LJetsAnalysis(outputFile, wk)); - else if (name == "NoSelection") - return std::unique_ptr<top::AnalysisBase>(new top::NoSelectionAnalysis(outputFile, wk)); - else if (name == "LJetsTtres") - return std::unique_ptr<top::AnalysisBase>(new top::LJetsTtresAnalysis(outputFile)); + std::unique_ptr<top::AnalysisBase> loadAnalysis(const std::string& name, TFile* outputFile, EL::Worker* wk) { + if (name == "Dilepton") return std::unique_ptr<top::AnalysisBase>(new top::DileptonAnalysis(outputFile, wk)); + else if (name == "LJets") return std::unique_ptr<top::AnalysisBase>(new top::LJetsAnalysis(outputFile, wk)); + else if (name == + "NoSelection") return std::unique_ptr<top::AnalysisBase>(new top::NoSelectionAnalysis(outputFile, wk)); + else if (name == "LJetsTtres") return std::unique_ptr<top::AnalysisBase>(new top::LJetsTtresAnalysis(outputFile)); else { - std::cout << "I only know about:\n"; - std::cout << "NoSelection\n"; - std::cout << "LJets\n"; - std::cout << "Dilepton\n"; - std::cout << "LJetsTtres\n"; - exit(1); + std::cout << "I only know about:\n"; + std::cout << "NoSelection\n"; + std::cout << "LJets\n"; + std::cout << "Dilepton\n"; + std::cout << "LJetsTtres\n"; + exit(1); } //make sure this never happens with the if statement above return nullptr; -} + } -const std::string getSampleNumberAsString(const std::string& filename, const std::string& infoContainerName) { + const std::string getSampleNumberAsString(const std::string& filename, const std::string& infoContainerName) { xAOD::TEvent xaodEvent(xAOD::TEvent::kBranchAccess); std::unique_ptr<TFile> fileForSampleNumber(TFile::Open(filename.c_str())); top::check(xaodEvent.readFrom(fileForSampleNumber.get()), "xAOD::TEvent readFrom failed"); xaodEvent.getEntry(0); const xAOD::EventInfo* info(0); - if (!xaodEvent.retrieve(info, infoContainerName)) - throw std::string("xAOD::TEvent couldn't get hold of ") + infoContainerName; + if (!xaodEvent.retrieve(info, + infoContainerName)) throw std::string("xAOD::TEvent couldn't get hold of ") + + infoContainerName; //data is padded with zero until it's 8 char long in ATLAS std::stringstream ss; @@ -66,24 +63,25 @@ const std::string getSampleNumberAsString(const std::string& filename, const std //but MC simulation is not padded in dataset names :) if (info->eventType(xAOD::EventInfo::IS_SIMULATION)) { - ss.str(""); - ss << info->mcChannelNumber(); + ss.str(""); + ss << info->mcChannelNumber(); } return ss.str(); -} + } -double sfToOneInversefb(unsigned int mcChannelNumber, double mcWeightsInSample) { + double sfToOneInversefb(unsigned int mcChannelNumber, double mcWeightsInSample) { //load the x-section from a file SampleXsection tdp; + // const char* const rc = getenv("ROOTCOREBIN"); // std::string filename = std::string(rc) + "/data/TopDataPreparation/XSection-MC15-13TeV-fromSusyGrp.data"; std::string filename = PathResolverFindCalibFile("TopDataPreparation/XSection-MC15-13TeV-fromSusyGrp.data"); if (!tdp.readFromFile(filename.c_str())) { - std::cout << "TopDataPreparation - could not read file\n"; - std::cout << filename << "\n"; - std::cout << "Maybe check it exists, first?" << std::endl; - exit(1); + std::cout << "TopDataPreparation - could not read file\n"; + std::cout << filename << "\n"; + std::cout << "Maybe check it exists, first?" << std::endl; + exit(1); } //calculate @@ -106,37 +104,36 @@ double sfToOneInversefb(unsigned int mcChannelNumber, double mcWeightsInSample) std::cout << "Scale factor to 1 fb-1 : " << sf << "\n"; return sf; -} + } -void updateCutflow(const std::string& name, TH1D*& histogram, TFile* inputFile) { + void updateCutflow(const std::string& name, TH1D*& histogram, TFile* inputFile) { const auto* const temp = dynamic_cast<TH1D*> (inputFile->Get(name.c_str())); + if (histogram == nullptr) { - histogram = dynamic_cast<TH1D*> (temp->Clone()); - histogram->SetDirectory(0); - } else - histogram->Add(temp); -} + histogram = dynamic_cast<TH1D*> (temp->Clone()); + histogram->SetDirectory(0); + } else histogram->Add(temp); + } -std::string gridTagFromDirectoryName(const std::string inputFile) { + std::string gridTagFromDirectoryName(const std::string inputFile) { std::string gridTag = inputFile; try { - gridTag.erase(gridTag.rfind("/")); - gridTag = gridTag.substr(gridTag.rfind("/") + 1); + gridTag.erase(gridTag.rfind("/")); + gridTag = gridTag.substr(gridTag.rfind("/") + 1); - for (int i = 0; i < 3; ++i) - gridTag = gridTag.erase(0, gridTag.find(".") + 1); + for (int i = 0; i < 3; ++i) + gridTag = gridTag.erase(0, gridTag.find(".") + 1); - gridTag = gridTag.erase(gridTag.rfind(".")); + gridTag = gridTag.erase(gridTag.rfind(".")); } catch (...) { - gridTag = "unkown"; + gridTag = "unkown"; } return gridTag; -} + } -bool passesPreSelection(const top::Event& topEvent, const std::string& name) { + bool passesPreSelection(const top::Event& topEvent, const std::string& name) { return topEvent.m_info->auxdata<int>(name); -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/ContainerNames.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/ContainerNames.cxx index ca8b4a924da7..2c8e04577a9e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/ContainerNames.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/ContainerNames.cxx @@ -1,20 +1,20 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/ContainerNames.h" #include <ostream> -std::ostream& operator<<(std::ostream& os, const top::ContainerNames& names) { - os << "EventInfo " << names.eventInfoName << "\n"; - os << "ElectronCollection: " << names.electronCollectionName << "\n"; - os << "MuonCollection: " << names.muonCollectionName << "\n"; - os << "JetCollection: " << names.jetCollectionName << "\n"; - os << "LargeJetCollection: " << names.largeJetCollectionName << "\n"; - os << "MET: " << names.metName << "\n"; - os << "TauCollection: " << names.tauCollectionName << "\n"; - os << "TruthCollection: " << names.truthCollectionName << "\n"; +std::ostream & operator << (std::ostream& os, const top::ContainerNames& names) { + os << "EventInfo " << names.eventInfoName << "\n"; + os << "ElectronCollection: " << names.electronCollectionName << "\n"; + os << "MuonCollection: " << names.muonCollectionName << "\n"; + os << "JetCollection: " << names.jetCollectionName << "\n"; + os << "LargeJetCollection: " << names.largeJetCollectionName << "\n"; + os << "MET: " << names.metName << "\n"; + os << "TauCollection: " << names.tauCollectionName << "\n"; + os << "TruthCollection: " << names.truthCollectionName << "\n"; - return os; + return os; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DefaultPlots.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DefaultPlots.cxx index 6fb972a4bb32..b830abf81f5d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DefaultPlots.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DefaultPlots.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/DefaultPlots.h" @@ -16,8 +16,7 @@ #include "TH1.h" namespace top { - -void addPlots(top::PlotManager& manager) { + void addPlots(top::PlotManager& manager) { manager.addHist("control_sig_njet", ";Number of selected jets;Events", 12, -0.5, 11.5); manager.addHist("control_sig_met", ";E_{T}^{miss} [GeV];Events / 10 GeV", 22, 0, 220); manager.addHist("control_met", ";E_{T}^{miss} [GeV];Events / 5 GeV", 45, 0, 225); @@ -25,9 +24,9 @@ void addPlots(top::PlotManager& manager) { manager.addHist("control_invmass", ";Invariant mass [GeV];Events / 5 GeV", 34, 15, 185); manager.addHist("control_sig_invmass", ";Invariant mass [GeV];Events / 10 GeV", 40, 11, 411); manager.addHist("control_sig_invmass_cut", ";Invariant mass [GeV];Events / 10 GeV", 40, 11, 411); - manager.addHist("dy_dphi",";#Delta#phi;Events", 10, 0., M_PI); - manager.addHist("dy_dphi_zpt",";Z p_{T} [GeV];Events", 30., 0., 300.); - manager.addHist("dy_counter",";DD norm;Events", 5., 0., 5.); + manager.addHist("dy_dphi", ";#Delta#phi;Events", 10, 0., M_PI); + manager.addHist("dy_dphi_zpt", ";Z p_{T} [GeV];Events", 30., 0., 300.); + manager.addHist("dy_counter", ";DD norm;Events", 5., 0., 5.); manager.addHist("mu", ";<#mu>;Events", 50, 0., 50.); manager.addHist("mc_weight", ";MC Event Weight", 100, -1.5, 5e6); @@ -55,47 +54,47 @@ void addPlots(top::PlotManager& manager) { manager.addHist("jet_eta", ";Jet #eta;Jets", 25, -2.5, 2.5); manager.addHist("jet_phi", ";Jet #phi;Jets", 25, -M_PI, M_PI); manager.addHist("jet_e", ";Jet E / GeV;Jets", 50, 0, 250); - manager.addHist("jet_mv2c20", ";Jet mv2c20;Jets", 50, 0, 1); + manager.addHist("jet_mv2c10", ";Jet mv2c10;Jets", 50, 0, 1); manager.addHist("jet0_pt", ";Jet0 p_{T} / GeV; Events / 10 GeV", 25, 5, 255); manager.addHist("jet0_eta", ";Jet0 #eta; Jets", 25, -2.5, 2.5); manager.addHist("jet0_phi", ";Jet0 #phi; Jets", 25, -M_PI, M_PI); manager.addHist("jet0_e", ";Jet0 E / GeV; Jets", 50, 0, 250); - manager.addHist("jet0_mv2c20", ";Jet0 mv2c20; Jets", 50, 0, 1); + manager.addHist("jet0_mv2c10", ";Jet0 mv2c10; Jets", 50, 0, 1); manager.addHist("jet1_pt", ";Jet1 p_{T} / GeV; Events / 10 GeV", 25, 5, 255); manager.addHist("jet1_eta", ";Jet1 #eta; Jets", 25, -2.5, 2.5); manager.addHist("jet1_phi", ";Jet1 #phi; Jets", 25, -M_PI, M_PI); manager.addHist("jet1_e", ";Jet1 E / GeV; Jets", 50, 0, 250); - manager.addHist("jet1_mv2c20", ";Jet1 mv2c20; Jets", 50, 0, 1); + manager.addHist("jet1_mv2c10", ";Jet1 mv2c10; Jets", 50, 0, 1); manager.addHist("jet2_pt", ";Jet2 p_{T} / GeV; Events / 10 GeV", 25, 5, 255); manager.addHist("jet2_eta", ";Jet2 #eta; Jets", 25, -2.5, 2.5); manager.addHist("jet2_phi", ";Jet2 #phi; Jets", 25, -M_PI, M_PI); manager.addHist("jet2_e", ";Jet2 E / GeV; Jets", 50, 0, 250); - manager.addHist("jet2_mv2c20", ";Jet2 mv2c20; Jets", 50, 0, 1); + manager.addHist("jet2_mv2c10", ";Jet2 mv2c10; Jets", 50, 0, 1); manager.addHist("jet3_pt", ";Jet3 p_{T} / GeV; Events / 10 GeV", 25, 5, 255); manager.addHist("jet3_eta", ";Jet3 #eta; Jets", 25, -2.5, 2.5); manager.addHist("jet3_phi", ";Jet3 #phi; Jets", 25, -M_PI, M_PI); manager.addHist("jet3_e", ";Jet3 E / GeV; Jets", 50, 0, 250); - manager.addHist("jet3_mv2c20", ";Jet3 mv2c20; Jets", 50, 0, 1); + manager.addHist("jet3_mv2c10", ";Jet3 mv2c10; Jets", 50, 0, 1); manager.addHist("met_et", ";MET / GeV;Events / 5 GeV", 40, 0, 200); manager.addHist("met_phi", ";MET #phi;Events", 40, -M_PI, M_PI); -} + } -void fillPlots(const top::Event& topEvent, top::PlotManager& manager, double eventWeight) { + void fillPlots(const top::Event& topEvent, top::PlotManager& manager, double eventWeight) { const double toGeV = 0.001; manager.hist("mu")->Fill(topEvent.m_info->averageInteractionsPerCrossing(), eventWeight); if (top::isSimulation(topEvent)) { -// manager.hist("mc_weight")->Fill(topEvent.m_info->mcEventWeight(), eventWeight); - manager.hist("mc_weight")->Fill(topEvent.m_truthEvent->at(0)->weights()[0], eventWeight);// FIXME temporary bugfix + manager.hist("mc_weight")->Fill(topEvent.m_info->auxdataConst<float>("AnalysisTop_eventWeight")); - if (top::ScaleFactorRetriever::hasPileupSF(topEvent)) - manager.hist("pileup_weight")->Fill(top::ScaleFactorRetriever::pileupSF(topEvent), eventWeight); + if (top::ScaleFactorRetriever::hasPileupSF(topEvent)) manager.hist("pileup_weight")->Fill(top::ScaleFactorRetriever::pileupSF( + topEvent), + eventWeight); } manager.hist("el_n")->Fill(topEvent.m_electrons.size(), eventWeight); @@ -104,53 +103,52 @@ void fillPlots(const top::Event& topEvent, top::PlotManager& manager, double eve //loop over all the electrons - new for loop style is cool for (const auto* const elPtr : topEvent.m_electrons) { - manager.hist("el_pt")->Fill(elPtr->pt() * toGeV, eventWeight); - manager.hist("el_eta")->Fill(elPtr->eta(), eventWeight); - manager.hist("el_phi")->Fill(elPtr->phi(), eventWeight); - manager.hist("el_e")->Fill(elPtr->e() * toGeV, eventWeight); - manager.hist("el_m")->Fill(elPtr->m() * toGeV, eventWeight); - manager.hist("el_charge")->Fill(elPtr->charge(), eventWeight); + manager.hist("el_pt")->Fill(elPtr->pt() * toGeV, eventWeight); + manager.hist("el_eta")->Fill(elPtr->eta(), eventWeight); + manager.hist("el_phi")->Fill(elPtr->phi(), eventWeight); + manager.hist("el_e")->Fill(elPtr->e() * toGeV, eventWeight); + manager.hist("el_m")->Fill(elPtr->m() * toGeV, eventWeight); + manager.hist("el_charge")->Fill(elPtr->charge(), eventWeight); } for (const auto* const muPtr : topEvent.m_muons) { - manager.hist("mu_pt")->Fill(muPtr->pt() * toGeV, eventWeight); - manager.hist("mu_eta")->Fill(muPtr->eta(), eventWeight); - manager.hist("mu_phi")->Fill(muPtr->phi(), eventWeight); - manager.hist("mu_e")->Fill(muPtr->e() * toGeV, eventWeight); - manager.hist("mu_m")->Fill(muPtr->m() * toGeV, eventWeight); - manager.hist("mu_charge")->Fill(muPtr->charge(), eventWeight); + manager.hist("mu_pt")->Fill(muPtr->pt() * toGeV, eventWeight); + manager.hist("mu_eta")->Fill(muPtr->eta(), eventWeight); + manager.hist("mu_phi")->Fill(muPtr->phi(), eventWeight); + manager.hist("mu_e")->Fill(muPtr->e() * toGeV, eventWeight); + manager.hist("mu_m")->Fill(muPtr->m() * toGeV, eventWeight); + manager.hist("mu_charge")->Fill(muPtr->charge(), eventWeight); } //plot for all jets, and also the four leading jets separately unsigned int i = 0; - std::array<std::string, 4> numbers{ {"jet0", "jet1", "jet2", "jet3"} }; + std::array<std::string, 4> numbers {{ + "jet0", "jet1", "jet2", "jet3" + }}; for (const auto* const jetPtr : topEvent.m_jets) { - manager.hist("jet_pt")->Fill(jetPtr->pt() * toGeV, eventWeight); - manager.hist("jet_eta")->Fill(jetPtr->eta(), eventWeight); - manager.hist("jet_phi")->Fill(jetPtr->phi(), eventWeight); - manager.hist("jet_e")->Fill(jetPtr->e() * toGeV, eventWeight); + manager.hist("jet_pt")->Fill(jetPtr->pt() * toGeV, eventWeight); + manager.hist("jet_eta")->Fill(jetPtr->eta(), eventWeight); + manager.hist("jet_phi")->Fill(jetPtr->phi(), eventWeight); + manager.hist("jet_e")->Fill(jetPtr->e() * toGeV, eventWeight); - double mv2c20_discriminant = 0.; - jetPtr->btagging()->MVx_discriminant("MV2c20", mv2c20_discriminant); + double mv2c10_discriminant = 0.; + jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); - manager.hist("jet_mv2c20")->Fill(mv2c20_discriminant, eventWeight); + manager.hist("jet_mv2c10")->Fill(mv2c10_discriminant, eventWeight); - if (i < numbers.size()) { - manager.hist(numbers[i] + "_pt")->Fill(jetPtr->pt() * toGeV, eventWeight); - manager.hist(numbers[i] + "_eta")->Fill(jetPtr->eta(), eventWeight); - manager.hist(numbers[i] + "_phi")->Fill(jetPtr->phi(), eventWeight); - manager.hist(numbers[i] + "_e")->Fill(jetPtr->e() * toGeV, eventWeight); - manager.hist(numbers[i] + "_mv2c20")->Fill(mv2c20_discriminant, eventWeight); - } + if (i < numbers.size()) { + manager.hist(numbers[i] + "_pt")->Fill(jetPtr->pt() * toGeV, eventWeight); + manager.hist(numbers[i] + "_eta")->Fill(jetPtr->eta(), eventWeight); + manager.hist(numbers[i] + "_phi")->Fill(jetPtr->phi(), eventWeight); + manager.hist(numbers[i] + "_e")->Fill(jetPtr->e() * toGeV, eventWeight); + manager.hist(numbers[i] + "_mv2c10")->Fill(mv2c10_discriminant, eventWeight); + } - ++i; + ++i; } manager.hist("met_et")->Fill(topEvent.m_met->met() * toGeV, eventWeight); manager.hist("met_phi")->Fill(topEvent.m_met->phi(), eventWeight); - - -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DileptonAnalysis.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DileptonAnalysis.cxx index 2d242c8ce9fa..fea19b10ea6f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DileptonAnalysis.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DileptonAnalysis.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/DileptonAnalysis.h" #include "TopExamples/DefaultPlots.h" @@ -17,7 +17,6 @@ #include <fstream> namespace top { - /** * @brief Setup the analysis, add some histograms. * @@ -26,32 +25,32 @@ namespace top { * and with / without weights to nullptr. They are loaded from the input files. * Also three counters are set to 0 for the number of processed events. */ -DileptonAnalysis::DileptonAnalysis(TFile* outputFile, EL::Worker* wk) : - m_mcChannelNumber(0), - m_runNumber(0), - m_histsElEl("ee", outputFile, wk), - m_histsMuMu("mumu", outputFile, wk), - m_histsElMu("emu", outputFile, wk), - m_cutflowEventsElEl(nullptr), - m_cutflowMCWeightsElEl(nullptr), - m_cutflowEventsMuMu(nullptr), - m_cutflowMCWeightsMuMu(nullptr), - m_cutflowEventsElMu(nullptr), - m_cutflowMCWeightsElMu(nullptr), - m_counterElEl(0), - m_counterMuMu(0), - m_counterElMu(0) { - //add some default histograms for each channel - top::addPlots(m_histsElEl); - top::addPlots(m_histsMuMu); - top::addPlots(m_histsElMu); - - //a special histogram for emu - m_histsElMu.addHist("ht", ";HT / GeV;Events / 20 GeV", 40, 0, 800); -} - -DileptonAnalysis::~DileptonAnalysis() { -} + DileptonAnalysis::DileptonAnalysis(TFile* outputFile, EL::Worker* wk) : + m_mcChannelNumber(0), + m_runNumber(0), + m_histsElEl("ee", outputFile, wk), + m_histsMuMu("mumu", outputFile, wk), + m_histsElMu("emu", outputFile, wk), + m_cutflowEventsElEl(nullptr), + m_cutflowMCWeightsElEl(nullptr), + m_cutflowEventsMuMu(nullptr), + m_cutflowMCWeightsMuMu(nullptr), + m_cutflowEventsElMu(nullptr), + m_cutflowMCWeightsElMu(nullptr), + m_counterElEl(0), + m_counterMuMu(0), + m_counterElMu(0) { + //add some default histograms for each channel + top::addPlots(m_histsElEl); + top::addPlots(m_histsMuMu); + top::addPlots(m_histsElMu); + + //a special histogram for emu + m_histsElMu.addHist("ht", ";HT / GeV;Events / 20 GeV", 40, 0, 800); + } + + DileptonAnalysis::~DileptonAnalysis() { + } /** * @brief When a new input file is opened we want to grab the cutflow histograms @@ -59,14 +58,14 @@ DileptonAnalysis::~DileptonAnalysis() { * * @param inputFile The file that was just opened. */ -void DileptonAnalysis::newFile(TFile* inputFile) { + void DileptonAnalysis::newFile(TFile* inputFile) { updateCutflow("ee/cutflow", m_cutflowEventsElEl, inputFile); updateCutflow("ee/cutflow_mc", m_cutflowMCWeightsElEl, inputFile); updateCutflow("mumu/cutflow", m_cutflowEventsMuMu, inputFile); updateCutflow("mumu/cutflow_mc", m_cutflowMCWeightsMuMu, inputFile); updateCutflow("emu/cutflow", m_cutflowEventsElMu, inputFile); updateCutflow("emu/cutflow_mc", m_cutflowMCWeightsElMu, inputFile); -} + } /** * @brief Work out if it's ee, mumu or emu and send the event to the correct @@ -80,27 +79,23 @@ void DileptonAnalysis::newFile(TFile* inputFile) { * * @param topEvent The event in question */ -void DileptonAnalysis::event(const top::Event& topEvent) { + void DileptonAnalysis::event(const top::Event& topEvent) { m_runNumber = topEvent.m_info->runNumber(); double eventWeight = 1.; if (top::isSimulation(topEvent)) { - m_mcChannelNumber = topEvent.m_info->mcChannelNumber(); -// eventWeight = topEvent.m_info->mcEventWeight(); - eventWeight = topEvent.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix + m_mcChannelNumber = topEvent.m_info->mcChannelNumber(); + eventWeight = topEvent.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); } //std::cout << topEvent << std::endl; - if (top::passesPreSelection(topEvent, "ee")) - eeAnalysis(topEvent, eventWeight); + if (top::passesPreSelection(topEvent, "ee")) eeAnalysis(topEvent, eventWeight); - if (top::passesPreSelection(topEvent, "mumu")) - mumuAnalysis(topEvent, eventWeight); + if (top::passesPreSelection(topEvent, "mumu")) mumuAnalysis(topEvent, eventWeight); - if (top::passesPreSelection(topEvent, "emu")) - emuAnalysis(topEvent, eventWeight); -} + if (top::passesPreSelection(topEvent, "emu")) emuAnalysis(topEvent, eventWeight); + } /** * @brief Plot some control regions, then the final plots for the analysis. @@ -116,7 +111,7 @@ void DileptonAnalysis::event(const top::Event& topEvent) { * exactly two electrons for the rest of this function. * @param eventWeight The event weight to be used when filling plots. */ -void DileptonAnalysis::eeAnalysis(const top::Event& topEvent, double eventWeight) { + void DileptonAnalysis::eeAnalysis(const top::Event& topEvent, double eventWeight) { ++m_counterElEl; const auto* e0 = topEvent.m_electrons[0]; @@ -130,45 +125,38 @@ void DileptonAnalysis::eeAnalysis(const top::Event& topEvent, double eventWeight const bool inZWindow = fabs(Z.M() - 91000.) < 10000.; //plot the met for all events in the Z-window - if (inZWindow && gteq2jets) - m_histsElEl.hist("control_met")->Fill(topEvent.m_met->met() * toGeV, eventWeight); + if (inZWindow && gteq2jets) m_histsElEl.hist("control_met")->Fill(topEvent.m_met->met() * toGeV, eventWeight); //plot the invariant mass for low MET events - if (!metgt60 && gteq2jets) - m_histsElEl.hist("control_invmass")->Fill(Z.M() / 1000., eventWeight); + if (!metgt60 && gteq2jets) m_histsElEl.hist("control_invmass")->Fill(Z.M() / 1000., eventWeight); //plot njet in zwindow for low MET events - if (inZWindow && !metgt60) - m_histsElEl.hist("control_njet")->Fill(topEvent.m_jets.size(), eventWeight); + if (inZWindow && !metgt60) m_histsElEl.hist("control_njet")->Fill(topEvent.m_jets.size(), eventWeight); //DY control region: inside Z window, but lower pt cut to signal region if (inZWindow && metgt30 && gteq2jets) { - m_histsElEl.hist("dy_dphi")->Fill(fabs(top::deltaPhi(*e0, *e1)), eventWeight); - m_histsElEl.hist("dy_dphi_zpt")->Fill(Z.Pt() * toGeV, eventWeight); - m_histsElEl.hist("dy_counter")->Fill(1., eventWeight); + m_histsElEl.hist("dy_dphi")->Fill(fabs(top::deltaPhi(*e0, *e1)), eventWeight); + m_histsElEl.hist("dy_dphi_zpt")->Fill(Z.Pt() * toGeV, eventWeight); + m_histsElEl.hist("dy_counter")->Fill(1., eventWeight); } //signal region - all cuts except Z mass - if (gteq2jets && metgt60) - m_histsElEl.hist("control_sig_invmass")->Fill(Z.M() * toGeV, eventWeight); + if (gteq2jets && metgt60) m_histsElEl.hist("control_sig_invmass")->Fill(Z.M() * toGeV, eventWeight); - if (!inZWindow && gteq2jets && metgt60) - m_histsElEl.hist("control_sig_invmass_cut")->Fill(Z.M() * toGeV, eventWeight); + if (!inZWindow && gteq2jets && + metgt60) m_histsElEl.hist("control_sig_invmass_cut")->Fill(Z.M() * toGeV, eventWeight); //signal region - all cuts except njet - if (!inZWindow && metgt60) - m_histsElEl.hist("control_sig_njet")->Fill(topEvent.m_jets.size(), eventWeight); + if (!inZWindow && metgt60) m_histsElEl.hist("control_sig_njet")->Fill(topEvent.m_jets.size(), eventWeight); //signal region - all cuts except met - if (!inZWindow && gteq2jets) - m_histsElEl.hist("control_sig_met")->Fill(topEvent.m_met->met() * toGeV, eventWeight); + if (!inZWindow && gteq2jets) m_histsElEl.hist("control_sig_met")->Fill(topEvent.m_met->met() * toGeV, eventWeight); //pretag selection - if (gteq2jets && !inZWindow && metgt60) - top::fillPlots(topEvent, m_histsElEl, eventWeight); -} + if (gteq2jets && !inZWindow && metgt60) top::fillPlots(topEvent, m_histsElEl, eventWeight); + } -void DileptonAnalysis::mumuAnalysis(const top::Event& topEvent, double eventWeight) { + void DileptonAnalysis::mumuAnalysis(const top::Event& topEvent, double eventWeight) { ++m_counterMuMu; const auto* mu0 = topEvent.m_muons[0]; @@ -182,43 +170,36 @@ void DileptonAnalysis::mumuAnalysis(const top::Event& topEvent, double eventWeig const bool inZWindow = fabs(Z.M() - 91000.) < 10000.; //plot the met for all events in the Z-window - if (inZWindow && gteq2jets) - m_histsMuMu.hist("control_met")->Fill(topEvent.m_met->met() * toGeV, eventWeight); + if (inZWindow && gteq2jets) m_histsMuMu.hist("control_met")->Fill(topEvent.m_met->met() * toGeV, eventWeight); //plot the invariant mass for low MET events - if (!metgt60 && gteq2jets) - m_histsMuMu.hist("control_invmass")->Fill(Z.M() / 1000., eventWeight); + if (!metgt60 && gteq2jets) m_histsMuMu.hist("control_invmass")->Fill(Z.M() / 1000., eventWeight); //plot njet in zwindow for low MET events - if (inZWindow && !metgt60) - m_histsMuMu.hist("control_njet")->Fill(topEvent.m_jets.size(), eventWeight); + if (inZWindow && !metgt60) m_histsMuMu.hist("control_njet")->Fill(topEvent.m_jets.size(), eventWeight); //DY control region: inside Z window, but lower pt cut to signal region if (inZWindow && metgt30 && gteq2jets) { - m_histsMuMu.hist("dy_dphi")->Fill(fabs(top::deltaPhi(*mu0, *mu1)), eventWeight); - m_histsMuMu.hist("dy_dphi_zpt")->Fill(Z.Pt() * toGeV, eventWeight); - m_histsMuMu.hist("dy_counter")->Fill(1., eventWeight); + m_histsMuMu.hist("dy_dphi")->Fill(fabs(top::deltaPhi(*mu0, *mu1)), eventWeight); + m_histsMuMu.hist("dy_dphi_zpt")->Fill(Z.Pt() * toGeV, eventWeight); + m_histsMuMu.hist("dy_counter")->Fill(1., eventWeight); } //signal region - all cuts except Z mass - if (gteq2jets && metgt60) - m_histsMuMu.hist("control_sig_invmass")->Fill(Z.M() * toGeV, eventWeight); + if (gteq2jets && metgt60) m_histsMuMu.hist("control_sig_invmass")->Fill(Z.M() * toGeV, eventWeight); - if (!inZWindow && gteq2jets && metgt60) - m_histsMuMu.hist("control_sig_invmass_cut")->Fill(Z.M() * toGeV,eventWeight); + if (!inZWindow && gteq2jets && + metgt60) m_histsMuMu.hist("control_sig_invmass_cut")->Fill(Z.M() * toGeV, eventWeight); //signal region - all cuts except njet - if (!inZWindow && metgt60) - m_histsMuMu.hist("control_sig_njet")->Fill(topEvent.m_jets.size(), eventWeight); + if (!inZWindow && metgt60) m_histsMuMu.hist("control_sig_njet")->Fill(topEvent.m_jets.size(), eventWeight); //signal region - all cuts except met - if (!inZWindow && gteq2jets) - m_histsMuMu.hist("control_sig_met")->Fill(topEvent.m_met->met() * toGeV, eventWeight); + if (!inZWindow && gteq2jets) m_histsMuMu.hist("control_sig_met")->Fill(topEvent.m_met->met() * toGeV, eventWeight); //pretag selection - if (gteq2jets && !inZWindow && metgt60) - top::fillPlots(topEvent, m_histsMuMu, eventWeight); -} + if (gteq2jets && !inZWindow && metgt60) top::fillPlots(topEvent, m_histsMuMu, eventWeight); + } /** * @brief emu channel @@ -230,7 +211,7 @@ void DileptonAnalysis::mumuAnalysis(const top::Event& topEvent, double eventWeig * @param topEvent The event in question * @param eventWeight The weights that are used when filling the histograms. */ -void DileptonAnalysis::emuAnalysis(const top::Event& topEvent, double eventWeight) { + void DileptonAnalysis::emuAnalysis(const top::Event& topEvent, double eventWeight) { ++m_counterElMu; //does it pass some cuts? @@ -238,10 +219,10 @@ void DileptonAnalysis::emuAnalysis(const top::Event& topEvent, double eventWeigh const double ht = top::ht(topEvent); if (gteq2jets && ht > 120. * toGeV) { - m_histsElMu.hist("ht")->Fill(ht * toGeV, eventWeight); - top::fillPlots(topEvent, m_histsElMu, eventWeight); + m_histsElMu.hist("ht")->Fill(ht * toGeV, eventWeight); + top::fillPlots(topEvent, m_histsElMu, eventWeight); } -} + } /** * @brief Print cutflows for each of the three channels. Save any histograms @@ -250,7 +231,7 @@ void DileptonAnalysis::emuAnalysis(const top::Event& topEvent, double eventWeigh * * @param outputFile Root file to save the histograms to. */ -void DileptonAnalysis::finalise(TFile* outputFile) { + void DileptonAnalysis::finalise(TFile* outputFile) { //to screen std::cout << "Cutflows directly from the input files:\n"; printCutflow(std::cout, m_cutflowEventsElEl, m_cutflowMCWeightsElEl, "ee", m_counterElEl); @@ -259,10 +240,8 @@ void DileptonAnalysis::finalise(TFile* outputFile) { //tofile - mc use channel number, data use run number std::stringstream ss; - if (m_mcChannelNumber > 0) - ss << m_mcChannelNumber; - else - ss << m_runNumber; + if (m_mcChannelNumber > 0) ss << m_mcChannelNumber; + else ss << m_runNumber; std::ofstream cutflowfile_ee(ss.str() + "_ee_cutflow.txt"); std::ofstream cutflowfile_mumu(ss.str() + "_mumu_cutflow.txt"); @@ -279,8 +258,8 @@ void DileptonAnalysis::finalise(TFile* outputFile) { //if MC then calculate a SF to 1 fb-1 double sf = 1.; if (m_mcChannelNumber != 0) { - const double mcWeightsInSample = m_cutflowMCWeightsElEl->GetBinContent(1); - sf = sfToOneInversefb(m_mcChannelNumber, mcWeightsInSample); + const double mcWeightsInSample = m_cutflowMCWeightsElEl->GetBinContent(1); + sf = sfToOneInversefb(m_mcChannelNumber, mcWeightsInSample); } //save the plots for the three channels @@ -288,8 +267,7 @@ void DileptonAnalysis::finalise(TFile* outputFile) { m_histsMuMu.scaleHistograms(sf); m_histsElMu.scaleHistograms(sf); outputFile->Write(); - -} + } /** * @brief Prints the cutflow table to the screen or a file. This is not scaled @@ -308,28 +286,27 @@ void DileptonAnalysis::finalise(TFile* outputFile) { * @param localYield Yield that the local code ran over. It should match the * number from the grid (since you ran on the same events). */ -void DileptonAnalysis::printCutflow(std::ostream& out, const TH1D* const eventHist, const TH1D* const mcWeightHist, const std::string& name, const unsigned int localYield) { + void DileptonAnalysis::printCutflow(std::ostream& out, const TH1D* const eventHist, const TH1D* const mcWeightHist, + const std::string& name, const unsigned int localYield) { out << name << " cutflow:\n"; out << " " << - std::setw(4) << "Num" << - std::setw(30) << "Name" << - std::setw(20) << "Grid (Events)" << - std::setw(20) << "Grid (MC Weights)" << - std::setw(20) << "Local (Events)" << "\n"; + std::setw(4) << "Num" << + std::setw(30) << "Name" << + std::setw(20) << "Grid (Events)" << + std::setw(20) << "Grid (MC Weights)" << + std::setw(20) << "Local (Events)" << "\n"; for (int i = 1; i <= eventHist->GetNbinsX(); ++i) { - out << " " << std::setw(4) << i - << std::setw(30) << eventHist->GetXaxis()->GetBinLabel(i) - << std::setw(20) << eventHist->GetBinContent(i) - << std::setw(20) << mcWeightHist->GetBinContent(i); + out << " " << std::setw(4) << i + << std::setw(30) << eventHist->GetXaxis()->GetBinLabel(i) + << std::setw(20) << eventHist->GetBinContent(i) + << std::setw(20) << mcWeightHist->GetBinContent(i); - if (i == eventHist->GetNbinsX()) - out << std::setw(20) << localYield; + if (i == eventHist->GetNbinsX()) out << std::setw(20) << localYield; - out << "\n"; + out << "\n"; } out << "\n"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/EventLoaderDirect.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/EventLoaderDirect.cxx index bbcf69ec9151..96b7c4fc4089 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/EventLoaderDirect.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/EventLoaderDirect.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/EventLoaderDirect.h" @@ -16,68 +16,79 @@ #include "xAODTruth/TruthParticleContainer.h" namespace top { + EventLoaderDirect::EventLoaderDirect(const ContainerNames& names) : + m_containerNames(names) { + } -EventLoaderDirect::EventLoaderDirect(const ContainerNames& names) : - m_containerNames(names) { -} - -EventLoaderDirect::~EventLoaderDirect() { -} + EventLoaderDirect::~EventLoaderDirect() { + } -top::Event EventLoaderDirect::loadEvent(xAOD::TEvent& xaodEvent) { + top::Event EventLoaderDirect::loadEvent(xAOD::TEvent& xaodEvent) { top::Event te; //EventInfo - top::check(xaodEvent.retrieve(te.m_info, m_containerNames.eventInfoName), "xAOD::TEvent retrieve failed to get " + m_containerNames.eventInfoName); + top::check(xaodEvent.retrieve(te.m_info, + m_containerNames.eventInfoName), + "xAOD::TEvent retrieve failed to get " + m_containerNames.eventInfoName); //Electrons if (m_containerNames.electronCollectionName != "None") { - const xAOD::ElectronContainer* electrons(0); - top::check(xaodEvent.retrieve(electrons, m_containerNames.electronCollectionName), "xAOD::TEvent retrieve failed to get " + m_containerNames.electronCollectionName); - te.m_electrons = *electrons; + const xAOD::ElectronContainer* electrons(0); + top::check(xaodEvent.retrieve(electrons, + m_containerNames.electronCollectionName), + "xAOD::TEvent retrieve failed to get " + m_containerNames.electronCollectionName); + te.m_electrons = *electrons; } //Muons if (m_containerNames.muonCollectionName != "None") { - const xAOD::MuonContainer* muons(0); - top::check(xaodEvent.retrieve(muons, m_containerNames.muonCollectionName), "xAOD::TEvent retrieve failed to get " + m_containerNames.muonCollectionName); - te.m_muons = *muons; + const xAOD::MuonContainer* muons(0); + top::check(xaodEvent.retrieve(muons, + m_containerNames.muonCollectionName), + "xAOD::TEvent retrieve failed to get " + m_containerNames.muonCollectionName); + te.m_muons = *muons; } //Jets if (m_containerNames.jetCollectionName != "None") { - const xAOD::JetContainer* jets(0); - top::check(xaodEvent.retrieve(jets, m_containerNames.jetCollectionName), "xAOD::TEvent retrieve failed to get " + m_containerNames.jetCollectionName); - te.m_jets = *jets; + const xAOD::JetContainer* jets(0); + top::check(xaodEvent.retrieve(jets, + m_containerNames.jetCollectionName), + "xAOD::TEvent retrieve failed to get " + m_containerNames.jetCollectionName); + te.m_jets = *jets; } //LargeJets if (m_containerNames.largeJetCollectionName != "None") { - const xAOD::JetContainer* largeJets(0); - top::check(xaodEvent.retrieve(largeJets, m_containerNames.largeJetCollectionName), "xAOD::TEvent retrieve failed to get " + m_containerNames.largeJetCollectionName); - te.m_largeJets = *largeJets; + const xAOD::JetContainer* largeJets(0); + top::check(xaodEvent.retrieve(largeJets, + m_containerNames.largeJetCollectionName), + "xAOD::TEvent retrieve failed to get " + m_containerNames.largeJetCollectionName); + te.m_largeJets = *largeJets; } //Taus if (m_containerNames.tauCollectionName != "None") { - const xAOD::TauJetContainer* taus(0); - top::check(xaodEvent.retrieve(taus, m_containerNames.tauCollectionName), "xAOD::TEvent retrieve failed to get " + m_containerNames.tauCollectionName); - te.m_tauJets = *taus; + const xAOD::TauJetContainer* taus(0); + top::check(xaodEvent.retrieve(taus, + m_containerNames.tauCollectionName), + "xAOD::TEvent retrieve failed to get " + m_containerNames.tauCollectionName); + te.m_tauJets = *taus; } //MET if (m_containerNames.metName != "None") { - - const xAOD::MissingETContainer* mets(0); - check(xaodEvent.retrieve(mets, m_containerNames.metName), "xAOD::TEvent retrieve failed to get " + m_containerNames.metName); - te.m_met = (*mets)[MissingETBase::Source::total()]; - + const xAOD::MissingETContainer* mets(0); + check(xaodEvent.retrieve(mets, + m_containerNames.metName), + "xAOD::TEvent retrieve failed to get " + m_containerNames.metName); + te.m_met = (*mets)[MissingETBase::Source::total()]; } return te; -} + } -void EventLoaderDirect::print(std::ostream& os) const { + void EventLoaderDirect::print(std::ostream& os) const { os << "EventLoaderDirect Configuration\n"; os << "No object corrections and no object selection\n"; @@ -88,7 +99,5 @@ void EventLoaderDirect::print(std::ostream& os) const { os << "Jet ContainerName: " << m_containerNames.jetCollectionName << "\n"; os << "LargeJet ContainerName: " << m_containerNames.largeJetCollectionName << "\n"; os << "MET ContainerName: " << m_containerNames.metName << "\n"; + } } - -} - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsAnalysis.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsAnalysis.cxx index dff88a5bc5e6..f825145316f9 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsAnalysis.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsAnalysis.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/LJetsAnalysis.h" #include "TopExamples/DefaultPlots.h" @@ -17,18 +17,17 @@ #include <fstream> namespace top { - -LJetsAnalysis::LJetsAnalysis(TFile* outputFile, EL::Worker* wk) : - m_mcChannelNumber(0), - m_runNumber(0), - m_histsEl("ejets", outputFile, wk), - m_histsMu("mujets", outputFile, wk), - m_cutflowEventsEl(nullptr), - m_cutflowMCWeightsEl(nullptr), - m_cutflowEventsMu(nullptr), - m_cutflowMCWeightsMu(nullptr), - m_counterEl(0), - m_counterMu(0) { + LJetsAnalysis::LJetsAnalysis(TFile* outputFile, EL::Worker* wk) : + m_mcChannelNumber(0), + m_runNumber(0), + m_histsEl("ejets", outputFile, wk), + m_histsMu("mujets", outputFile, wk), + m_cutflowEventsEl(nullptr), + m_cutflowMCWeightsEl(nullptr), + m_cutflowEventsMu(nullptr), + m_cutflowMCWeightsMu(nullptr), + m_counterEl(0), + m_counterMu(0) { //add some default histograms for each channel top::addPlots(m_histsEl); top::addPlots(m_histsMu); @@ -36,46 +35,45 @@ LJetsAnalysis::LJetsAnalysis(TFile* outputFile, EL::Worker* wk) : //some extra histograms m_histsEl.addHist("mwt", ";MWT [GeV];Events", 20, 0, 200); m_histsMu.addHist("mwt", ";MWT [GeV];Events", 20, 0, 200); -} + } -LJetsAnalysis::~LJetsAnalysis() { -} + LJetsAnalysis::~LJetsAnalysis() { + } -void LJetsAnalysis::newFile(TFile* inputFile) { + void LJetsAnalysis::newFile(TFile* inputFile) { updateCutflow("ejets/cutflow", m_cutflowEventsEl, inputFile); updateCutflow("ejets/cutflow_mc", m_cutflowMCWeightsEl, inputFile); updateCutflow("mujets/cutflow", m_cutflowEventsMu, inputFile); updateCutflow("mujets/cutflow_mc", m_cutflowMCWeightsMu, inputFile); -} + } -void LJetsAnalysis::event(const top::Event& topEvent) { + void LJetsAnalysis::event(const top::Event& topEvent) { m_runNumber = topEvent.m_info->runNumber(); double eventWeight = 1.; if (top::isSimulation(topEvent)) { - m_mcChannelNumber = topEvent.m_info->mcChannelNumber(); -// eventWeight = topEvent.m_info->mcEventWeight(); - eventWeight = topEvent.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix + m_mcChannelNumber = topEvent.m_info->mcChannelNumber(); + eventWeight = topEvent.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); } //std::cout << topEvent << std::endl; if (top::passesPreSelection(topEvent, "ejets")) { - top::fillPlots(topEvent, m_histsEl, eventWeight); - const double mwt = top::mwt(*topEvent.m_electrons[0], *topEvent.m_met); - m_histsEl.hist("mwt")->Fill(mwt * top::toGeV, eventWeight); - ++m_counterEl; + top::fillPlots(topEvent, m_histsEl, eventWeight); + const double mwt = top::mwt(*topEvent.m_electrons[0], *topEvent.m_met); + m_histsEl.hist("mwt")->Fill(mwt * top::toGeV, eventWeight); + ++m_counterEl; } if (top::passesPreSelection(topEvent, "mujets")) { - top::fillPlots(topEvent, m_histsMu, eventWeight); - const double mwt = top::mwt(*topEvent.m_muons[0], *topEvent.m_met); - m_histsMu.hist("mwt")->Fill(mwt * top::toGeV, eventWeight); - ++m_counterMu; + top::fillPlots(topEvent, m_histsMu, eventWeight); + const double mwt = top::mwt(*topEvent.m_muons[0], *topEvent.m_met); + m_histsMu.hist("mwt")->Fill(mwt * top::toGeV, eventWeight); + ++m_counterMu; } -} + } -void LJetsAnalysis::finalise(TFile* outputFile) { + void LJetsAnalysis::finalise(TFile* outputFile) { //to screen std::cout << "Cutflows directly from the input files:\n"; printCutflow(std::cout, m_cutflowEventsEl, m_cutflowMCWeightsEl, "ejets", m_counterEl); @@ -83,10 +81,8 @@ void LJetsAnalysis::finalise(TFile* outputFile) { //tofile - mc use channel number, data use run number std::stringstream ss; - if (m_mcChannelNumber > 0) - ss << m_mcChannelNumber; - else - ss << m_runNumber; + if (m_mcChannelNumber > 0) ss << m_mcChannelNumber; + else ss << m_runNumber; std::ofstream cutflowfile_ejets(ss.str() + "_ejets_cutflow.txt"); std::ofstream cutflowfile_mujets(ss.str() + "_mujets_cutflow.txt"); @@ -100,14 +96,14 @@ void LJetsAnalysis::finalise(TFile* outputFile) { //normalise to 1 fb-1 for MC simulation double sf = 1.; if (m_mcChannelNumber != 0) { - const double mcWeightsInSample = m_cutflowMCWeightsEl->GetBinContent(1); - sf = sfToOneInversefb(m_mcChannelNumber, mcWeightsInSample); + const double mcWeightsInSample = m_cutflowMCWeightsEl->GetBinContent(1); + sf = sfToOneInversefb(m_mcChannelNumber, mcWeightsInSample); } m_histsEl.scaleHistograms(sf); m_histsMu.scaleHistograms(sf); outputFile->Write(); -} + } /** * @brief Prints the cutflow table to the screen or a file. This is not scaled @@ -126,28 +122,27 @@ void LJetsAnalysis::finalise(TFile* outputFile) { * @param localYield Yield that the local code ran over. It should match the * number from the grid (since you ran on the same events). */ -void LJetsAnalysis::printCutflow(std::ostream& out, const TH1D* const eventHist, const TH1D* const mcWeightHist, const std::string& name, const unsigned int localYield) { + void LJetsAnalysis::printCutflow(std::ostream& out, const TH1D* const eventHist, const TH1D* const mcWeightHist, + const std::string& name, const unsigned int localYield) { out << name << " cutflow:\n"; out << " " << - std::setw(4) << "Num" << - std::setw(20) << "Name" << - std::setw(20) << "Grid (Events)" << - std::setw(20) << "Grid (MC Weights)" << - std::setw(20) << "Local (Events)" << "\n"; + std::setw(4) << "Num" << + std::setw(20) << "Name" << + std::setw(20) << "Grid (Events)" << + std::setw(20) << "Grid (MC Weights)" << + std::setw(20) << "Local (Events)" << "\n"; for (int i = 1; i <= eventHist->GetNbinsX(); ++i) { - out << " " << std::setw(4) << i - << std::setw(20) << eventHist->GetXaxis()->GetBinLabel(i) - << std::setw(20) << eventHist->GetBinContent(i) - << std::setw(20) << mcWeightHist->GetBinContent(i); + out << " " << std::setw(4) << i + << std::setw(20) << eventHist->GetXaxis()->GetBinLabel(i) + << std::setw(20) << eventHist->GetBinContent(i) + << std::setw(20) << mcWeightHist->GetBinContent(i); - if (i == eventHist->GetNbinsX()) - out << std::setw(20) << localYield; + if (i == eventHist->GetNbinsX()) out << std::setw(20) << localYield; - out << "\n"; + out << "\n"; } out << "\n"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsTtresAnalysis.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsTtresAnalysis.cxx index 10b610aaff07..c185024f259a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsTtresAnalysis.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsTtresAnalysis.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/LJetsTtresAnalysis.h" #include "TopExamples/DefaultPlots.h" @@ -20,34 +20,31 @@ namespace top { - -LJetsTtresAnalysis::LJetsTtresAnalysis(TFile* outputFile) : - m_mcChannelNumber(0), - m_histsREl("rejets", outputFile), - m_histsRMu("rmujets", outputFile), - m_histsBEl("bejets", outputFile), - m_histsBMu("bmujets", outputFile), - m_cutflowEventsREl(nullptr), - m_cutflowMCWeightsREl(nullptr), - m_cutflowEventsRMu(nullptr), - m_cutflowMCWeightsRMu(nullptr), - m_cutflowEventsBEl(nullptr), - m_cutflowMCWeightsBEl(nullptr), - m_cutflowEventsBMu(nullptr), - m_cutflowMCWeightsBMu(nullptr), - m_counterREl(0), - m_counterRMu(0), - m_counterBEl(0), - m_counterBMu(0), - m_neutrinoBuilder("MeV"), - m_chi2("MeV") - { - + LJetsTtresAnalysis::LJetsTtresAnalysis(TFile* outputFile) : + m_mcChannelNumber(0), + m_histsREl("rejets", outputFile), + m_histsRMu("rmujets", outputFile), + m_histsBEl("bejets", outputFile), + m_histsBMu("bmujets", outputFile), + m_cutflowEventsREl(nullptr), + m_cutflowMCWeightsREl(nullptr), + m_cutflowEventsRMu(nullptr), + m_cutflowMCWeightsRMu(nullptr), + m_cutflowEventsBEl(nullptr), + m_cutflowMCWeightsBEl(nullptr), + m_cutflowEventsBMu(nullptr), + m_cutflowMCWeightsBMu(nullptr), + m_counterREl(0), + m_counterRMu(0), + m_counterBEl(0), + m_counterBMu(0), + m_neutrinoBuilder("MeV"), + m_chi2("MeV") { //tell it to load AKT10 SetContainerNames()->largeJetCollectionName = "CorrectedSelectedAntiKt10LCTopoTrimmedPtFrac30SmallR5Jets"; // AntiKt10LCTopoTrimmedPtFrac30SmallR5Jets //SetContainerNames()->largeJetCollectionName = "CorrectedSelectedAntiKt10LCTopoJets"; m_chi2.Init(TtresChi2::DATA2012SUMMER2013); - + //add some default histograms for each channel top::addPlots(m_histsREl); top::addPlots(m_histsRMu); @@ -115,12 +112,12 @@ LJetsTtresAnalysis::LJetsTtresAnalysis(TFile* outputFile) : m_histsBEl.addHist("mtt", ";boosted m_{tt} [GeV];Events", 30, 0, 3000); m_histsBMu.addHist("mtt", ";boosted m_{tt} [GeV];Events", 30, 0, 3000); -} + } -LJetsTtresAnalysis::~LJetsTtresAnalysis() { -} + LJetsTtresAnalysis::~LJetsTtresAnalysis() { + } -void LJetsTtresAnalysis::newFile(TFile* inputFile) { + void LJetsTtresAnalysis::newFile(TFile* inputFile) { updateCutflow("rejets/cutflow", m_cutflowEventsREl, inputFile); updateCutflow("rejets/cutflow_mc", m_cutflowMCWeightsREl, inputFile); updateCutflow("rmujets/cutflow", m_cutflowEventsRMu, inputFile); @@ -129,38 +126,38 @@ void LJetsTtresAnalysis::newFile(TFile* inputFile) { updateCutflow("bejets/cutflow_mc", m_cutflowMCWeightsBEl, inputFile); updateCutflow("bmujets/cutflow", m_cutflowEventsBMu, inputFile); updateCutflow("bmujets/cutflow_mc", m_cutflowMCWeightsBMu, inputFile); -} + } -void LJetsTtresAnalysis::fillIt(top::PlotManager &hists, const top::Event& topEvent, bool isBoosted) { + void LJetsTtresAnalysis::fillIt(top::PlotManager& hists, const top::Event& topEvent, bool isBoosted) { double eventWeight = 1.; + if (top::isSimulation(topEvent)) { - m_mcChannelNumber = topEvent.m_info->mcChannelNumber(); -// eventWeight = topEvent.m_info->mcEventWeight(); - eventWeight = topEvent.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix + m_mcChannelNumber = topEvent.m_info->mcChannelNumber(); + eventWeight = topEvent.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); } top::fillPlots(topEvent, hists, eventWeight); double mwt = -1; - if (topEvent.m_electrons.size() == 1) - mwt = top::mwt(*topEvent.m_electrons[0], *topEvent.m_met); - if (topEvent.m_muons.size() == 1) - mwt = top::mwt(*topEvent.m_muons[0], *topEvent.m_met); + if (topEvent.m_electrons.size() == 1) mwt = top::mwt(*topEvent.m_electrons[0], *topEvent.m_met); + if (topEvent.m_muons.size() == 1) mwt = top::mwt(*topEvent.m_muons[0], *topEvent.m_met); hists.hist("mwt")->Fill(mwt * top::toGeV, eventWeight); hists.hist("met")->Fill(topEvent.m_met->met() * top::toGeV, eventWeight); TLorentzVector lepton; - if (topEvent.m_electrons.size() == 1) - lepton.SetPtEtaPhiE(topEvent.m_electrons[0]->pt(), topEvent.m_electrons[0]->eta(), topEvent.m_electrons[0]->phi(), topEvent.m_electrons[0]->e()); - if (topEvent.m_muons.size() == 1) - lepton.SetPtEtaPhiE(topEvent.m_muons[0]->pt(), topEvent.m_muons[0]->eta(), topEvent.m_muons[0]->phi(), topEvent.m_muons[0]->e()); + if (topEvent.m_electrons.size() == 1) lepton.SetPtEtaPhiE( + topEvent.m_electrons[0]->pt(), topEvent.m_electrons[0]->eta(), + topEvent.m_electrons[0]->phi(), topEvent.m_electrons[0]->e()); + if (topEvent.m_muons.size() == 1) lepton.SetPtEtaPhiE(topEvent.m_muons[0]->pt(), + topEvent.m_muons[0]->eta(), + topEvent.m_muons[0]->phi(), topEvent.m_muons[0]->e()); hists.hist("lep_pt")->Fill(lepton.Pt() * top::toGeV, eventWeight); hists.hist("lep_eta")->Fill(lepton.Eta(), eventWeight); hists.hist("lep_phi")->Fill(lepton.Phi(), eventWeight); if (isBoosted) { - const xAOD::Jet *selJet = nullptr; + const xAOD::Jet* selJet = nullptr; for (const auto* const jetPtr : topEvent.m_jets) { if (jetPtr->auxdata<int>("closeToLepton") == 1) { selJet = jetPtr; @@ -168,7 +165,7 @@ void LJetsTtresAnalysis::fillIt(top::PlotManager &hists, const top::Event& topEv } } - const xAOD::Jet *largeJet = nullptr; + const xAOD::Jet* largeJet = nullptr; for (const auto* const jetPtr : topEvent.m_largeJets) { if (jetPtr->auxdata<int>("good") == 1) { largeJet = jetPtr; @@ -184,12 +181,15 @@ void LJetsTtresAnalysis::fillIt(top::PlotManager &hists, const top::Event& topEv hists.hist("ljetSel_eta")->Fill(largeJet->eta(), eventWeight); hists.hist("ljetSel_phi")->Fill(largeJet->phi(), eventWeight); - TLorentzVector tt(0,0,0,0); + TLorentzVector tt(0, 0, 0, 0); tt += largeJet->p4(); tt += lepton; tt += selJet->p4(); - std::vector<TLorentzVector*> vec_nu = m_neutrinoBuilder.candidatesFromWMass_Rotation(&lepton, topEvent.m_met->met(), topEvent.m_met->phi(), true); - TLorentzVector nu(0,0,0,0); + std::vector<TLorentzVector*> vec_nu = m_neutrinoBuilder.candidatesFromWMass_Rotation(&lepton, + topEvent.m_met->met(), + topEvent.m_met->phi(), + true); + TLorentzVector nu(0, 0, 0, 0); if (vec_nu.size() > 0) { nu = *(vec_nu[0]); for (size_t z = 0; z < vec_nu.size(); ++z) delete vec_nu[z]; @@ -210,30 +210,33 @@ void LJetsTtresAnalysis::fillIt(top::PlotManager &hists, const top::Event& topEv hists.hist("ljet_phi")->Fill(topEvent.m_largeJets[0]->phi(), eventWeight); } } else { // is resolved - // inputs + // inputs // LEPTON --> TLorentzVector for your lepton // vjets --> std::vector<TLorentzVector*> for the jets // vjets_btagged --> std::vector<bool> to say if the jets are btagged or not // met --> TLorentzVector for your MET // outputs, they will be filled by the TTBarLeptonJetsBuilder_chi2 - int igj3, igj4; // index for the Whad + int igj3, igj4; // index for the Whad int igb3, igb4; // index for the b's - int ign1; // index for the neutrino (because chi2 can test both pz solution) + int ign1; // index for the neutrino (because chi2 can test both pz solution) double chi2ming1, chi2ming1H, chi2ming1L; - std::vector<TLorentzVector *> vjets; + std::vector<TLorentzVector*> vjets; std::vector<bool> vjets_btagged; for (size_t z = 0; z < topEvent.m_jets.size(); ++z) { - vjets.push_back(new TLorentzVector(0,0,0,0)); - vjets[z]->SetPtEtaPhiE(topEvent.m_jets[z]->pt(), topEvent.m_jets[z]->eta(), topEvent.m_jets[z]->phi(), topEvent.m_jets[z]->e()); - const xAOD::BTagging *myBTag = topEvent.m_jets[z]->btagging(); + vjets.push_back(new TLorentzVector(0, 0, 0, 0)); + vjets[z]->SetPtEtaPhiE(topEvent.m_jets[z]->pt(), topEvent.m_jets[z]->eta(), + topEvent.m_jets[z]->phi(), topEvent.m_jets[z]->e()); + const xAOD::BTagging* myBTag = topEvent.m_jets[z]->btagging(); // https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/BTagingxAODEDM // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/BTaggingBenchmarks - vjets_btagged.push_back(myBTag->SV1plusIP3D_discriminant() > 1.85); // best discriminant available for 8 TeV (cut at 70%) + vjets_btagged.push_back(myBTag->SV1plusIP3D_discriminant() > 1.85); // best discriminant available for 8 TeV + // (cut at 70%) } - TLorentzVector met(0,0,0,0); + TLorentzVector met(0, 0, 0, 0); met.SetPtEtaPhiM(topEvent.m_met->met(), 0, topEvent.m_met->phi(), 0); - bool status = m_chi2.findMinChiSquare(&lepton, &vjets, &vjets_btagged, &met, igj3, igj4, igb3, igb4, ign1, chi2ming1, chi2ming1H, chi2ming1L); // status has to be true + bool status = m_chi2.findMinChiSquare(&lepton, &vjets, &vjets_btagged, &met, igj3, igj4, igb3, igb4, ign1, + chi2ming1, chi2ming1H, chi2ming1L); // status has to be true double mtt = -1; if (status) mtt = m_chi2.getResult_Mtt(); @@ -244,20 +247,21 @@ void LJetsTtresAnalysis::fillIt(top::PlotManager &hists, const top::Event& topEv vjets.clear(); vjets_btagged.clear(); } -} + } -void LJetsTtresAnalysis::event(const top::Event& topEvent) { + void LJetsTtresAnalysis::event(const top::Event& topEvent) { double eventWeight = 1.; + if (top::isSimulation(topEvent)) { - m_mcChannelNumber = topEvent.m_info->mcChannelNumber(); + m_mcChannelNumber = topEvent.m_info->mcChannelNumber(); // eventWeight = topEvent.m_info->mcEventWeight(); - eventWeight = topEvent.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix + eventWeight = topEvent.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix } int pass_rejets = top::passesPreSelection(topEvent, "rejets"); int pass_rmujets = top::passesPreSelection(topEvent, "rmujets"); - int pass_bejets = top::passesPreSelection(topEvent, "bejets"); + int pass_bejets = top::passesPreSelection(topEvent, "bejets"); int pass_bmujets = top::passesPreSelection(topEvent, "bmujets"); if (pass_rejets) fillIt(m_histsREl, topEvent, false); @@ -268,54 +272,37 @@ void LJetsTtresAnalysis::event(const top::Event& topEvent) { // fill overlap histogram with 1 if there is an overlap // fill it with 0 for resolved only or 2 if it is boosted only - if (pass_rejets && pass_bejets) - m_histsREl.hist("overlap")->Fill(1.0, eventWeight); + if (pass_rejets && pass_bejets) m_histsREl.hist("overlap")->Fill(1.0, eventWeight); - if (pass_rejets && !pass_bejets) - m_histsREl.hist("overlap")->Fill(0.0, eventWeight); + if (pass_rejets && !pass_bejets) m_histsREl.hist("overlap")->Fill(0.0, eventWeight); - if (!pass_rejets && pass_bejets) - m_histsREl.hist("overlap")->Fill(2.0, eventWeight); + if (!pass_rejets && pass_bejets) m_histsREl.hist("overlap")->Fill(2.0, eventWeight); - if (pass_rmujets && pass_bmujets) - m_histsRMu.hist("overlap")->Fill(1.0, eventWeight); + if (pass_rmujets && pass_bmujets) m_histsRMu.hist("overlap")->Fill(1.0, eventWeight); - if (pass_rmujets && !pass_bmujets) - m_histsRMu.hist("overlap")->Fill(0.0, eventWeight); + if (pass_rmujets && !pass_bmujets) m_histsRMu.hist("overlap")->Fill(0.0, eventWeight); - if (!pass_rmujets && pass_bmujets) - m_histsRMu.hist("overlap")->Fill(2.0, eventWeight); + if (!pass_rmujets && pass_bmujets) m_histsRMu.hist("overlap")->Fill(2.0, eventWeight); - if (pass_rejets && pass_bejets) - m_histsBEl.hist("overlap")->Fill(1.0, eventWeight); + if (pass_rejets && pass_bejets) m_histsBEl.hist("overlap")->Fill(1.0, eventWeight); - if (pass_rejets && !pass_bejets) - m_histsBEl.hist("overlap")->Fill(0.0, eventWeight); + if (pass_rejets && !pass_bejets) m_histsBEl.hist("overlap")->Fill(0.0, eventWeight); - if (!pass_rejets && pass_bejets) - m_histsBEl.hist("overlap")->Fill(2.0, eventWeight); + if (!pass_rejets && pass_bejets) m_histsBEl.hist("overlap")->Fill(2.0, eventWeight); - if (pass_rmujets && pass_bmujets) - m_histsBMu.hist("overlap")->Fill(1.0, eventWeight); + if (pass_rmujets && pass_bmujets) m_histsBMu.hist("overlap")->Fill(1.0, eventWeight); - if (pass_rmujets && !pass_bmujets) - m_histsBMu.hist("overlap")->Fill(0.0, eventWeight); + if (pass_rmujets && !pass_bmujets) m_histsBMu.hist("overlap")->Fill(0.0, eventWeight); - if (!pass_rmujets && pass_bmujets) - m_histsBMu.hist("overlap")->Fill(2.0, eventWeight); + if (!pass_rmujets && pass_bmujets) m_histsBMu.hist("overlap")->Fill(2.0, eventWeight); - if (pass_rejets) - m_counterREl++; - if (pass_rmujets) - m_counterRMu++; - if (pass_bejets) - m_counterBEl++; - if (pass_bmujets) - m_counterBMu++; - -} + if (pass_rejets) m_counterREl++; + if (pass_rmujets) m_counterRMu++; + if (pass_bejets) m_counterBEl++; + if (pass_bmujets) m_counterBMu++; + } -void LJetsTtresAnalysis::finalise(TFile* outputFile) { + void LJetsTtresAnalysis::finalise(TFile* outputFile) { std::cout << "Cutflows directly from the input files:\n"; printCutflow(m_cutflowEventsREl, m_cutflowMCWeightsREl, "rejets", m_counterREl); printCutflow(m_cutflowEventsRMu, m_cutflowMCWeightsRMu, "rmujets", m_counterRMu); @@ -326,8 +313,8 @@ void LJetsTtresAnalysis::finalise(TFile* outputFile) { //normalise to 1 fb-1 for MC simulation double sf = 1.; if (m_mcChannelNumber != 0) { - const double mcWeightsInSample = m_cutflowMCWeightsREl->GetBinContent(1); - sf = sfToOneInversefb(m_mcChannelNumber, mcWeightsInSample); + const double mcWeightsInSample = m_cutflowMCWeightsREl->GetBinContent(1); + sf = sfToOneInversefb(m_mcChannelNumber, mcWeightsInSample); } m_histsREl.scaleHistograms(sf); @@ -336,31 +323,29 @@ void LJetsTtresAnalysis::finalise(TFile* outputFile) { m_histsBEl.scaleHistograms(sf); m_histsBMu.scaleHistograms(sf); outputFile->Write(); -} - + } -void LJetsTtresAnalysis::printCutflow(TH1D* eventHist, TH1D* mcWeightHist, const std::string& name, unsigned int localYield) { + void LJetsTtresAnalysis::printCutflow(TH1D* eventHist, TH1D* mcWeightHist, const std::string& name, + unsigned int localYield) { std::cout << name << " cutflow:\n"; - std::cout << " " << - std::setw(4) << "Num" << - std::setw(20) << "Name" << - std::setw(20) << "Grid (Events)" << - std::setw(20) << "Grid (MC Weights)" << - std::setw(20) << "Local (Events)" << "\n"; + std::cout << " " << + std::setw(4) << "Num" << + std::setw(20) << "Name" << + std::setw(20) << "Grid (Events)" << + std::setw(20) << "Grid (MC Weights)" << + std::setw(20) << "Local (Events)" << "\n"; for (int i = 1; i <= eventHist->GetNbinsX(); ++i) { - std::cout << " " << std::setw(4) << i + std::cout << " " << std::setw(4) << i << std::setw(20) << eventHist->GetXaxis()->GetBinLabel(i) << std::setw(20) << eventHist->GetBinContent(i) << std::setw(20) << mcWeightHist->GetBinContent(i); - if (i == eventHist->GetNbinsX()) - std::cout << std::setw(20) << localYield; + if (i == eventHist->GetNbinsX()) std::cout << std::setw(20) << localYield; - std::cout << "\n"; + std::cout << "\n"; } std::cout << "\n"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MakeTopConfig.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MakeTopConfig.cxx index ed837826902d..fdf30956a474 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MakeTopConfig.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MakeTopConfig.cxx @@ -1,27 +1,27 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/MakeTopConfig.h" #include "TopConfiguration/TopConfig.h" #include "TopConfiguration/TopPersistentSettings.h" #include "TopEvent/EventTools.h" -namespace top{ - MakeTopConfig::MakeTopConfig( const std::string& name ) : - asg::AsgMetadataTool( name ) - { +namespace top { + MakeTopConfig::MakeTopConfig(const std::string& name) : + asg::AsgMetadataTool(name) { } - - std::shared_ptr<top::TopConfig> MakeTopConfig::makeTopConfig() - { + + std::shared_ptr<top::TopConfig> MakeTopConfig::makeTopConfig() { ///-- Get the settings from the input file const top::TopPersistentSettings* settings(nullptr); - top::check( inputMetaStore()->retrieve(settings,"TopPersistentSettings") , "Failed to retrieve TopPersistentSettings"); - + + top::check(inputMetaStore()->retrieve(settings, "TopPersistentSettings"), + "Failed to retrieve TopPersistentSettings"); + ///-- Create the top::TopConfig from the TopPersistentSettings --/// - std::shared_ptr<top::TopConfig> config( new top::TopConfig( settings ) ); - + std::shared_ptr<top::TopConfig> config(new top::TopConfig(settings)); + return config; } } \ No newline at end of file diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MiniToFlatAnalysis.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MiniToFlatAnalysis.cxx index 6e5577de23e0..8993881a7a03 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MiniToFlatAnalysis.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MiniToFlatAnalysis.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/MiniToFlatAnalysis.h" @@ -29,20 +29,21 @@ namespace top { m_outputFileName("SetMe"), m_outputFile(nullptr) { - declareProperty("config" , m_config); - declareProperty("outputFileName" , m_outputFileName = "miniout.root"); + declareProperty("config", m_config); + declareProperty("outputFileName", m_outputFileName = "miniout.root"); } StatusCode MiniToFlatAnalysis::initialize() { m_topTools = std::unique_ptr<top::TopToolStore> (new top::TopToolStore("top::TopToolStore")); - top::check(m_topTools->setProperty("config", m_config) , + top::check(m_topTools->setProperty("config", m_config), "Failed to set config for topTools"); - top::check(m_topTools->initialize() , "Failed to initialize"); + top::check(m_topTools->initialize(), "Failed to initialize"); - m_sfCalc = std::unique_ptr<top::ScaleFactorCalculator> (new top::ScaleFactorCalculator("top::ScaleFactorCalculator")); - top::check(m_sfCalc->setProperty("config", m_config) , + m_sfCalc = + std::unique_ptr<top::ScaleFactorCalculator> (new top::ScaleFactorCalculator("top::ScaleFactorCalculator")); + top::check(m_sfCalc->setProperty("config", m_config), "Failed to set config for sfCalc"); - top::check(m_sfCalc->initialize() , "Failed to initialize"); + top::check(m_sfCalc->initialize(), "Failed to initialize"); m_evtMaker = std::unique_ptr<top::TopEventMaker>(new top::TopEventMaker("top::TopEventMaker")); top::check(m_evtMaker->setProperty("config", m_config), @@ -59,14 +60,15 @@ namespace top { StatusCode MiniToFlatAnalysis::execute() { // Re-do Scale Factors - You cannot do this with a flat ntuple - top::check(m_sfCalc->execute() , "Failed to calculate scale factors"); + top::check(m_sfCalc->execute(), "Failed to calculate scale factors"); - const xAOD::SystematicEventContainer* allSystematics = m_evtMaker->systematicEvents(m_config->sgKeyTopSystematicEvents()); + const xAOD::SystematicEventContainer* allSystematics = m_evtMaker->systematicEvents( + m_config->sgKeyTopSystematicEvents()); // ATH_MSG_INFO(" Total number of SystematicEvents (inc Nominal) = "<<allSystematics->size()); for (auto currentSystematic : *allSystematics) { // Make a top::Event - top::Event topEvent = m_evtMaker->makeTopEvent(*currentSystematic); + top::Event topEvent = m_evtMaker->makeTopEvent(currentSystematic); topEvent.m_saveEvent = false; // Reset the ttree indicies (probably should be done somewhere else) @@ -89,12 +91,10 @@ namespace top { return StatusCode::SUCCESS; } - StatusCode MiniToFlatAnalysis::finalize() { m_outputFile->cd(); m_event_saver->finalize(); return StatusCode::SUCCESS; } - } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MinixAODAnalysis.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MinixAODAnalysis.cxx index 7500728ba29c..68b74c4025b3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MinixAODAnalysis.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/MinixAODAnalysis.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples//MinixAODAnalysis.h" @@ -18,120 +18,112 @@ #include "TFile.h" #include "TDirectoryFile.h" -namespace top{ - MinixAODAnalysis::MinixAODAnalysis( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + MinixAODAnalysis::MinixAODAnalysis(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), - + m_topTools(nullptr), m_sfCalc(nullptr), m_evtMaker(nullptr), - + m_outputFileName("SetMe"), m_outputFile(nullptr), - + m_firstEvent(true), m_sampleName("SetMe"), - m_plots() - { - declareProperty( "config" , m_config ); - declareProperty( "outputFileName" , m_outputFileName = "miniout.root" ); - declareProperty( "sampleName" , m_sampleName = "Example" ); + m_plots() { + declareProperty("config", m_config); + declareProperty("outputFileName", m_outputFileName = "miniout.root"); + declareProperty("sampleName", m_sampleName = "Example"); } - - StatusCode MinixAODAnalysis::initialize() - { - - m_topTools = std::unique_ptr<top::TopToolStore> ( new top::TopToolStore( "top::TopToolStore" ) ); - top::check( m_topTools->setProperty("config",m_config) , "Failed to set property" ); - top::check( m_topTools->initialize() , "Failed to initialize" ); - - m_sfCalc = std::unique_ptr<top::ScaleFactorCalculator> ( new top::ScaleFactorCalculator( "top::ScaleFactorCalculator" ) ); - top::check( m_sfCalc->setProperty("config",m_config) , "Failed to set property" ); - top::check( m_sfCalc->initialize() , "Failed to initialize" ); - - m_evtMaker = std::unique_ptr<top::TopEventMaker> ( new top::TopEventMaker( "top::TopEventMaker" ) ); - top::check( m_evtMaker->setProperty("config",m_config) , "Failed to set property" ); - top::check( m_evtMaker->initialize() , "Failed to initialize" ); - - m_outputFile = new TFile(m_outputFileName.c_str(),"RECREATE"); - - + + StatusCode MinixAODAnalysis::initialize() { + m_topTools = std::unique_ptr<top::TopToolStore> (new top::TopToolStore("top::TopToolStore")); + top::check(m_topTools->setProperty("config", m_config), "Failed to set property"); + top::check(m_topTools->initialize(), "Failed to initialize"); + + m_sfCalc = + std::unique_ptr<top::ScaleFactorCalculator> (new top::ScaleFactorCalculator("top::ScaleFactorCalculator")); + top::check(m_sfCalc->setProperty("config", m_config), "Failed to set property"); + top::check(m_sfCalc->initialize(), "Failed to initialize"); + + m_evtMaker = std::unique_ptr<top::TopEventMaker> (new top::TopEventMaker("top::TopEventMaker")); + top::check(m_evtMaker->setProperty("config", m_config), "Failed to set property"); + top::check(m_evtMaker->initialize(), "Failed to initialize"); + + m_outputFile = new TFile(m_outputFileName.c_str(), "RECREATE"); + + return StatusCode::SUCCESS; } - - StatusCode MinixAODAnalysis::execute() - { - + + StatusCode MinixAODAnalysis::execute() { ///-- Re-do Scale Factors - You cannot do this with a flat ntuple --/// - top::check( m_sfCalc->execute() , "Failed to calculate scale factors" ); + top::check(m_sfCalc->execute(), "Failed to calculate scale factors"); - const xAOD::SystematicEventContainer* allSystematics = m_evtMaker->systematicEvents( m_config->sgKeyTopSystematicEvents() ); + const xAOD::SystematicEventContainer* allSystematics = m_evtMaker->systematicEvents( + m_config->sgKeyTopSystematicEvents()); // ATH_MSG_INFO(" Total number of SystematicEvents (inc Nominal) = "<<allSystematics->size()); - + ///-- OK, this is a bit ugly, it will be cleaned up massively in future versions --/// ///-- This is a demonstration program only --/// - - + + if (m_firstEvent) { m_firstEvent = false; - + // Setup a top::PlotManager for each channel and each syst for (auto channel : *m_config->allSelectionNames()) { - std::unordered_map<std::string,top::PlotManager*> channelPlotMap; + std::unordered_map<std::string, top::PlotManager*> channelPlotMap; for (auto currentSystematic : *allSystematics) { - channelPlotMap.insert( std::make_pair( - m_config->systematicName( currentSystematic->hashValue() ) , - new top::PlotManager(m_sampleName,channel,m_config->systematicName( currentSystematic->hashValue() ) ,m_outputFile) - ) ); + channelPlotMap.insert(std::make_pair( + m_config->systematicName(currentSystematic->hashValue()), + new top::PlotManager(m_sampleName, channel, + m_config->systematicName(currentSystematic->hashValue()), + m_outputFile) + )); } - m_plots.insert( std::make_pair( channel , channelPlotMap ) ); + m_plots.insert(std::make_pair(channel, channelPlotMap)); } - - for (Itr i=m_plots.begin();i!=m_plots.end();++i) { - for (Itr2 j=(*i).second.begin();j!=(*i).second.end();++j) { - top::addPlots( *((*j).second) ); + + for (Itr i = m_plots.begin(); i != m_plots.end(); ++i) { + for (Itr2 j = (*i).second.begin(); j != (*i).second.end(); ++j) { + top::addPlots(*((*j).second)); } } - } - + for (auto currentSystematic : *allSystematics) { ///-- Make a top::Event --/// - top::Event topEvent = m_evtMaker->makeTopEvent( *currentSystematic ); + top::Event topEvent = m_evtMaker->makeTopEvent(currentSystematic); ///-- Loop over all selections --/// for (auto sel : *m_config->allSelectionNames()) { - Itr channelPlotMap = m_plots.find( sel ); + Itr channelPlotMap = m_plots.find(sel); if (channelPlotMap != m_plots.end()) { - ///-- If selection passes, plot the top::Event --/// - if (currentSystematic->isAvailable<int>(sel)){ + if (currentSystematic->isAvailable<int>(sel)) { bool passSelection = currentSystematic->auxdataConst<int>(sel) == 1 ? true : false; - if (passSelection){ - - Itr2 systPlotMap = (*channelPlotMap).second.find( m_config->systematicName( currentSystematic->hashValue() ) ); + if (passSelection) { + Itr2 systPlotMap = + (*channelPlotMap).second.find(m_config->systematicName(currentSystematic->hashValue())); if (systPlotMap != (*channelPlotMap).second.end()) { - top::fillPlots(topEvent ,*((*systPlotMap).second) , 1. ); + top::fillPlots(topEvent, *((*systPlotMap).second), 1.); } - } - } } } } - - return StatusCode::SUCCESS; + + return StatusCode::SUCCESS; } - - - StatusCode MinixAODAnalysis::finalize() - { + + StatusCode MinixAODAnalysis::finalize() { m_outputFile->cd(); m_outputFile->Write(); - - return StatusCode::SUCCESS; + + return StatusCode::SUCCESS; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/NoSelectionAnalysis.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/NoSelectionAnalysis.cxx index 06738694bfa3..f2a52c5c4133 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/NoSelectionAnalysis.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/NoSelectionAnalysis.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopExamples/NoSelectionAnalysis.h" #include "TopExamples/DefaultPlots.h" @@ -15,65 +15,61 @@ #include <iostream> namespace top { - -NoSelectionAnalysis::NoSelectionAnalysis(TFile* outputFile, EL::Worker* wk) : - m_hists("all", outputFile, wk), - m_cutflowEvents(nullptr), - m_cutflowMCWeights(nullptr), - m_counter(0) { + NoSelectionAnalysis::NoSelectionAnalysis(TFile* outputFile, EL::Worker* wk) : + m_hists("all", outputFile, wk), + m_cutflowEvents(nullptr), + m_cutflowMCWeights(nullptr), + m_counter(0) { top::addPlots(m_hists); -} + } -NoSelectionAnalysis::~NoSelectionAnalysis() { -} + NoSelectionAnalysis::~NoSelectionAnalysis() { + } -void NoSelectionAnalysis::newFile(TFile* inputFile) { + void NoSelectionAnalysis::newFile(TFile* inputFile) { top::updateCutflow("all/cutflow", m_cutflowEvents, inputFile); top::updateCutflow("all/cutflow_mc", m_cutflowMCWeights, inputFile); -} + } -void NoSelectionAnalysis::event(const top::Event& topEvent) { + void NoSelectionAnalysis::event(const top::Event& topEvent) { ++m_counter; double eventWeight = 1.; - if (top::isSimulation(topEvent)) -// eventWeight = topEvent.m_info->mcEventWeight(); - eventWeight = topEvent.m_truthEvent->at(0)->weights()[0];// FIXME temporary bugfix + if (top::isSimulation(topEvent)) eventWeight = topEvent.m_info->auxdataConst<float>("AnalysisTop_eventWeight"); //std::cout << topEvent << std::endl; top::fillPlots(topEvent, m_hists, eventWeight); -} + } -void NoSelectionAnalysis::finalise(TFile* outputFile) { + void NoSelectionAnalysis::finalise(TFile* outputFile) { std::cout << "Cutflow directly from the input files:\n"; printCutflow(m_cutflowEvents, m_cutflowMCWeights, "all", m_counter); //write out plots outputFile->Write(); -} + } -void NoSelectionAnalysis::printCutflow(TH1D* eventHist, TH1D* mcWeightHist, const std::string& name, unsigned int localYield) { + void NoSelectionAnalysis::printCutflow(TH1D* eventHist, TH1D* mcWeightHist, const std::string& name, + unsigned int localYield) { std::cout << name << " cutflow:\n"; - std::cout << " " << - std::setw(4) << "Num" << - std::setw(20) << "Name" << - std::setw(20) << "Grid (Events)" << - std::setw(20) << "Grid (MC Weights)" << - std::setw(20) << "Local (Events)" << "\n"; + std::cout << " " << + std::setw(4) << "Num" << + std::setw(20) << "Name" << + std::setw(20) << "Grid (Events)" << + std::setw(20) << "Grid (MC Weights)" << + std::setw(20) << "Local (Events)" << "\n"; for (int i = 1; i <= eventHist->GetNbinsX(); ++i) { - std::cout << " " << std::setw(4) << i + std::cout << " " << std::setw(4) << i << std::setw(20) << eventHist->GetXaxis()->GetBinLabel(i) << std::setw(20) << eventHist->GetBinContent(i) << std::setw(20) << mcWeightHist->GetBinContent(i); - if (i == eventHist->GetNbinsX()) - std::cout << std::setw(20) << localYield; + if (i == eventHist->GetNbinsX()) std::cout << std::setw(20) << localYield; - std::cout << "\n"; + std::cout << "\n"; } std::cout << "\n"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/AnalysisBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/AnalysisBase.h index 0b7568412561..99735ec98883 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/AnalysisBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/AnalysisBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISBASE_H_ #define ANALYSISBASE_H_ @@ -10,21 +10,21 @@ class TFile; namespace top { -class Event; + class Event; /** * @brief An interface so that the analysis codes look the same and can be * run by the mini-to-plots executable. */ -class AnalysisBase { -public: + class AnalysisBase { + public: /** * @brief This is run once only at the very start. You might want to book * some histograms or something. */ AnalysisBase() { - //container names - m_containerNames.eventInfoName ="EventInfo"; + //container names + m_containerNames.eventInfoName = "EventInfo"; m_containerNames.electronCollectionName = "CorrectedSelectedElectrons"; m_containerNames.muonCollectionName = "CorrectedSelectedMuons"; m_containerNames.jetCollectionName = "CorrectedSelectedAntiKt4EMTopoJets"; @@ -63,14 +63,12 @@ public: */ virtual void finalise(TFile*) = 0; - const ContainerNames containerNames() const { return m_containerNames; } - - ContainerNames* SetContainerNames() { return &m_containerNames; } + const ContainerNames containerNames() const {return m_containerNames;} -private: + ContainerNames* SetContainerNames() {return &m_containerNames;} + private: top::ContainerNames m_containerNames; -}; - + }; } #endif /* ANALYSISBASE_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/AnalysisTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/AnalysisTools.h index da27cc947fe1..649cd8490d02 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/AnalysisTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/AnalysisTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOOLS_H #define ANALYSISTOOLS_H @@ -19,15 +19,14 @@ namespace EL { } /** - * @file TopExamples/AnalysisTools.h + * @file AnalysisTools.h * * @brief A few functions for analysis code in the final stages. */ namespace top { - ///Sometimes you want things in GeV, no. Do by multiplication. -const double toGeV = 0.001; + const double toGeV = 0.001; /** * @brief Load one of the three analyses in a factory like way. @@ -42,7 +41,7 @@ const double toGeV = 0.001; * @return a unique ptr (these things are magic, they delete themselves when they * are no longer needed) to the analysis code. */ -std::unique_ptr<top::AnalysisBase> loadAnalysis(const std::string& name, TFile* outputFile, EL::Worker* wk=nullptr); + std::unique_ptr<top::AnalysisBase> loadAnalysis(const std::string& name, TFile* outputFile, EL::Worker* wk = nullptr); /** * @brief Open an xAOD and return the sample number as a string. @@ -58,7 +57,7 @@ std::unique_ptr<top::AnalysisBase> loadAnalysis(const std::string& name, TFile* * * @return run number for data, MC channel number for MC simulation. */ -const std::string getSampleNumberAsString(const std::string& filename, const std::string& infoContainerName); + const std::string getSampleNumberAsString(const std::string& filename, const std::string& infoContainerName); /** * @brief Calculate a scale factor to one inverse fb given the sum of weights @@ -71,7 +70,7 @@ const std::string getSampleNumberAsString(const std::string& filename, const std * section using TopDataPreparation * @param mcWeightsInSample The sum of the MC weights in the MC sample */ -double sfToOneInversefb(unsigned int mcChannelNumber, double mcWeightsInSample); + double sfToOneInversefb(unsigned int mcChannelNumber, double mcWeightsInSample); /** * @brief We want to add a histogram with name "name" from file "inputFile" to @@ -85,7 +84,7 @@ double sfToOneInversefb(unsigned int mcChannelNumber, double mcWeightsInSample); * modified by this function! * @param inputFile The inputFile to read the histogram from. */ -void updateCutflow(const std::string& name, TH1D*& histogram, TFile* inputFile); + void updateCutflow(const std::string& name, TH1D*& histogram, TFile* inputFile); /** * @brief Messy. @@ -98,7 +97,7 @@ void updateCutflow(const std::string& name, TH1D*& histogram, TFile* inputFile); * @param inputFile A path with a specific naming convention for the last directory. * @return The e<blah>_s<blah>_r<blah> or equivalent. */ -std::string gridTagFromDirectoryName(const std::string inputFile); + std::string gridTagFromDirectoryName(const std::string inputFile); /** * @brief The top-xaod code is decorating events with a integer (not bool!) @@ -111,8 +110,7 @@ std::string gridTagFromDirectoryName(const std::string inputFile); * @param name The channel we're interested in. e.g. ee * @return True if the event passed the grid selection, false otherwise. */ -bool passesPreSelection(const top::Event& topEvent, const std::string& name); - + bool passesPreSelection(const top::Event& topEvent, const std::string& name); } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/ContainerNames.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/ContainerNames.h index da373bec6f88..d2496e6c0451 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/ContainerNames.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/ContainerNames.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef CONTAINERNAMES_H_ #define CONTAINERNAMES_H_ @@ -8,8 +8,7 @@ #include <string> namespace top { - -struct ContainerNames { + struct ContainerNames { std::string eventInfoName; std::string electronCollectionName; std::string muonCollectionName; @@ -18,10 +17,9 @@ struct ContainerNames { std::string metName; std::string tauCollectionName; std::string truthCollectionName; -}; - + }; } -std::ostream& operator<<(std::ostream& os, const top::ContainerNames& names); +std::ostream& operator << (std::ostream& os, const top::ContainerNames& names); #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/DefaultPlots.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/DefaultPlots.h index 6b1e6238de55..d60e0be9908a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/DefaultPlots.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/DefaultPlots.h @@ -1,13 +1,13 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef DEFAULTPLOTS_H_ #define DEFAULTPLOTS_H_ namespace top { -class PlotManager; -class Event; + class PlotManager; + class Event; /** * @brief Since a few of the analyses might want some 'default' plots we've put @@ -18,7 +18,7 @@ class Event; * @param manager This is a little package that lets you store a bunch of * histograms and then refer to them by name. */ -void addPlots(top::PlotManager& manager); + void addPlots(top::PlotManager& manager); /** * @brief Fill the plots made by the addPlots function. This should be run every @@ -30,8 +30,7 @@ void addPlots(top::PlotManager& manager); * @param eventWeight Maybe you're running on MC simulation and the events are * weighted and you want to plot them with weights? */ -void fillPlots(const top::Event& topEvent, top::PlotManager& manager, double eventWeight); - + void fillPlots(const top::Event& topEvent, top::PlotManager& manager, double eventWeight); } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/DileptonAnalysis.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/DileptonAnalysis.h index 33bc7a81cff3..430a9a5d2d9f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/DileptonAnalysis.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/DileptonAnalysis.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef DILEPTONANALYSIS_H_ #define DILEPTONANALYSIS_H_ @@ -16,22 +16,21 @@ namespace EL { } namespace top { - -class DileptonAnalysis : public AnalysisBase { -public: - DileptonAnalysis(TFile* outputFile, EL::Worker* wk=nullptr); + class DileptonAnalysis: public AnalysisBase { + public: + DileptonAnalysis(TFile* outputFile, EL::Worker* wk = nullptr); ~DileptonAnalysis(); void newFile(TFile* inputFile) override; void event(const top::Event& topEvent) override; void finalise(TFile* outputFile) override; - -private: + private: void eeAnalysis(const top::Event& topEvent, double eventWeight); void mumuAnalysis(const top::Event& topEvent, double eventWeight); void emuAnalysis(const top::Event& topEvent, double eventWeight); - void printCutflow(std::ostream& out, const TH1D* const eventHist, const TH1D* const mcWeightHist, const std::string& name, const unsigned int localYield); + void printCutflow(std::ostream& out, const TH1D* const eventHist, const TH1D* const mcWeightHist, + const std::string& name, const unsigned int localYield); ///MC Channel number is needed to calculate the SF (to 1 fb-1) at the end of the job unsigned int m_mcChannelNumber; @@ -56,8 +55,7 @@ private: unsigned int m_counterElEl; unsigned int m_counterMuMu; unsigned int m_counterElMu; -}; - + }; } #endif /* DILEPTONANALYSIS_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/EventLoaderDirect.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/EventLoaderDirect.h index bfcb184a5c78..6102101f7086 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/EventLoaderDirect.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/EventLoaderDirect.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef LOADALL_H_ #define LOADALL_H_ @@ -10,9 +10,8 @@ #include "TopEvent/Event.h" namespace top { - -class EventLoaderDirect { -public: + class EventLoaderDirect { + public: EventLoaderDirect(const ContainerNames& names); ~EventLoaderDirect(); @@ -22,13 +21,11 @@ public: void print(std::ostream& os) const; ///Get hold of the container names (in derived classes too). - const ContainerNames containerNames() const { return m_containerNames; } - -private: + const ContainerNames containerNames() const {return m_containerNames;} + private: ///Store the container names ContainerNames m_containerNames; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/LJetsAnalysis.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/LJetsAnalysis.h index b03b50b7119c..b569b6ba73d0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/LJetsAnalysis.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/LJetsAnalysis.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef LJETSANALYSIS_H_ #define LJETSANALYSIS_H_ @@ -18,18 +18,17 @@ namespace EL { } namespace top { - -class LJetsAnalysis : public AnalysisBase { -public: - LJetsAnalysis(TFile* outputFile, EL::Worker* wk=nullptr); + class LJetsAnalysis: public AnalysisBase { + public: + LJetsAnalysis(TFile* outputFile, EL::Worker* wk = nullptr); ~LJetsAnalysis(); void newFile(TFile* inputFile) override; void event(const top::Event& topEvent) override; void finalise(TFile* outputFile) override; - -private: - void printCutflow(std::ostream& out, const TH1D* const eventHist, const TH1D* const mcWeightHist, const std::string& name, const unsigned int localYield); + private: + void printCutflow(std::ostream& out, const TH1D* const eventHist, const TH1D* const mcWeightHist, + const std::string& name, const unsigned int localYield); ///used for output filename (for MC) unsigned int m_mcChannelNumber; @@ -47,8 +46,7 @@ private: unsigned int m_counterEl; unsigned int m_counterMu; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/LJetsTtresAnalysis.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/LJetsTtresAnalysis.h index f7101f61b7db..6ab4306a8af7 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/LJetsTtresAnalysis.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/LJetsTtresAnalysis.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef LJETSTTRESANALYSIS_H_ #define LJETSTTRESANALYSIS_H_ @@ -17,20 +17,18 @@ class TH1D; class TFile; namespace top { - -class LJetsTtresAnalysis : public AnalysisBase { -public: + class LJetsTtresAnalysis: public AnalysisBase { + public: LJetsTtresAnalysis(TFile* outputFile); ~LJetsTtresAnalysis(); void newFile(TFile* inputFile) override; void event(const top::Event& topEvent) override; void finalise(TFile* outputFile) override; - -private: + private: void printCutflow(TH1D* eventHist, TH1D* mcWeightHist, const std::string& name, unsigned int localYield); - void fillIt(top::PlotManager &hist, const top::Event& topEvent, bool isBoosted); + void fillIt(top::PlotManager& hist, const top::Event& topEvent, bool isBoosted); unsigned int m_mcChannelNumber; @@ -57,8 +55,7 @@ private: TtresNeutrinoBuilder m_neutrinoBuilder; TtresChi2 m_chi2; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MakeTopConfig.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MakeTopConfig.h index ccd2505a1f34..b78dbc121e8a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MakeTopConfig.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MakeTopConfig.h @@ -1,19 +1,15 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ -// $Id: MakeTopConfig.h 681944 2015-07-09 21:59:27Z morrisj $ #ifndef ANALYSISTOP_NEXTGEN_MAKETOPCONFIG_H -#define ANALYSISTOP_NEXTGEN_MAKTOPCONFIG_H +#define ANALYSISTOP_NEXTGEN_MAKETOPCONFIG_H /** * @author John Morris <john.morris@cern.ch> * * @brief MakeTopConfig - it makes a top::TopConfig from the metadata * - * $Revision: 681944 $ - * $Date: 2015-07-09 23:59:27 +0200 (Thu, 09 Jul 2015) $ - * * **/ @@ -22,14 +18,13 @@ // Framework include(s): #include "AsgTools/AsgMetadataTool.h" -namespace top{ +namespace top { class TopConfig; - class MakeTopConfig : public asg::AsgMetadataTool { - public: - explicit MakeTopConfig( const std::string& name ); - - std::shared_ptr<top::TopConfig> makeTopConfig(); - + class MakeTopConfig: public asg::AsgMetadataTool { + public: + explicit MakeTopConfig(const std::string& name); + + std::shared_ptr<top::TopConfig> makeTopConfig(); }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MiniToFlatAnalysis.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MiniToFlatAnalysis.h index 92c2f8888ce8..1adde5c9abae 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MiniToFlatAnalysis.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MiniToFlatAnalysis.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: MiniToFlatAnalysis.h 733950 2016-04-05 11:21:48Z tneep $ #ifndef TOPEXAMPLES_MINITOFLATANALYSIS_H_ @@ -26,8 +26,8 @@ // Forward declaration(s): namespace top { -class TopConfig; -class PlotManager; + class TopConfig; + class PlotManager; } class TFile; @@ -38,30 +38,29 @@ class TFile; #include "TopAnalysis/EventSaverFlatNtuple.h" namespace top { -class MiniToFlatAnalysis : public asg::AsgTool { - public: - explicit MiniToFlatAnalysis(const std::string& name); - virtual ~MiniToFlatAnalysis() {} + class MiniToFlatAnalysis: public asg::AsgTool { + public: + explicit MiniToFlatAnalysis(const std::string& name); + virtual ~MiniToFlatAnalysis() {} - // Delete Standard constructors - MiniToFlatAnalysis(const MiniToFlatAnalysis& rhs) = delete; - MiniToFlatAnalysis(MiniToFlatAnalysis&& rhs) = delete; - MiniToFlatAnalysis& operator=(const MiniToFlatAnalysis& rhs) = delete; + // Delete Standard constructors + MiniToFlatAnalysis(const MiniToFlatAnalysis& rhs) = delete; + MiniToFlatAnalysis(MiniToFlatAnalysis&& rhs) = delete; + MiniToFlatAnalysis& operator = (const MiniToFlatAnalysis& rhs) = delete; - virtual StatusCode initialize(); - virtual StatusCode execute(); - virtual StatusCode finalize(); + virtual StatusCode initialize(); + virtual StatusCode execute(); + virtual StatusCode finalize(); + private: + std::shared_ptr<top::TopConfig> m_config; - private: - std::shared_ptr<top::TopConfig> m_config; + std::unique_ptr<top::TopToolStore> m_topTools; + std::unique_ptr<top::ScaleFactorCalculator> m_sfCalc; + std::unique_ptr<top::TopEventMaker> m_evtMaker; + std::unique_ptr<top::EventSaverFlatNtuple> m_event_saver; - std::unique_ptr<top::TopToolStore> m_topTools; - std::unique_ptr<top::ScaleFactorCalculator> m_sfCalc; - std::unique_ptr<top::TopEventMaker> m_evtMaker; - std::unique_ptr<top::EventSaverFlatNtuple> m_event_saver; - - std::string m_outputFileName; - ::TFile* m_outputFile; -}; + std::string m_outputFileName; + ::TFile* m_outputFile; + }; } // namespace top #endif // TOPEXAMPLES_MINITOFLATANALYSIS_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MinixAODAnalysis.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MinixAODAnalysis.h index 26f2398ca648..2a6ad4a4c263 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MinixAODAnalysis.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/MinixAODAnalysis.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: MinixAODAnalysis.h 683667 2015-07-17 02:24:59Z morrisj $ #ifndef ANALYSISTOP_TOPEXAMPLES_MINIXAODANALYSIS_H @@ -12,7 +12,7 @@ * @brief MinixAODAnalysis * * $Revision: 683667 $ - * $Date: 2015-07-17 04:24:59 +0200 (Fri, 17 Jul 2015) $ + * $Date: 2015-07-17 03:24:59 +0100 (Fri, 17 Jul 2015) $ * * **/ @@ -24,7 +24,7 @@ #include "AsgTools/AsgTool.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; class PlotManager; } @@ -34,38 +34,36 @@ class TFile; #include "TopCorrections/ScaleFactorCalculator.h" #include "TopEvent/TopEventMaker.h" -namespace top{ - class MinixAODAnalysis : public asg::AsgTool { - public: - explicit MinixAODAnalysis( const std::string& name ); - virtual ~MinixAODAnalysis(){} - - // Delete Standard constructors - MinixAODAnalysis(const MinixAODAnalysis& rhs) = delete; - MinixAODAnalysis(MinixAODAnalysis&& rhs) = delete; - MinixAODAnalysis& operator=(const MinixAODAnalysis& rhs) = delete; - - virtual StatusCode initialize(); - virtual StatusCode execute(); - virtual StatusCode finalize(); - - private: - std::shared_ptr<top::TopConfig> m_config; - - std::unique_ptr<top::TopToolStore> m_topTools; - std::unique_ptr<top::ScaleFactorCalculator> m_sfCalc; - std::unique_ptr<top::TopEventMaker> m_evtMaker; - - std::string m_outputFileName; - ::TFile* m_outputFile; - - // Analysis - bool m_firstEvent; - std::string m_sampleName; - std::unordered_map<std::string,std::unordered_map<std::string,top::PlotManager*>> m_plots; - typedef std::unordered_map<std::string,std::unordered_map<std::string,top::PlotManager*>>::const_iterator Itr; - typedef std::unordered_map<std::string,top::PlotManager*>::const_iterator Itr2; +namespace top { + class MinixAODAnalysis: public asg::AsgTool { + public: + explicit MinixAODAnalysis(const std::string& name); + virtual ~MinixAODAnalysis() {} + // Delete Standard constructors + MinixAODAnalysis(const MinixAODAnalysis& rhs) = delete; + MinixAODAnalysis(MinixAODAnalysis&& rhs) = delete; + MinixAODAnalysis& operator = (const MinixAODAnalysis& rhs) = delete; + + virtual StatusCode initialize(); + virtual StatusCode execute(); + virtual StatusCode finalize(); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::unique_ptr<top::TopToolStore> m_topTools; + std::unique_ptr<top::ScaleFactorCalculator> m_sfCalc; + std::unique_ptr<top::TopEventMaker> m_evtMaker; + + std::string m_outputFileName; + ::TFile* m_outputFile; + + // Analysis + bool m_firstEvent; + std::string m_sampleName; + std::unordered_map<std::string, std::unordered_map<std::string, top::PlotManager*> > m_plots; + typedef std::unordered_map<std::string, std::unordered_map<std::string, top::PlotManager*> >::const_iterator Itr; + typedef std::unordered_map<std::string, top::PlotManager*>::const_iterator Itr2; }; } #endif \ No newline at end of file diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/NoSelectionAnalysis.h b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/NoSelectionAnalysis.h index 0f6ca4c7490d..ec3a05c61f41 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/NoSelectionAnalysis.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/TopExamples/NoSelectionAnalysis.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef NOSELECTIONANALYSIS_H_ #define NOSELECTIONANALYSIS_H_ @@ -18,17 +18,15 @@ namespace EL { } namespace top { - -class NoSelectionAnalysis : public AnalysisBase { -public: - NoSelectionAnalysis(TFile* outputFile, EL::Worker* wk=nullptr); + class NoSelectionAnalysis: public AnalysisBase { + public: + NoSelectionAnalysis(TFile* outputFile, EL::Worker* wk = nullptr); ~NoSelectionAnalysis(); void newFile(TFile* inputFile) override; void event(const top::Event& topEvent) override; void finalise(TFile* outputFile) override; - -private: + private: void printCutflow(TH1D* eventHist, TH1D* mcWeightHist, const std::string& name, unsigned int localYield); top::PlotManager m_hists; @@ -37,8 +35,7 @@ private: TH1D* m_cutflowMCWeights; unsigned int m_counter; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/AtlasStyle.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/AtlasStyle.py index 987ae94ffcb0..a4f55fc299b4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/AtlasStyle.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/AtlasStyle.py @@ -3,7 +3,7 @@ import ROOT def SetAtlasStyle(): - print 'Applying ATLAS style settings...' + print('Applying ATLAS style settings...') atlasStyle = AtlasStyle() ROOT.gROOT.SetStyle("ATLAS") ROOT.gROOT.ForceStyle() @@ -77,4 +77,4 @@ def AtlasStyle(): atlasStyle.SetPadTickX(1) atlasStyle.SetPadTickY(1) -SetAtlasStyle() \ No newline at end of file +SetAtlasStyle() diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/__init__.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/__init__.py index 324aa2caa108..74583d364ec2 100755 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/__init__.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/__init__.py @@ -1,3 +1,2 @@ # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -# PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/__init__.py diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/ami.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/ami.py index 0277362e58df..11f85a41b73c 100755 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/ami.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/ami.py @@ -1,20 +1,48 @@ #!/usr/bin/env python -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +import re import os import sys from xml.dom.minidom import parse, parseString import logger + try: import pyAMI.client import pyAMI.atlas.api #import pyAMI except: - print "Maybe you didn't do localSetupPyAMI?" + print("Maybe you didn't do localSetupPyAMI?") sys.exit() + +# Call this function when the AMI client throws any exceptions. +# Quite likely, this is due to a missing VOMS proxy, so point +# that out to the user and exit with error code. +def exit_with_pyami_exception(): + print('') + print(logger.FAIL + 'is your voms proxy okay?' + logger.ENDC) + print('Try voms-proxy-init -voms atlas') + sys.exit(1) + + +# Exception to be thrown when information cannot be extracted +# from an LDN, e.g. the p-tag cannot be identified. +class ldn_decypher_error(Exception): + """Raised when information cannot be extracted from an LDN""" + pass + + +# Exception to be thrown when the wrong LDN type is fed into a +# function (e.g. data-type LDN into an MC-only function). This +# assumes there are only data and MC as types. +class ldn_wrong_type(Exception): + """Raised when an LDN of a wrong type is used""" + pass + + def getContainerContents(containerName): amiclient = pyAMI.client.Client('atlas') @@ -22,11 +50,9 @@ def getContainerContents(containerName): data = "'%"+query+"%'" argument = 'SearchQuery -glite="select dataset.logicalDatasetName, dataset.identifier where dataset.logicalDatasetName like %s" -processingStep=real_data -project=dataSuper_001' % data - #print 'argument', argument maxTries = 3 - #print argument failures = 0 for i in range(maxTries): try: @@ -34,58 +60,35 @@ def getContainerContents(containerName): except: failures += 1 - if failures == maxTries: - print '' - print logger.FAIL + 'is your voms proxy okay?' + logger.ENDC - print 'Try voms-proxy-init -voms atlas' - sys.exit(1) - - #print 'made it' + if failures == maxTries: exit_with_pyami_exception() - #txt = results.output('xml') - #print txt dom = parseString(results) rows = dom.getElementsByTagName('row') - #final = {} datasets = [] - #print 'found', len(rows) for row in rows: - #print 'here', row fields = row.getElementsByTagName('field') for field in fields: - #print field.attributes['name'].value if field.attributes['name'].value == 'logicalDatasetName': retName=field.firstChild.nodeValue - #print retName -# if field.attributes['name'].value == 'identifier': identifier = field.firstChild.nodeValue - #print identifier #Now search for all datasets that match that - #print 'PART 2' - #argument.append("entity=contained_dataset") argument = 'SearchQuery -glite="SELECT contained_dataset.contained_datasetName WHERE dataset.identifier=%s" -processingStep=real_data -project=dataSuper_001' % identifier results = amiclient.execute(argument, format='xml') - #print results - #txt = results.output('xml') - #print txt dom = parseString(results) container = dom.getElementsByTagName('row') - #print len(container) for dataset in container: fields = dataset.getElementsByTagName('field') for field in fields: if field.attributes['name'].value == 'contained_datasetName': - #print 'hello' - #print field.firstChild.nodeValue datasets.append(field.firstChild.nodeValue.encode('ascii','ignore') + '/') - return sorted(datasets) + def askAmi(query, property = 'totalEvents'): amiclient = pyAMI.client.Client('atlas') @@ -93,9 +96,7 @@ def askAmi(query, property = 'totalEvents'): query = query.replace('*', '%%') data = "'"+query+"'" - #argument.append("entity=dataset") argument = 'SearchQuery -glite="SELECT dataset.logicalDatasetName, dataset.%s WHERE dataset.logicalDatasetName LIKE %s"' % (property, data) - #print argument if data.find('data') > -1: argument += ' -processingStep=real_data' @@ -123,11 +124,11 @@ def askAmi(query, property = 'totalEvents'): argument += ' -project=mc14_001' elif data.find('mc15') > -1: argument += ' -project=mc15_001' + elif data.find('mc16') > -1: + argument += ' -project=mc16_001' maxTries = 3 - #print argument - failures = 0 for i in range(maxTries): final = {} @@ -138,29 +139,20 @@ def askAmi(query, property = 'totalEvents'): except: failures += 1 - if failures == maxTries: - print '' - print logger.FAIL + 'is your voms proxy okay?' + logger.ENDC - print 'Try voms-proxy-init -voms atlas' - sys.exit(1) + if failures == maxTries: exit_with_pyami_exception() - #print results.getElementsByTagName('error') - #txt = results.output('xml') - #print txt dom = parseString(results) #they changed it so that a voms-proxy-init error now returns a search #result with error in it. That's annoying. mayBeAnError = dom.getElementsByTagName('error') for row in mayBeAnError: - print row.firstChild.nodeValue + print(row.firstChild.nodeValue) sys.exit(1) rows = dom.getElementsByTagName('row') for row in rows: - #print 'here', row.toprettyxml() - fields = row.getElementsByTagName('field') retName = '' retNev = 0 @@ -169,50 +161,206 @@ def askAmi(query, property = 'totalEvents'): if field.attributes['name'].value == 'logicalDatasetName': retName = field.firstChild.nodeValue - if field.attributes['name'].value == property: - if field.firstChild != None: - retNev = field.firstChild.nodeValue - - #print retName, retNev + if field.attributes['name'].value == property: + if field.firstChild != None: + retNev = field.firstChild.nodeValue final[retName] = retNev else: try: - results = pyAMI.atlas.api.list_datasets(amiclient, query, fields="ldn,events,modified") + results = pyAMI.atlas.api.list_datasets(amiclient, query, fields="ldn,events,modified") except: failures += 1 - if failures == maxTries: - print '' - print logger.FAIL + 'is your voms proxy okay?' + logger.ENDC - print 'Try voms-proxy-init -voms atlas' - sys.exit(1) - - for row in results: + if failures == maxTries: exit_with_pyami_exception() + + for row in results: retName = row["ldn"] retNev = row["events"] - - #print retName, retNev + final[retName] = retNev - - #unicode -> normalcode results = {} for k in final.keys(): results[str(k)] = int(final[k]) - - return results + +# Take a single LDN, extract its dataset number and return it. +def get_dataset_number(ldn): + if is_data(ldn): raise ldn_wrong_type + regex = re.compile("\.[0-9]{6}\.") + match = regex.search(ldn) + if not match: raise ldn_decypher_error + else: return match.group(0)[1:-1] + + +# Take a single LDN, extract its p-tag and return it. +def get_ptag(ldn): + regex = re.compile("_p[0-9]+") + match = regex.search(ldn) + if not match: raise ldn_decypher_error + else: return match.group(0)[1:] + + +# Return the type of LDN we're looking at (e.g. simul.HITS, +# recon.AOD, DAOD_TOPQ1 or other derivation). +def get_type(ldn): + match = re.search("\.recon\.AOD\.", ldn) + if match: return match.group(0)[1:-1] + match = re.search("\.simul.HITS\.", ldn) + if match: return match.group(0)[1:-1] + match = re.search("\.DAOD_[A-Z]+[0-9]+\.", ldn) + if match: return match.group(0)[1:-1] + # If none of the above, raise exception. + raise ldn_decypher_error + + +# Get the data scope of a data-type LDN (e.g. +# data15_13TeV.periodA or data16_13TeV.AllYear) and return it. +# This function should only be called on data LDNs. +def get_data_scope(ldn): + if not is_data(ldn): raise ldn_wrong_type + regex = re.compile("data[0-9]+.*?\..*?\.") + match = regex.search(ldn) + if not match: raise ldn_decypher_error + else: return match.group(0)[:-1] + + +# Get a list of all derivations registered on AMI for a list of +# LDNs. This removes the p-tags from the LDNs and replaces them +# with wildcards to search on AMI. The function returns a +# dictionary with dataset numbers as keys, and a list of LDNs as +# values. The LDNs are assumed to be TOPQ derivations. +def get_derivations(ldns): + amiclient = pyAMI.client.Client('atlas') + regex = re.compile("_p[0-9]+") + wildcards = [regex.sub('_p%', d) for d in ldns] + try: results = pyAMI.atlas.api.list_datasets(amiclient, patterns = wildcards) + except pyAMI.exception.Error: exit_with_pyami_exception() + + dictionary = dict() + + # Make sure the dictionary has empty lists prepared for all + # LDNs that were searched for. If MC, use the dataset number + # as dictionary key, if data, use the data scope. + for ldn in ldns: + try: dictionary[get_dataset_number(ldn)] = [] + except ldn_wrong_type: dictionary[get_data_scope(ldn)] = [] + + # Go through the results and add them to appropriate + # dictionary entries (appending to lists). + for d in results: + try: dictionary[get_dataset_number(d['ldn'])].append(d['ldn']) + except ldn_wrong_type: dictionary[get_data_scope(d['ldn'])].append(d['ldn']) + return dictionary + + +# Check whether an LDN is actually available and valid on AMI. +def is_available(ldn): + amiclient = pyAMI.client.Client('atlas') + try: results = pyAMI.atlas.api.list_datasets(amiclient, patterns = [ldn], fields = ['ldn']) + except pyAMI.exception.Error: exit_with_pyami_exception() + for d in results: + if d['ldn'] == ldn: return True + return False + + +# Check whether an LDN refers to data (and not MC). +def is_data(ldn): + if (ldn[0:4] == "data"): return True + return False + + +# From a given list of LDNs, pick the latest one (i.e. extract +# the p-tag and pick the LDN with the highest one). If the p-tag +# cannot be identified, just return None. +def pick_newest_derivation(ldn_list): + if len(ldn_list) == 0: return "" + try: + get_ptag_as_int = lambda a: int(get_ptag(a)[1:]) + return sorted(ldn_list, key = get_ptag_as_int)[-1] + except ldn_decypher_error: + return None + + +# Print the status of a list of samples on AMI. This takes a list +# of objects of type TopExamples.grid.Sample, wich then contain +# lists of datasets. Set the second argument to "True" will make +# the function stop on any errors. +def check_sample_status(samples, stop_on_error = False): + for s in samples: + print('\n' + logger.WARNING + s.name + logger.ENDC + " (%s %s)" % (len(s.datasets), "dataset" if len(s.datasets) == 1 else "datasets")) + derivations = get_derivations(s.datasets) + status_ok = True + + for ldn in s.datasets: + # First try to understand what type of LDN we're looking + # at (e.g. recon.AOD or DAOD_xx derivations). If this + # fails, exit here. + try: + dataset_type = get_type(ldn) + except: + print("Could not identify dataset type (e.g. recon.AOD or DAOD_TOPQ1) of LDN: %s" % ldn) + sys.exit(1) + + # Try to guess the name of the dictionary key. If the + # LDN is of type MC, then the dataset number should be + # the key, for data it's the data scope. + try: dict_key = get_dataset_number(ldn) + except ldn_wrong_type: dict_key = get_data_scope(ldn) + latest_ldn = pick_newest_derivation(derivations[dict_key]) + + status_msg = "" + + # First output whether the requested LDN exists and + # has a valid entry in the AMI database. + if is_available(ldn): + status_msg = logger.OKGREEN + "found" + logger.ENDC + else: + status_msg = logger.FAIL + "not found" + logger.ENDC + status_ok = False + + # If the dataset is _not_ a derivation, output its type + # and mark it in red. + if dataset_type[0:5] != "DAOD_": + status_msg += ", " + logger.WARNING + "Type: " + dataset_type + logger.ENDC + status_ok = False + + # Then output the derivation status: (1) no derivation + # available at all, (2) derivations available, but the + # requested p-tag is not the latest, (3) requested p-tag + # is the latest. + if not latest_ldn: + status_ok = False + elif not ldn == latest_ldn: + try: + status_msg += ", " + logger.WARNING + "latest p-tag: " + get_ptag(latest_ldn) + logger.ENDC + status_ok = False + except ldn_decypher_error: + print("Could not identify p-tag of LDN: %s" % latest_ldn) + sys.exit(1) + else: + status_msg += ", " + logger.OKGREEN + "latest" + logger.ENDC + + print(" - %s (%s)" % (ldn, status_msg)) + + # Make the function stop if requested and any of the + # datasets of the previous sample list had problems. + if (stop_on_error and not status_ok): + print("\nRequested to stop on error. Please check the above samples ... ") + sys.exit(1) + + if __name__ == '__main__': #data - print 'Testing data15' + print('Testing data15') results = askAmi('data15_comm.%.physics_Main.%.DAOD_TOPQ1.%p2356') for ds in sorted(results): - print ds + print(ds) #MC simulation - print 'Testing MC15' + print('Testing MC15') results = askAmi('mc15_13TeV.%.DAOD_TOPQ1.%p2352') for ds in sorted(results): - print ds + print(ds) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/analysis.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/analysis.py index 704290bf991a..1cc750b9331d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/analysis.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/analysis.py @@ -85,18 +85,18 @@ class TopDataPreparation: def queryAmi(amiSamples, tag): sys.stdout.write('-> %s: ' % tag) sys.stdout.flush() - print tag + print(tag) ds = ami.askAmi(tag) - print len(ds), 'datasets' + print(len(ds), 'datasets') amiSamples.update(ds) def cacheAmi(ptaglist): try: amiSamples = pickle.load(open("amiyields.pickle", "rb" )) - print logger.OKBLUE + 'Using cached yields - to force me to query AMI delete amiyields.pickle' + logger.ENDC - except IOError, ioex: + print(logger.OKBLUE + 'Using cached yields - to force me to query AMI delete amiyields.pickle' + logger.ENDC) + except IOError as ioex: if ioex.errno == 2: - print logger.OKBLUE + 'Asking AMI' + logger.ENDC + print(logger.OKBLUE + 'Asking AMI' + logger.ENDC) amiSamples = {} @@ -109,7 +109,7 @@ def cacheAmi(ptaglist): queryAmi(amiSamples, 'mc15_13TeV.%.DAOD_TOPQ%.%' + ptag) if len(amiSamples) == 0: - print logger.FAIL + 'Something went wrong when trying to get the data from ami' + logger.ENDC + print(logger.FAIL + 'Something went wrong when trying to get the data from ami' + logger.ENDC) sys.exit(1) else: pickle.dump(amiSamples, open("amiyields.pickle", "wb")) @@ -134,7 +134,7 @@ def getDatasetYield(directoryName): f = ROOT.TFile.Open(fileName) if not f: - print logger.FAIL + 'ERROR: Failed to open %s' % fileName + logger.ENDC + print(logger.FAIL + 'ERROR: Failed to open %s' % fileName + logger.ENDC) continue #Look for TDirectory file (not TTree) and read the cutflow from @@ -154,7 +154,7 @@ def getDatasetYield(directoryName): def makeDirectory(outputDirectory): try: os.makedirs(outputDirectory) - print 'Made directory', outputDirectory + print('Made directory', outputDirectory) except: #directory already exists pass @@ -207,7 +207,7 @@ def check(analysis, directory, runDirectory, samples): if not IsInList: ptaglist.append(tag) - print ptaglist + print(ptaglist) amiSamples = cacheAmi(ptaglist) @@ -228,11 +228,11 @@ def check(analysis, directory, runDirectory, samples): analyses = [] bad = [] - print '%s%50s %90s %12s %12s%s' % (logger.OKBLUE, 'dsid.gridtag', 'local location', 'local yield', 'ami yield', logger.ENDC) + print('%s%50s %90s %12s %12s%s' % (logger.OKBLUE, 'dsid.gridtag', 'local location', 'local yield', 'ami yield', logger.ENDC)) for sample in samples: existingSampleFilenames = [] - print logger.OKBLUE + sample.name + logger.ENDC + print(logger.OKBLUE + sample.name + logger.ENDC) for ds in sample.datasets: splitName = ds.replace('/','').split('.') shortname = splitName[1] + '.' + splitName[-2] + '.' + splitName[-1] @@ -268,7 +268,7 @@ def check(analysis, directory, runDirectory, samples): evenshortername = makeNameFitOnTerminal(shortname, 50) eventshorterfilename = makeFileNameFitOnTerminal(directory.split('/')[-1], 60) - print '%s%50s %90s %12d %12d%s' % (colourstart, evenshortername, eventshorterfilename, directoryYield, amiYield, colourend) + print('%s%50s %90s %12d %12d%s' % (colourstart, evenshortername, eventshorterfilename, directoryYield, amiYield, colourend)) if amiYield > 0 and directoryYield != amiYield: bad.append(ds) @@ -294,31 +294,31 @@ def check(analysis, directory, runDirectory, samples): analyses.append('cd %s;hadd -f %s.root %s' % (runDirectory, sample.name, mergelist)) if '--debug' in sys.argv: - print '' - print '' - print 'These commands are going to be run:' + print('') + print('') + print('These commands are going to be run:') for l in analyses: - print l + print(l) if '--bad' in sys.argv: - print '' - print '' - print 'These are datasets where the ami yield does not match' - print 'TopExamples.grid.Add("Resubmit").datasets = [' + print('') + print('') + print('These are datasets where the ami yield does not match') + print('TopExamples.grid.Add("Resubmit").datasets = [') for l in bad: - print '"%s",' % l + print('"%s",' % l) - print ']' - print "resubmit = TopExamples.grid.Samples(['Resubmit'])" - print 'TopExamples.grid.submit(config, resubmit)' + print(']') + print("resubmit = TopExamples.grid.Samples(['Resubmit'])") + print('TopExamples.grid.submit(config, resubmit)') if '--run' in sys.argv: makeDirectory(runDirectory) - print '' - print '' - print analyses + print('') + print('') + print(analyses) for i, l in enumerate(analyses): - print logger.OKBLUE + l + logger.ENDC - os.system(l) + print(logger.OKBLUE + l + logger.ENDC) + o.ssysteml() diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/grid.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/grid.py index 2930dd177421..4ee66715d8c6 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/grid.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/grid.py @@ -6,22 +6,8 @@ import sys import distutils.spawn import logger import analysis - -try: - import rucio.client -except: - print logger.FAIL + 'DANGER DANGER DANGER' + logger.ENDC - print 'Could not find rucio.client.Client. If you use setupATLAS (you should) then' - print '"localSetupRucioClients" and run this again' - sys.exit(1) - -try: - rucio = rucio.client.Client() -except: - print logger.FAIL + 'DANGER DANGER DANGER' + logger.ENDC - print 'Could not setup rucio.client.Client.' - print 'Did you do voms-proxy-init -voms atlas ?' - sys.exit(1) +import ROOT +from PathResolver import PathResolver availableDatasets = {} @@ -44,13 +30,13 @@ class Sample: if n != 1: suffix = 's' - print logger.OKGREEN + ' %s ' % self.name + logger.ENDC + '(%d dataset%s)' % (n, suffix) + print(logger.OKGREEN + ' %s ' % self.name + logger.ENDC + '(%d dataset%s)' % (n, suffix)) for i, l in enumerate(self.datasets): note = 'Not found' if l in actuallyExists: note = 'Found' - print ' -%2d %s %s' % (i, l, note) + print(' -%2d %s %s' % (i, l, note)) def Add(name): availableDatasets[name] = Sample(name) @@ -62,58 +48,113 @@ def AvailableDatasets(): def Samples(names): samples = [] for n in names: + #removing whitespaces from concatenated lines - ANALYSISTO-553 + for ds in range(0,len(availableDatasets[n].datasets)): + availableDatasets[n].datasets[ds]=availableDatasets[n].datasets[ds].replace(' ','') samples.append(availableDatasets[n]) return samples +def basicInDSNameShortener(*args): + # don't ask what args[0] is; just use args[1] (sorry for my lack of understanding of python) + # if you want to use a different function defined outside this module, you don't need to bother + inDSName = args[1] + splitted = inDSName.split('.') + + runNumber = splitted[1] + physicsName = splitted[2] + if splitted[0] == "user" or splitted[0] == "group": #this is in case we run on private derivations, either produced with user or group role + runNumber = splitted[2] + physicsName = splitted[3] + derivation = splitted[-2] + tags = splitted[-1].replace('/','') + + #grid complains dataset names are too long + #stupid grid + if len(physicsName) > 20: + physicsName = physicsName.split('_')[0] + + outDSName = runNumber + '.' + physicsName + '.' + derivation + '.' + tags + return outDSName + class Config: code = 'top-xaod' - cutsFile = 'nocuts.txt' - - gridUsername = '' - suffix = '' - excludedSites = '' - forceSite = '' - noSubmit = False - CMake = False # False by default - need to set to True for CMake-based releases (release 21) - mergeType = 'Default' #None, Default, xAOD - destSE = '' - memory = '2000' #in MB + settingsFile = 'nocuts.txt' + combine_outputFile = None + combine_prefixes = None + + gridUsername = '' + groupProduction = None + suffix = '' + excludedSites = '' + forceSite = '' + noSubmit = False + CMake = (os.getenv('ROOTCORE_RELEASE_SERIES')=='25') # ROOTCORE_RELEASE_SERIES variable used to identify release (CMake required for R21) + mergeType = 'Default' #None, Default, xAOD + destSE = '' + memory = '2000' #in MB maxNFilesPerJob = '' - otherOptions = '' + otherOptions = '' + skipShowerCheck = False + nameShortener = basicInDSNameShortener # default shortener function + customTDPFile = None + reuseTarBall = False + checkPRW = False def details(self): - cutsFileIsARealFile = checkForFile(self.settingsFile) - txt = '(' + logger.FAIL + 'not found' + logger.ENDC + ')' - if cutsFileIsARealFile: - txt = '(exists)' - - print logger.OKBLUE + 'Analysis Settings:' + logger.ENDC - print ' -Code: ', self.code - print ' -CutsFile: ', self.settingsFile, txt - - print logger.OKBLUE + 'Grid Settings:' + logger.ENDC - print ' -GridUsername: ', self.gridUsername - print ' -Suffix: ', self.suffix - print ' -ExcludedSites: ', self.excludedSites - print ' -ForceSite: ', self.forceSite - print ' -NoSubmit: ', self.noSubmit - print ' -MergeType: ', self.mergeType, 'out of (None, Default, xAOD)' - print ' -memory: ', self.memory, 'in MB' - print ' -maxNFilesPerJob', self.maxNFilesPerJob - print ' -OtherOptions: ', self.otherOptions + txt = '(' + iconfigFile=0 + for configFile in self.settingsFile.split(','): + cutsFileIsARealFile = checkForFile(ROOT.PathResolver.find_file(configFile, "DATAPATH", ROOT.PathResolver.LocalSearch)) + if cutsFileIsARealFile: + txt += 'exists' + else: + txt += logger.FAIL + 'not found' + logger.ENDC + ')' + if iconfigFile!=len(self.settingsFile.split(','))-1: + txt += ',' + iconfigFile += 1 + txt += ')' + + print(logger.OKBLUE + 'Analysis Settings:' + logger.ENDC) + print(' -Code: ', self.code) + print(' -CutsFile: ', self.settingsFile, txt) + print(' -Combine_outputFile: ', self.combine_outputFile) + print(' -Combine_prefixes: ', self.combine_prefixes) + + if (self.groupProduction != None): + logger.WARNING + "Option groupProduction is obsolete. Production mode is deduced from gridUsername (e.g. if it's 'phys-top')." + logger.ENDC + if self.gridUsername.find('phys-') == 0: + self.groupProduction = True + txt = ' (group production)' + else: + self.groupProduction = False + txt = '' + print(logger.OKBLUE + 'Grid Settings:' + logger.ENDC) + print(' -GridUsername: ', self.gridUsername, txt) + print(' -Suffix: ', self.suffix) + print(' -ExcludedSites: ', self.excludedSites) + print(' -ForceSite: ', self.forceSite) + print(' -NoSubmit: ', self.noSubmit) + print(' -MergeType: ', self.mergeType, 'out of (None, Default, xAOD)') + print(' -memory: ', self.memory, 'in MB') + print(' -maxNFilesPerJob', self.maxNFilesPerJob) + print(' -skipShowerCheck', self.skipShowerCheck) + print(' -OtherOptions: ', self.otherOptions) + print(' -nameShortener: ', self.nameShortener) + print(' -reuseTarBall: ', self.reuseTarBall) + print(' -checkPRW: ', self.checkPRW) txt = self.destSE if len(txt) == 0: txt = '<not set>' - print ' -DestSE ', txt + print(' -DestSE ', txt) - print '' + print('') def checkMergeType(configuration): type = configuration.mergeType if type != "None" and type != "Default" and type != "xAOD": - print "MergeType must be set to either None, Default or xAOD" - print 'Not', type, "Since that doesn't make sense" + print("MergeType must be set to either None, Default or xAOD") + print('Not', type, "Since that doesn't make sense") sys.exit() #If settings.txt doesn't exist your grid job will fail @@ -122,9 +163,9 @@ def checkForFile(filename): def checkForPrun(): if distutils.spawn.find_executable('prun') == None: - print logger.FAIL + 'DANGER DANGER DANGER' + logger.ENDC - print 'Could not find prun. If you use setupATLAS (you should) then' - print '"localSetupPandaClient --noAthenaCheck" and run this again' + print(logger.FAIL + 'DANGER DANGER DANGER' + logger.ENDC) + print('Could not find prun. If you use setupATLAS (you should) then') + print('"localSetupPandaClient --noAthenaCheck" and run this again') sys.exit() #I see a crash if I setup with rcSetup Top,1.4.0 @@ -136,15 +177,15 @@ def findPackages(): debug = False if debug: - print 'finding packages' - print cmd + print('finding packages') + print(cmd) for l in os.popen(cmd).readlines(): if debug: - print l.strip() + print(l.strip()) if debug: - print 'done' + print('done') #Given a list of datasets, the command to run and a mode (egamma, muons) this #submits one prun job per run @@ -153,63 +194,113 @@ def submit(config, allSamples): checkForPrun() checkMergeType(config) config.details() - checkForShowerAlgorithm(allSamples) + if not config.skipShowerCheck: + for configFile in config.settingsFile.split(','): + checkForShowerAlgorithm(allSamples, configFile) + if config.checkPRW: + for configFile in config.settingsFile.split(','): + checkPRWFile(allSamples, configFile) tarfile = 'top-xaod.tar.gz' - #We don't want to use an old, out-of-date file - #Delete the file if it exists - try: - os.remove(tarfile) - except OSError, e: - #Number 2 is 'file doesn't exist' which is okay for us - if e.errno == 2: - pass - else: - raise + # Delete the old tarball if requested + if not config.reuseTarBall: + try: + os.remove(tarfile) + except OSError as e: + #Number 2 is 'file doesn't exist' which is okay for us + if e.errno == 2: + pass + else: + raise #Check for cuts file - if not checkForFile(config.settingsFile): - print logger.FAIL + "DANGER DANGER. HIGH VOLTAGE" + logger.ENDC - print '%s does not exist in this directory' % config.settingsFile - print 'please make it before submitting' - - if config.settingsFile == 'dil-cuts.txt' or config.settingsFile == 'ljets-cuts.txt': - print 'or... copy it with' - print 'cp $ROOTCOREBIN/data/TopAnalysis/%s .' % config.settingsFile - - sys.exit(1) - - #Look in the cuts file for the output filename - outputFilename = 'EMPTY' - for l in open(config.settingsFile): - #ignore text after comments - if l.find('#') > -1: - l = l.split('#')[0] - - if l.find('OutputFilename') > -1: - outputFilename = l.replace('OutputFilename', '').strip() - - if outputFilename == 'EMPTY': - print 'OutputFilename not found in %s' % config.settingsFile - sys.exit(1) + for configFile in config.settingsFile.split(','): + if not checkForFile(configFile): + print(logger.WARNING + " WARNING - Did not find config file %s in this dir "%(configFile) + logger.ENDC) + print(logger.WARNING + " - Attempt to find this file in a sensible location using PathResolver... " + logger.ENDC) + settingsFilePath = ROOT.PathResolver.find_file(configFile, "DATAPATH", ROOT.PathResolver.LocalSearch) + if settingsFilePath == "": + print(logger.FAIL + "DANGER DANGER. HIGH VOLTAGE" + logger.ENDC) + print('%s does not exist in this directory and cannot be found using PathResolver, exiting!' % configFile) + sys.exit(1) + else: + print(logger.WARNING + " - Found an appropriate file %s "%(settingsFilePath) + logger.ENDC) + + outputFiles = [] + for configFile in config.settingsFile.split(','): + settingsFilePath = ROOT.PathResolver.find_file(configFile, "DATAPATH", ROOT.PathResolver.LocalSearch) + + #Look in the cuts file for the output filename + outputFilename = 'EMPTY' + for l in open(settingsFilePath, "r"): + #ignore text after comments + if l.find('#') > -1: + l = l.split('#')[0] + if l.find('OutputFilename') > -1: + outputFilename = l.replace('OutputFilename', '').strip() + if outputFilename == 'EMPTY': + print(logger.FAIL + 'OutputFilename not found in ' + settingsFilePath + logger.ENDC) + sys.exit(1) + else: + outputFiles.append(outputFilename) + + outputFilenames='' # string defining the output file(s) + combineArgument='' # argument of command for combining the multiple output files, if need be + if len(outputFiles) == 0: # at this stage this shouldn't happen + print(logger.FAIL + 'No OutputFileName found' + logger.ENDC) + sys.exit(1) + elif len(outputFiles) ==1: # the simplest case + outF = outputFiles[0] + outputFilenames = outF.replace(".root","_root") + ":" + outF + else: # len(outputFiles) >=2: multiple output files, or a single combined one + # check if the output files are unique + if len(outputFiles) != len(set(outputFiles)): + print(logger.FAIL + 'Two of the output file names are identical. Check the config files (separated by commas).' + logger.ENDC) + sys.exit(1) + if config.combine_outputFile == None: # no combination asked + iconfigFile = 0 + for configFile in outputFiles: + cFile = configFile.replace(".root","_root") + ":" + configFile + outputFilenames += cFile + if iconfigFile != len(outputFiles)-1: + outputFilenames += ',' + iconfigFile += 1 + else: # combination of the multiple output files + # retrieving the prefixes + prefixes = config.combine_prefixes.split(',') + # check if the prefixes are unique + if len(prefixes) != len(set(prefixes)): + print(logger.FAIL + 'Two of the prefixes (separated by commas) are identical. Check the combine_prefixes option.' + logger.ENDC) + sys.exit(1) + # check if the prefixes and the output files have same length + if len(prefixes) != len(outputFiles): + print(logger.FAIL + 'When combining the outputs, there should be as many prefixes as there are output files (separated by commas). Check the combine_prefixes and settingsFile options.' + logger.ENDC) + sys.exit(1) + # using combined file name + outputFilenames = config.combine_outputFile.replace(".root","_root") + ":" + config.combine_outputFile + # building the input file argument of the combination + iconfigFile = 0 + for outFile in outputFiles: + combineArgument += outFile + combineArgument += ":" + combineArgument += prefixes[iconfigFile] + if iconfigFile != len(outputFiles)-1: + combineArgument += ',' + iconfigFile += 1 + - #print outputFilename + #print outputFilenames these = [] - print logger.OKBLUE + 'For these samples' + logger.ENDC + print(logger.OKBLUE + 'For these samples' + logger.ENDC) - #Only submit jobs if the dataset actually exists (check with rucio) for sample in allSamples: currentDatasets = sample.datasets actuallyExists = [] for ds in currentDatasets: - if checkDatasetExists(ds): - actuallyExists.append(ds) - - sample.details(actuallyExists) - these += actuallyExists + these.append(ds) #check if it's a release - which automatically would set rootVer and cmtConfig if not config.CMake: @@ -219,44 +310,48 @@ def submit(config, allSamples): if len(these) > 1: plural = 's' - print '' - print logger.OKBLUE + 'Starting submission of %d sample%s' % (len(these), plural) + logger.ENDC - print '' + print('') + print(logger.OKBLUE + 'Starting submission of %d sample%s' % (len(these), plural) + logger.ENDC) + print('') isfirst = True - for i, d in enumerate(these): - print logger.OKBLUE + 'Submitting %d of %d' % (i+1, len(these)) + logger.ENDC - - splitted = d.split('.') - - runNumber = splitted[1] - txt = splitted[2] - if splitted[0] == "user": - runNumber = splitted[2] - txt = splitted[3] - derivation = splitted[-2] - tags = splitted[-1].replace('/','') - - #grid complains dataset names are too long - #stupid grid - if len(txt) > 20: - txt = txt.split('_')[0] - - n = runNumber + '.' + txt + '.' + derivation + '.' + tags + for i, d_concatenated in enumerate(these): + d = getShortenedConcatenatedSample(d_concatenated) # in case of coma-separated list of samples with same DSID and same first tag of each type + print(logger.OKBLUE + 'Submitting %d of %d' % (i+1, len(these)) + logger.ENDC) #Make the output dataset name - output = 'user.' + config.gridUsername + '.' + n + '.' + config.suffix + #for group production it has to start with "group." and we asume that gridUsername is the name of the group (e.g. phys-top) + if config.groupProduction: + output = 'group.' + config.gridUsername + '.' + config.nameShortener(d) + '.' + config.suffix + else: + output = 'user.' + config.gridUsername + '.' + config.nameShortener(d) + '.' + config.suffix cmd = 'prun \\\n' - cmd += '--inDS=' + d + ' \\\n' + #special care for group production - we assume that gridUsername is the name of the group (e.g. phys-top) + if config.groupProduction: + cmd += '--official --voms atlas:/atlas/' + config.gridUsername + '/Role=production \\\n' + cmd += '--inDS=' + d_concatenated + ' \\\n' # the inDS may be a comma-separated list of samples with same DSID and same first tag of each type cmd += '--outDS=' + output + ' \\\n' if config.CMake: - cmd += '--useAthenaPackages --cmtConfig=x86_64-slc6-gcc49-opt \\\n' + CMTCONFIG = os.getenv("CMTCONFIG") + cmd += '--useAthenaPackages --cmtConfig=%s \\\n'%(CMTCONFIG) else: - cmd += '--useRootCore \\\n' + cmd += '--useRootCore \\\n' cmd += '--writeInputToTxt=IN:in.txt \\\n' - cmd += '--outputs=%s \\\n' % outputFilename - cmd += '--exec="%s %s in.txt" \\\n' % (config.code, config.settingsFile) + cmd += '--outputs=%s \\\n' % outputFilenames + # write the --exec commands - will possibly AnalysisTop several times + cmd += '--exec="' + iconfigFile=0 + for configFile in config.settingsFile.split(','): + cmd += '%s %s in.txt' % (config.code, configFile) + if iconfigFile!=len(config.settingsFile.split(','))-1: + cmd += '; ' + iconfigFile += 1 + elif combineArgument != '': + cmd += '; combineATOutputs ' + config.combine_outputFile + " " + combineArgument + cmd += '" \\\n' + else: + cmd += '" \\\n' #you might really hate a certain site if len(config.excludedSites) > 0: @@ -268,11 +363,19 @@ def submit(config, allSamples): #tar-up the first time only, to save time when submitting if isfirst: - cmd += '--outTarBall=%s \\\n' % tarfile + if checkForFile(tarfile) and config.reuseTarBall:# reuse existing tarball if it already exists + print(logger.OKBLUE + 'Reusing existing tarball %s' % (tarfile) + logger.ENDC) + cmd += '--inTarBall=%s \\\n' % tarfile + elif config.reuseTarBall:# reuse existing tarball if it already exists + print(logger.WARNING + 'Tarball %s not found - will re-create it' % (tarfile) + logger.ENDC) + cmd += '--outTarBall=%s \\\n' % tarfile + else: + cmd += '--outTarBall=%s \\\n' % tarfile isfirst = False else: cmd += '--inTarBall=%s \\\n' % tarfile + #maybe you don't want to submit the job? if config.noSubmit: cmd += '--noSubmit \\\n' @@ -307,17 +410,17 @@ def submit(config, allSamples): cmd += '\n' #show people what you're about to do - print cmd + print(cmd) #then do it for l in os.popen(cmd).readlines(): - print '>> ', l.strip() + print('>> ', l.strip()) #Make a directory if it doesn't exist def makeDirectory(outputDirectory): try: os.makedirs(outputDirectory) - print 'Made directory', outputDirectory + print('Made directory', outputDirectory) except: #directory already exists pass @@ -331,73 +434,190 @@ def convertAODtoTOPQ(derivationToUse, ptag, samples): for i, ds in enumerate(sample.datasets): sample.datasets[i] = ds.replace('AOD', derivationToUse).replace('/', '') + '_' + ptag -#Get a list of dataset names matching some pattern with stars in, using dq2-ls -def listDatasets(theScope, datasetPattern): - response = rucio.list_dids(scope = theScope, filters = {'name' : datasetPattern}) - - names = [] - for l in response: - names.append(l) - - return names - -#Download all datasets that match the pattern, to the outputDirectory -def download(theScope, datasetPattern, outputDirectory): - #Make sure the directory where these need to go exists - makeDirectory(outputDirectory) - - #Get datasets matching the pattern - intdatasets = listDatasets(theScope, datasetPattern) - txt = '' - if len(intdatasets) != 1: - txt = 's' - - print 'Found %d dataset%s:' % (len(intdatasets), txt) - - for ds in intdatasets: - print ' %s' % ds - - for j, d in enumerate(intdatasets): - cmd = 'rucio download %s:%s --dir %s' % (theScope, d, outputDirectory) - print logger.OKBLUE + 'Dataset %d of %d: %s' % (j+1, len(intdatasets), cmd) + logger.ENDC - - #Run the dq2 command - os.system(cmd) - -#Prun submits to datasets that don't exist, so do a quick check first... -def checkDatasetExists(name): - theScope = name.split('.')[0] - #name = 'data15_13TeV.00266904.physics_Main.merge.DAOD_TOPQ1.f594_m1435_p2361' - if theScope == "user" or theScope == "group": - theScope = name.split('.')[0] + "." + name.split('.')[1] - reply = listDatasets(theScope, name) - #print reply - return len(reply) == 1 - if __name__ == '__main__': - print "You don't run this directly!" - print 'For an example, see 01SubmitToGrid.py' + print("You don't run this directly!") + print('For an example, see 01SubmitToGrid.py') -def checkForShowerAlgorithm(Samples): +def checkForShowerAlgorithm(Samples, cutfile): + settingsFilePath = ROOT.PathResolver.find_file(cutfile, "DATAPATH", ROOT.PathResolver.LocalSearch) noShowerDatasets = [] - tdp = analysis.TopDataPreparation(os.getenv('ROOTCOREBIN') + '/data/TopDataPreparation/XSection-MC15-13TeV.data') + customTDPFile = None + tmp = open(settingsFilePath, "r") + for line in tmp.readlines(): + if "TDPPath" not in line: + continue + else: + customTDPFile = line.strip().split("TDPPath")[1] + break + print(customTDPFile) + if customTDPFile: + tdpFile = ROOT.PathResolver.find_calib_file(customTDPFile) + else: + tdpFile = ROOT.PathResolver.find_file("dev/AnalysisTop/TopDataPreparation/XSection-MC16-13TeV.data", "CALIBPATH", ROOT.PathResolver.RecursiveSearch) + # Load the file + print(tdpFile) + tdp = analysis.TopDataPreparation(tdpFile) for TopSample in availableDatasets.values(): for List in Samples: SublistSamples = List.datasets - for sample in SublistSamples: + for sample_concatenated in SublistSamples: + sample=getShortenedConcatenatedSample(sample_concatenated) # in the case of comma-separated samples with same DSIDs and same first tags (it's the same sample) scope = sample.split('.')[0] if 'mc' not in scope: continue dsid = sample.split('.')[1] dsid = int(dsid) - hasShower = tdp.getShower(dsid) in ['sherpa','sherpa21','pythia','pythia8','herwigpp'] + hasShower = tdp.getShower(dsid) in ['sherpa','sherpa21','pythia','pythia8','herwigpp','amcatnlopythia8', 'herwigpp713', 'sherpa228'] #print hasShower," ",sample if not tdp.hasID(dsid) or not hasShower: noShowerDatasets += [dsid] if len(noShowerDatasets) > 0: - print 'The following datasets do not have a showering algorithm defined in TopDataPreparation and will fail on the grid. Please ask for this to be fixed in TopDataPreparation!' + print('TopDataPreparation .data file specified in '+settingsFilePath+' was checked.') + print('The following datasets do not have a showering algorithm defined in TopDataPreparation and will fail on the grid. Please ask for this to be fixed in TopDataPreparation!') for ds in set(noShowerDatasets): - print ds + print(ds) raise RuntimeError("Datasets without shower.") + +def isAF2(dataset): + tags = dataset.split('.')[-1] + tagList = tags.split('_') + for tag in tagList: + if tag.find('a')>-1: + return True + return False + +def isData(dataset): + scope = dataset.split('.')[0] + if scope.find('data')>-1: + return True + else: + return False + +def checkPRWFile(Samples, cutfile): + # Some imports + import subprocess, shlex + + # We need to find the PRW files being used and make use of the checkPRW + # checkPRW.py --inDsTxt=my.datasets.txt path/to/prwConfigs/*.root + # First, find the PRW names from cutfile + settingsFilePath = ROOT.PathResolver.find_file(cutfile, "DATAPATH", ROOT.PathResolver.LocalSearch) + print(logger.OKBLUE + " - Processing checks for PRWConfig in " + settingsFilePath + logger.ENDC) + tmp = open(settingsFilePath, "r") + PRWConfig = None + PRWConfig_FS = None + PRWConfig_AF = None + for line in tmp.readlines(): + line = line.split('#', 1)[0].strip() + if line.startswith("PRWConfigFiles_AF"): + PRWConfig_AF = [ ROOT.PathResolver.find_file( x, "CALIBPATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] + PRWConfig_AF.extend( [ ROOT.PathResolver.find_file( x, "DATAPATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] ) + PRWConfig_AF.extend( [ ROOT.PathResolver.find_file( x, "PATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] ) + elif line.startswith("PRWConfigFiles_FS"): + PRWConfig_FS = [ ROOT.PathResolver.find_file( x, "CALIBPATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] + PRWConfig_FS.extend( [ ROOT.PathResolver.find_file( x, "DATAPATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] ) + PRWConfig_FS.extend( [ ROOT.PathResolver.find_file( x, "PATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] ) + elif line.startswith("PRWConfigFiles"): + PRWConfig = [ ROOT.PathResolver.find_file( x, "CALIBPATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] + PRWConfig.extend( [ ROOT.PathResolver.find_file( x, "DATAPATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] ) + PRWConfig.extend( [ ROOT.PathResolver.find_file( x, "PATH", ROOT.PathResolver.RecursiveSearch ) for x in line.split()[1:] ] ) + + if PRWConfig and PRWConfig_AF: + print(logger.FAIL + " - Problem in cutfile " + settingsFilePath + ": PRWConfigFiles is inconsistent with usage of PRWConfigFiles_AF" + logger.ENDC) + return + elif PRWConfig and PRWConfig_FS: + print(logger.FAIL + " - Problem in cutfile " + settingsFilePath + ": PRWConfigFiles is inconsistent with usage of PRWConfigFiles_FS" + logger.ENDC) + return + elif PRWConfig and not PRWConfig_FS and not PRWConfig_AF: + PRWConfig_FS = PRWConfig + PRWConfig_AF = PRWConfig + elif not PRWConfig and not PRWConfig_FS and not PRWConfig_AF: + print(logger.FAIL + " - Error reading PRWConfigFiles from cutfile" + logger.ENDC) + return + # else: we assume that PRWConfigFiles_FS and PRWConfigFiles_AF are set + + # Print the PRW files + print(logger.OKGREEN + "PRW files used for FS:" + logger.ENDC) + print(logger.OKGREEN + "\n".join(PRWConfig_FS) + logger.ENDC) + print(logger.OKGREEN + "PRW files used for AF2:" + logger.ENDC) + print(logger.OKGREEN + "\n".join(PRWConfig_AF) + logger.ENDC) + + # Create a temporary sample list + tmpFileNameFS = "samplesforprwcheck_FS.txt" + tmpOutFS = open(tmpFileNameFS,"w") + tmpFileNameAF = "samplesforprwcheck_AF.txt" + tmpOutAF = open(tmpFileNameAF,"w") + for List in Samples: + SublistSamples = List.datasets + for sample_concatenated in SublistSamples: # the listed samples may be comma-separated list of samples + for sample in sample_concatenated.split(','): # we need to check all of them, not just the first one + if (isData(sample)): + continue + else: + if not isAF2(sample): + tmpOutFS.write(sample+"\n") + else: + tmpOutAF.write(sample+"\n") + tmpOutFS.close() + tmpOutAF.close() + + # then do the check + if (os.path.getsize(tmpFileNameFS)): # what follows only makes sense if the file isn't empty + # Make the FS command + cmdFS = "checkPRW.py --inDsTxt %s %s"%(tmpFileNameFS, " ".join(PRWConfig_FS)) + print(logger.OKBLUE + " - Running command : " + cmdFS + logger.ENDC) + # Run + procFS = subprocess.Popen(shlex.split(cmdFS)) + procFS.wait() + else: + print(logger.OKBLUE + " - No PRWConfig check is needed for FS." + logger.ENDC) + if (os.path.getsize(tmpFileNameAF)): # what follows only makes sense if the file isn't empty + # Make the AF command + cmdAF = "checkPRW.py --inDsTxt %s %s"%(tmpFileNameAF, " ".join(PRWConfig_AF)) + print(logger.OKBLUE + " - Running command : " + cmdAF + logger.ENDC) + # Run + procAF = subprocess.Popen(shlex.split(cmdAF)) + procAF.wait() + else: + print(logger.OKBLUE + " - No PRWConfig check is needed for AF2." + logger.ENDC) + # At the moment, just print the output, but we need to learn what to catch also + +## gets the first AMI tag of a kind +def getFirstTag(tags,letter): + tagList = tags.split('_') + first = '' + for tag in tagList: + if tag.find(letter,0,1) != -1 and tag[1:].isdigit() and first == '': + first = tag + return first + + +# In MC16, a given DSID can have been "split" into several datasets, were some have more ami-tags +# This function takes as input a coma-separated list of datasets, and returns the name of the first sample if we are in such case +# It throws an error if the DSID of these datasets is different, or if the first ami-tag of each time is different for the different datasets +def getShortenedConcatenatedSample(sampleName): + samples = sampleName.split(',') + if len(samples) == 1: # the simplest case + return samples[0] + + # check if the DSIDs are all the same + DSID = samples[0].split('.')[1] + firstTagOfFirstSample = { 'e':'', 's':'', 'a':'', 'r':'', 'f':'', 'm':'', 'p':'', } + isFirstSample = True + for s in samples: + if s.split('.')[1] != DSID: + print(logger.FAIL + " Issue with this concatenated sample: " + sampleName + logger.ENDC) + print(logger.FAIL + " This syntax can only work if all dataset containers have the same DSID " + logger.ENDC) + raise RuntimeError("Issue with contatenated samples.") + AmiTags = s.split('.')[-1] + for tagType in firstTagOfFirstSample: + if firstTagOfFirstSample[tagType] == '' and isFirstSample: + firstTagOfFirstSample[tagType] = getFirstTag(AmiTags,tagType) + elif firstTagOfFirstSample[tagType] != getFirstTag(AmiTags,tagType): + print(logger.FAIL + " Issue with this concatenated sample: " + sampleName + logger.ENDC) + print(logger.FAIL + " This syntax can only work if all dataset containers have the same first tag of each type " + logger.ENDC) + print(logger.FAIL + " And it seems there are two samples in this list, one with " + firstTagOfFirstSample[tagType] + " and one with " + getFirstTag(AmiTags,tagType) + " as first " + tagType + "-tag" + logger.ENDC) + raise RuntimeError("Issue with contatenated samples.") + isFirstSample = False + return samples[0] # if we survived all the tests, return the first of the list diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/logger.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/logger.py index e34f34601a33..5461d70ea7f7 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/logger.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/logger.py @@ -3,6 +3,6 @@ HEADER = '\033[95m' OKBLUE = '\033[94m' OKGREEN = '\033[92m' -WARNING = '\033[93m' +WARNING = '\033[33m' FAIL = '\033[91m' -ENDC = '\033[m' \ No newline at end of file +ENDC = '\033[m' diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/plot.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/plot.py index dca8f4cb7181..dde501e1a954 100755 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/plot.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/plot.py @@ -14,9 +14,9 @@ ROOT.gROOT.SetBatch(True) def makeDirectory(outputDirectory): try: os.makedirs(outputDirectory) - print 'Made directory', outputDirectory + print('Made directory', outputDirectory) except: - print 'directory already exists:', outputDirectory + print('directory already exists:', outputDirectory) pass class Proc: @@ -42,9 +42,9 @@ class Plotter: makeDirectory(self.imgDirectory) - print logger.OKBLUE +'Stack configuration'+ logger.ENDC + print(logger.OKBLUE +'Stack configuration'+ logger.ENDC) for currentProcess in stack: - print ' Name %s Colour %d Caption %s' % (currentProcess.name, currentProcess.colour, currentProcess.caption) + print(' Name %s Colour %d Caption %s' % (currentProcess.name, currentProcess.colour, currentProcess.caption)) def doneAndDusted(self): self.out.write('</html>\n') @@ -54,7 +54,7 @@ class Plotter: if not self.files.has_key(fileName): f = ROOT.TFile.Open(fileName) if not f: - print logger.FAIL + 'Failed to open %s' % fileName + logger.ENDC + print(logger.FAIL + 'Failed to open %s' % fileName + logger.ENDC) raise Exception('Failed to open %s' % fileName) self.files[fileName] = f @@ -81,7 +81,7 @@ class Plotter: return legend def plot(self, histName): - print 'plotting ', histName + print('plotting ', histName) self.c1.Clear() entries = [] diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/web.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/web.py index 4628028985ab..d64280be04b4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/web.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/python/web.py @@ -27,10 +27,10 @@ def makeDict(scope, query): def makeTable(name, ids): - print '---++ %s (%d)' % (name, len(ids)) + print('---++ %s (%d)' % (name, len(ids))) - print '''%TABLE{tablewidth="100%" columnwidths="6%,70%,12%,12%"}%''' - print '| %8s | %60s | %22s | %22s | %22s | %22s |' % ( '*DSID*', '*Description*', '*Primary xAOD yield*', '*TOPQ1 yield*', '*Primary size [GB]*', '*xAOD size [GB]*' ) + print('''%TABLE{tablewidth="100%" columnwidths="6%,70%,12%,12%"}%''') + print('| %8s | %60s | %22s | %22s | %22s | %22s |' % ( '*DSID*', '*Description*', '*Primary xAOD yield*', '*TOPQ1 yield*', '*Primary size [GB]*', '*xAOD size [GB]*' )) for id in ids: dsids_sofar.append(id) @@ -96,35 +96,17 @@ def makeTable(name, ids): topq1_size_txt = "%15d (%0.0f%%)" % (topq1_size * toGB, frac) - print '| %d|%s| %d| %s| %4.2f| %s|' % (id, twisty, aod_yield, topq1_yield_txt, aod_size * toGB, topq1_size_txt) + print('| %d|%s| %d| %s| %4.2f| %s|' % (id, twisty, aod_yield, topq1_yield_txt, aod_size * toGB, topq1_size_txt)) - print '' + print('') if __name__ == '__main__': query = '*.AOD.*_r5591_r5625' query13 = '*.merge.AOD.*_r5787_r5853' - print '%TOC%' + print('%TOC%') - print ''' -On this page we have listed the main DC14 samples. You can find more details on -the DC14StartPage and DC14DataMCSampleInfo. - -For 8 !TeV we list - * *Primary xAOD:* =%s= - * *TOPQ1:* =%s= - -For 13 !TeV we list - * *Primary xAOD:* =%s= - * *TOPQ1:* =%s= - -For more details on which containers are removed see TopDerivations. -No event selection is currently applied to MC in TOPQ1. -Since the only difference between TOPQ1 and TOPQ2 is the event selection we -don't make TOPQ2 for MC. -''' % (query, query.replace('AOD','DAOD_TOPQ1') + '_p1854', query13, query13.replace('AOD','DAOD_TOPQ1') + '_p1852') - - print '---+ Introduction' + print('---+ Introduction') aods_idtag, aods_idonly = makeDict('mc14_8TeV', query) topq1_idtag, topq1_idonly = makeDict('mc14_8TeV', query.replace('AOD','DAOD_TOPQ1') + '_p1854') @@ -138,7 +120,7 @@ don't make TOPQ2 for MC. #sys.exit() dsids_sofar = [] - print '---+ 8 !TeV' + print('---+ 8 !TeV') makeTable('ttbar', [117050]) makeTable('single top', [110101, 110119, 110140]) @@ -163,7 +145,7 @@ don't make TOPQ2 for MC. dsids_sofar = [] - print '---+ 13 !TeV' + print('---+ 13 !TeV') makeTable('ttbar', [110401]) makeTable('single top', [110070, 110071, 110305]) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/01SubmitToGrid.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/01SubmitToGrid.py index 33a6e28001b3..e37a7f43a8b7 100755 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/01SubmitToGrid.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/01SubmitToGrid.py @@ -1,23 +1,40 @@ #!/usr/bin/env python -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration import TopExamples.grid import DerivationTags -import Data -import MC15c_TOPQ1 +import Data_rel21 +import MC16_TOPQ1 + +## fancy function to shorten the physics part of the name of a sample +#def MyFancyShortener(superLongInDSName): + #splitted = superLongInDSName.split('.') + #runNumber = splitted[1] + #physicsName = splitted[2] + #if splitted[0] == "user" or splitted[0] == "group": #this is in case we run on private derivations, either produced with user or group role + #runNumber = splitted[2] + #physicsName = splitted[3] + #tags = splitted[-1].replace('/','') + #physicsName = physicsName.split('_')[0] + #outDSName = runNumber + '.' + physicsName + '.someFunnyTags' + #return outDSName config = TopExamples.grid.Config() config.code = 'top-xaod' -config.settingsFile = 'dil-cuts.txt' +config.settingsFile = 'validation-cuts.txt' +#config.settingsFile = 'validation-cuts_Topo.txt,validation-cuts_PFlow.txt' +#config.combine_outputFile = 'out.root' +#config.combine_prefixes = 'Topo,PFlow' -config.gridUsername = 'aknue' -config.suffix = '02-04-24' +config.gridUsername = 'iconnell' # use e.g. phys-top or phys-higgs for group production +config.suffix = '17-10-03' config.excludedSites = '' config.noSubmit = False config.mergeType = 'Default' #'None', 'Default' or 'xAOD' config.destSE = '' #This is the default (anywhere), or try e.g. 'UKI-SOUTHGRID-BHAM-HEP_LOCALGROUPDISK' # by default the requested memory is set to 2GB, if you need to increase this, please disable the line below!!! # config.memory = '4000' +#config.nameShortener = MyFancyShortener # to use your own physics part shortening function - uncomment here and in the function definition above ############################################################################### @@ -32,26 +49,31 @@ config.destSE = '' #This is the default (anywhere), or try e.g. 'UKI-SOUT ############################################################################### -# Data - look in Data.py -# Change if you want TOPQ2/3/4 -names = ['Data15_TOPQ1', 'Data16_TOPQ1'] +# Data - look in Data_rel21.py +# Change if you want TOPQ2/3/4/5 +names = ['Data15_TOPQ1', + 'Data16_TOPQ1', + 'Data17_TOPQ1'] samples = TopExamples.grid.Samples(names) +TopExamples.ami.check_sample_status(samples) # Call with (samples, True) to halt on error TopExamples.grid.submit(config, samples) ############################################################################### -###MC Simulation - look in MC15c_TOPQ1.py +###MC Simulation - look in MC16_TOPQ1.py ###Using list of TOPQ1 25ns MC samples, consistent mixture of p-tags ###Edit these lines if you don't want to run everything! -names = [ - 'TOPQ1_ttbar_PowPy6', - 'TOPQ1_singleTop_PowPy6', - 'TOPQ1_ttV', - 'TOPQ1_Wjets_Sherpa221', - 'TOPQ1_Zjets_Sherpa221', - 'TOPQ1_Diboson_Sherpa', -] - +names = ['TOPQ1_ttbar_PowPy8', + 'TOPQ1_ttbar_dil_PowPy8', + 'TOPQ1_tchan_lep_PowPy6', + 'TOPQ1_Wt_inc_PowPy6', + 'TOPQ1_schan_noAllHad_PowPy6', + 'TOPQ1_diboson_Sherpa', + 'TOPQ1_Zjets_Sherpa221', + 'TOPQ1_Wjets_Sherpa221', + 'TOPQ1_ttV', + ] samples = TopExamples.grid.Samples(names) +TopExamples.ami.check_sample_status(samples) # Call with (samples, True) to halt on error TopExamples.grid.submit(config, samples) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/Data_rel21.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/Data_rel21.py index f9593fb3a49b..b8495f2ecce1 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/Data_rel21.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/Data_rel21.py @@ -3,17 +3,336 @@ import TopExamples.grid import TopExamples.ami -# Just a few runs processed with 21.0.19.2 -DATA16 = [ - 'data16_13TeV.00297730.physics_Main.deriv.DAOD_{}.r9264_p3083_p3142', - 'data16_13TeV.00304008.physics_Main.deriv.DAOD_{}.r9264_p3083_p3142', - 'data16_13TeV.00307126.physics_Main.deriv.DAOD_{}.r9264_p3083_p3142', - 'data16_13TeV.00311071.physics_Main.deriv.DAOD_{}.r9264_p3083_p3142', - 'data16_13TeV.00311287.physics_Main.deriv.DAOD_{}.r9264_p3083_p3142', - 'data16_13TeV.00311321.physics_Main.deriv.DAOD_{}.r9264_p3083_p3142', - ] +# Period containers +DATA15 = ['data15_13TeV.periodA.physics_Main.PhysCont.DAOD_{}.grp15_v01_p3180', + 'data15_13TeV.periodC.physics_Main.PhysCont.DAOD_{}.grp15_v01_p3180', + 'data15_13TeV.periodD.physics_Main.PhysCont.DAOD_{}.grp15_v01_p3180', + 'data15_13TeV.periodE.physics_Main.PhysCont.DAOD_{}.grp15_v01_p3180', + 'data15_13TeV.periodF.physics_Main.PhysCont.DAOD_{}.grp15_v01_p3180', + 'data15_13TeV.periodG.physics_Main.PhysCont.DAOD_{}.grp15_v01_p3180', + 'data15_13TeV.periodH.physics_Main.PhysCont.DAOD_{}.grp15_v01_p3180', + 'data15_13TeV.periodJ.physics_Main.PhysCont.DAOD_{}.grp15_v01_p3180',] + +DATA16 = ['data16_13TeV.periodA.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodB.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodC.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodD.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodE.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodF.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodG.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodI.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodK.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180', + 'data16_13TeV.periodL.physics_Main.PhysCont.DAOD_{}.grp16_v01_p3180',] + +DATA17 = ['data17_13TeV.periodB.physics_Main.PhysCont.DAOD_{}.grp17_v01_p3213', + 'data17_13TeV.periodC.physics_Main.PhysCont.DAOD_{}.grp17_v01_p3213', + 'data17_13TeV.periodD.physics_Main.PhysCont.DAOD_{}.grp17_v01_p3267', + 'data17_13TeV.periodE.physics_Main.PhysCont.DAOD_{}.grp17_v01_p3267', + # Period F is waiting for feedback on the runs to use... + ] + +DATA15RUN = [ 'data15_13TeV.00276689.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00284006.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00271048.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00270806.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281381.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00284427.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00283780.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279867.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00282784.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279928.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276336.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276731.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00271516.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276329.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276416.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279284.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00270953.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276511.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276245.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00283608.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276952.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00282992.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00267152.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281143.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279345.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279259.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280423.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00270816.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00283074.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280319.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276073.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280977.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280368.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00271388.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00267073.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280673.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281070.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279685.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281411.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00284285.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276161.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281385.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276212.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281317.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00267167.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276790.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279813.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276183.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280500.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00278912.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279932.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00283155.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00278968.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00282631.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00284473.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00266919.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276954.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00266904.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281130.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00283270.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281075.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00278748.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280464.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276189.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00281074.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00271421.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00284484.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279169.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00271744.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280520.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280950.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00270588.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279279.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279764.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00267162.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00270949.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280273.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276330.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280614.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280853.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00282625.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276262.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279515.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00270448.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00278727.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00267639.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00278970.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00270441.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00278880.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280231.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276176.physics_Main.deriv.DAOD_{}.r9412_p3083_p3180', + 'data15_13TeV.00282712.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00271595.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280862.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276778.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279598.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276181.physics_Main.deriv.DAOD_{}.r9412_p3083_p3180', + 'data15_13TeV.00283429.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00284420.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00284154.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00279984.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00267638.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00284213.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00271298.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00280753.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data15_13TeV.00276147.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + ] + +# all data16 runs available with 21.0.19.4 + +DATA16RUN = [ 'data16_13TeV.00297730.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298595.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298609.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298633.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298687.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298690.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298771.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298773.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298862.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00298967.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299055.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299144.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299147.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299184.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299241.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299243.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299288.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299343.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00299584.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300279.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300345.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300415.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300418.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300487.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300540.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300571.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300600.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300655.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300687.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300784.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300800.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300863.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00300908.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00301912.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00301915.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00301918.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00301932.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00301973.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302053.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302137.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302265.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302269.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302300.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302347.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302380.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302391.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302393.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302737.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302829.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302831.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302872.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302919.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302925.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00302956.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303007.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303059.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303079.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303201.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303208.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303264.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303266.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303291.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303304.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303338.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303421.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303499.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303560.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303638.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303832.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303846.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303892.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00303943.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304006.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304008.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304128.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304178.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304198.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304211.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304243.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304308.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304337.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304409.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304431.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00304494.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305380.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305543.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305571.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305618.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305671.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305674.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305723.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305727.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305735.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305777.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305811.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00305920.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00306269.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00306278.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00306310.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00306384.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00306419.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00306442.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00306448.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00306451.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307126.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307195.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307259.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307306.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307354.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307358.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307394.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307454.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307514.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307539.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307569.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307601.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307619.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307656.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307710.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307716.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307732.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307861.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00307935.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00308047.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00308084.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00309375.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00309390.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00309440.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00309516.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00309640.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00309674.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00309759.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310015.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310247.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310249.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310341.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310370.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310405.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310468.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310473.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310634.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310691.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310738.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310809.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310863.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310872.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00310969.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311071.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311170.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311244.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311287.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311321.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311365.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311402.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311473.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + 'data16_13TeV.00311481.physics_Main.deriv.DAOD_{}.r9264_p3083_p3180', + ] + +# Use the period containers which have removed duplicate runs with different tags +DATA17RUN = [ ] + +# Individual runs +TopExamples.grid.Add('Data15Runs_TOPQ1').datasets = [i.format('TOPQ1') for i in DATA15RUN] +TopExamples.grid.Add('Data15Runs_TOPQ2').datasets = [i.format('TOPQ2') for i in DATA15RUN] +TopExamples.grid.Add('Data15Runs_TOPQ3').datasets = [i.format('TOPQ3') for i in DATA15RUN] +TopExamples.grid.Add('Data15Runs_TOPQ4').datasets = [i.format('TOPQ4') for i in DATA15RUN] +TopExamples.grid.Add('Data15Runs_TOPQ5').datasets = [i.format('TOPQ5') for i in DATA15RUN] + +TopExamples.grid.Add('Data16Runs_TOPQ1').datasets = [i.format('TOPQ1') for i in DATA16RUN] +TopExamples.grid.Add('Data16Runs_TOPQ2').datasets = [i.format('TOPQ2') for i in DATA16RUN] +TopExamples.grid.Add('Data16Runs_TOPQ3').datasets = [i.format('TOPQ3') for i in DATA16RUN] +TopExamples.grid.Add('Data16Runs_TOPQ4').datasets = [i.format('TOPQ4') for i in DATA16RUN] +TopExamples.grid.Add('Data16Runs_TOPQ5').datasets = [i.format('TOPQ5') for i in DATA16RUN] + +TopExamples.grid.Add('Data17Runs_TOPQ1').datasets = [i.format('TOPQ1') for i in DATA17RUN] +TopExamples.grid.Add('Data17Runs_TOPQ2').datasets = [i.format('TOPQ2') for i in DATA17RUN] +TopExamples.grid.Add('Data17Runs_TOPQ3').datasets = [i.format('TOPQ3') for i in DATA17RUN] +TopExamples.grid.Add('Data17Runs_TOPQ4').datasets = [i.format('TOPQ4') for i in DATA17RUN] +TopExamples.grid.Add('Data17Runs_TOPQ5').datasets = [i.format('TOPQ5') for i in DATA17RUN] + +# Period containers - preferred choice +TopExamples.grid.Add('Data15_TOPQ1').datasets = [i.format('TOPQ1') for i in DATA15] +TopExamples.grid.Add('Data15_TOPQ2').datasets = [i.format('TOPQ2') for i in DATA15] +TopExamples.grid.Add('Data15_TOPQ3').datasets = [i.format('TOPQ3') for i in DATA15] +TopExamples.grid.Add('Data15_TOPQ4').datasets = [i.format('TOPQ4') for i in DATA15] TopExamples.grid.Add('Data16_TOPQ1').datasets = [i.format('TOPQ1') for i in DATA16] TopExamples.grid.Add('Data16_TOPQ2').datasets = [i.format('TOPQ2') for i in DATA16] TopExamples.grid.Add('Data16_TOPQ3').datasets = [i.format('TOPQ3') for i in DATA16] TopExamples.grid.Add('Data16_TOPQ4').datasets = [i.format('TOPQ4') for i in DATA16] + +TopExamples.grid.Add('Data17_TOPQ1').datasets = [i.format('TOPQ1') for i in DATA17] +TopExamples.grid.Add('Data17_TOPQ2').datasets = [i.format('TOPQ2') for i in DATA17] +TopExamples.grid.Add('Data17_TOPQ3').datasets = [i.format('TOPQ3') for i in DATA17] +TopExamples.grid.Add('Data17_TOPQ4').datasets = [i.format('TOPQ4') for i in DATA17] diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/MC16_TOPQ1.py b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/MC16_TOPQ1.py index ff488b4cc8af..62d3afbd821d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/MC16_TOPQ1.py +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/MC16_TOPQ1.py @@ -2,7 +2,207 @@ import TopExamples.grid -# just a test sample processed with 21.0.19.2+DerivationFrameworkTop-00-04-06 TopExamples.grid.Add("TOPQ1_ttbar_PowPy8").datasets = [ - "group.phys-top.mc15_13TeV.410501.PowPy8EG_A14_ttbar_hdamp258p75_lep.DAOD_TOPQ1.AOD.e5458_s3126_r9364_r9315_p3144.v1_EXT0", - ] \ No newline at end of file + 'mc16_13TeV.410501.PowhegPythia8EvtGen_A14_ttbar_hdamp258p75_nonallhad.deriv.DAOD_TOPQ1.e5458_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_ttbar_dil_PowPy8").datasets = [ + 'mc16_13TeV.410503.PowhegPythia8EvtGen_A14_ttbar_hdamp258p75_dil.deriv.DAOD_TOPQ1.e5475_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_tchan_lep_PowPy6").datasets = [ + 'mc16_13TeV.410011.PowhegPythiaEvtGen_P2012_singletop_tchan_lept_top.deriv.DAOD_TOPQ1.e3824_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410012.PowhegPythiaEvtGen_P2012_singletop_tchan_lept_antitop.deriv.DAOD_TOPQ1.e3824_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_Wt_inc_PowPy6").datasets = [ + 'mc16_13TeV.410013.PowhegPythiaEvtGen_P2012_Wt_inclusive_top.deriv.DAOD_TOPQ1.e3753_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410014.PowhegPythiaEvtGen_P2012_Wt_inclusive_antitop.deriv.DAOD_TOPQ1.e3753_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_schan_noAllHad_PowPy6").datasets = [ + 'mc16_13TeV.410025.PowhegPythiaEvtGen_P2012_SingleTopSchan_noAllHad_top.deriv.DAOD_TOPQ1.e3998_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410026.PowhegPythiaEvtGen_P2012_SingleTopSchan_noAllHad_antitop.deriv.DAOD_TOPQ1.e3998_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_tZ_noAllHad_PowPy6").datasets = [ + 'mc16_13TeV.410560.MadGraphPythia8EvtGen_A14_tZ_4fl_tchan_noAllHad.deriv.DAOD_TOPQ1.e5803_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_tZ_trilepton_PowPy6").datasets = [ + 'mc16_13TeV.410550.MadGraphPythia8EvtGen_A14_tZ_4fl_tchan_trilepton.deriv.DAOD_TOPQ1.e5803_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_tWZ").datasets = [ + 'mc16_13TeV.410217.aMcAtNloHerwigppEvtGen_UEEE5_CTEQ6L1_CT10ME_260000_tWZDR.deriv.DAOD_TOPQ1.e4851_s3126_r9364_r9315_p3215', + ] + + +TopExamples.grid.Add("TOPQ1_ttbargamma").datasets = [ + 'mc16_13TeV.410082.MadGraphPythia8EvtGen_A14NNPDF23LO_ttgamma_noallhad.deriv.DAOD_TOPQ1.e4404_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_photons").datasets = [ + 'mc16_13TeV.301535.Sherpa_CT10_eegammaPt10_35.deriv.DAOD_TOPQ1.e3952_s3126_r9364_r9315_p3215', + 'mc16_13TeV.301536.Sherpa_CT10_mumugammaPt10_35.deriv.DAOD_TOPQ1.e3952_s3126_r9364_r9315_p3215', + 'mc16_13TeV.301899.Sherpa_CT10_eegammaPt35_70.deriv.DAOD_TOPQ1.e3952_s3126_r9364_r9315_p3215', + 'mc16_13TeV.301900.Sherpa_CT10_eegammaPt70_140.deriv.DAOD_TOPQ1.e3952_s3126_r9364_r9315_p3215', + 'mc16_13TeV.301901.Sherpa_CT10_eegammaPt140.deriv.DAOD_TOPQ1.e3952_s3126_r9364_r9315_p3215', + 'mc16_13TeV.301902.Sherpa_CT10_mumugammaPt35_70.deriv.DAOD_TOPQ1.e3952_s3126_r9364_r9315_p3215', + 'mc16_13TeV.301903.Sherpa_CT10_mumugammaPt70_140.deriv.DAOD_TOPQ1.e3952_s3126_r9364_r9315_p3215', + 'mc16_13TeV.301904.Sherpa_CT10_mumugammaPt140.deriv.DAOD_TOPQ1.e3952_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364510.Sherpa_222_NNPDF30NNLO_tautaugamma_pty_7_15.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364511.Sherpa_222_NNPDF30NNLO_tautaugamma_pty_15_35.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364512.Sherpa_222_NNPDF30NNLO_tautaugamma_pty_35_70.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364513.Sherpa_222_NNPDF30NNLO_tautaugamma_pty_70_140.deriv.DAOD_TOPQ1.e5982_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364514.Sherpa_222_NNPDF30NNLO_tautaugamma_pty_140_E_CMS.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364517.Sherpa_222_NNPDF30NNLO_nunugamma_pty_35_70.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364518.Sherpa_222_NNPDF30NNLO_nunugamma_pty_70_140.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364519.Sherpa_222_NNPDF30NNLO_nunugamma_pty_140_E_CMS.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364521.Sherpa_222_NNPDF30NNLO_enugamma_pty_7_15.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364523.Sherpa_222_NNPDF30NNLO_enugamma_pty_35_70.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364524.Sherpa_222_NNPDF30NNLO_enugamma_pty_70_140.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364525.Sherpa_222_NNPDF30NNLO_enugamma_pty_140_E_CMS.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364526.Sherpa_222_NNPDF30NNLO_munugamma_pty_7_15.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364528.Sherpa_222_NNPDF30NNLO_munugamma_pty_35_70.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364529.Sherpa_222_NNPDF30NNLO_munugamma_pty_70_140.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364530.Sherpa_222_NNPDF30NNLO_munugamma_pty_140_E_CMS.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364531.Sherpa_222_NNPDF30NNLO_taunugamma_pty_7_15.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364533.Sherpa_222_NNPDF30NNLO_taunugamma_pty_35_70.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364534.Sherpa_222_NNPDF30NNLO_taunugamma_pty_70_140.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364535.Sherpa_222_NNPDF30NNLO_taunugamma_pty_140_E_CMS.deriv.DAOD_TOPQ1.e5928_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_diboson_Sherpa").datasets = [ + 'mc16_13TeV.363355.Sherpa_221_NNPDF30NNLO_ZqqZvv.deriv.DAOD_TOPQ1.e5525_s3126_r9364_r9315_p3215', + 'mc16_13TeV.363356.Sherpa_221_NNPDF30NNLO_ZqqZll.deriv.DAOD_TOPQ1.e5525_s3126_r9364_r9315_p3215', + 'mc16_13TeV.363357.Sherpa_221_NNPDF30NNLO_WqqZvv.deriv.DAOD_TOPQ1.e5525_s3126_r9364_r9315_p3215', + 'mc16_13TeV.363358.Sherpa_221_NNPDF30NNLO_WqqZll.deriv.DAOD_TOPQ1.e5525_s3126_r9364_r9315_p3215', + 'mc16_13TeV.363359.Sherpa_221_NNPDF30NNLO_WpqqWmlv.deriv.DAOD_TOPQ1.e5583_s3126_r9364_r9315_p3215', + 'mc16_13TeV.363360.Sherpa_221_NNPDF30NNLO_WplvWmqq.deriv.DAOD_TOPQ1.e5583_s3126_r9364_r9315_p3215', + 'mc16_13TeV.363360.Sherpa_221_NNPDF30NNLO_WplvWmqq.deriv.DAOD_TOPQ1.e5983_s3126_r9364_r9315_p3215', + 'mc16_13TeV.363489.Sherpa_221_NNPDF30NNLO_WlvZqq.deriv.DAOD_TOPQ1.e5525_s3126_r9364_r9315_p3215', + 'mc16_13TeV.363494.Sherpa_221_NNPDF30NNLO_vvvv.deriv.DAOD_TOPQ1.e5332_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364250.Sherpa_222_NNPDF30NNLO_llll.deriv.DAOD_TOPQ1.e5894_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364253.Sherpa_222_NNPDF30NNLO_lllv.deriv.DAOD_TOPQ1.e5916_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364254.Sherpa_222_NNPDF30NNLO_llvv.deriv.DAOD_TOPQ1.e5916_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364255.Sherpa_222_NNPDF30NNLO_lvvv.deriv.DAOD_TOPQ1.e5916_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_Zjets_Sherpa221").datasets = [ + 'mc16_13TeV.364100.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV0_70_CVetoBVeto.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364101.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV0_70_CFilterBVeto.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364102.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364103.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV70_140_CVetoBVeto.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364104.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV70_140_CFilterBVeto.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364105.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV70_140_BFilter.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364106.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV140_280_CVetoBVeto.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364107.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV140_280_CFilterBVeto.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364108.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV140_280_BFilter.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364109.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV280_500_CVetoBVeto.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364110.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV280_500_CFilterBVeto.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364111.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV280_500_BFilter.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364112.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV500_1000.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364113.Sherpa_221_NNPDF30NNLO_Zmumu_MAXHTPTV1000_E_CMS.deriv.DAOD_TOPQ1.e5271_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364114.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV0_70_CVetoBVeto.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364115.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV0_70_CFilterBVeto.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364116.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364117.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV70_140_CVetoBVeto.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364118.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV70_140_CFilterBVeto.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364119.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV70_140_BFilter.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364120.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV140_280_CVetoBVeto.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364121.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV140_280_CFilterBVeto.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364122.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV140_280_BFilter.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364123.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV280_500_CVetoBVeto.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364124.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV280_500_CFilterBVeto.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364125.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV280_500_BFilter.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364126.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV500_1000.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364127.Sherpa_221_NNPDF30NNLO_Zee_MAXHTPTV1000_E_CMS.deriv.DAOD_TOPQ1.e5299_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364128.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV0_70_CVetoBVeto.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364129.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV0_70_CFilterBVeto.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364130.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364131.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV70_140_CVetoBVeto.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364132.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV70_140_CFilterBVeto.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364133.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV70_140_BFilter.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364134.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV140_280_CVetoBVeto.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364135.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV140_280_CFilterBVeto.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364136.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV140_280_BFilter.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364137.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV280_500_CVetoBVeto.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364138.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV280_500_CFilterBVeto.deriv.DAOD_TOPQ1.e5313_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364139.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV280_500_BFilter.deriv.DAOD_TOPQ1.e5313_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364140.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV500_1000.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364141.Sherpa_221_NNPDF30NNLO_Ztautau_MAXHTPTV1000_E_CMS.deriv.DAOD_TOPQ1.e5307_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364198.Sherpa_221_NN30NNLO_Zmm_Mll10_40_MAXHTPTV0_70_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364199.Sherpa_221_NN30NNLO_Zmm_Mll10_40_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364200.Sherpa_221_NN30NNLO_Zmm_Mll10_40_MAXHTPTV70_280_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364201.Sherpa_221_NN30NNLO_Zmm_Mll10_40_MAXHTPTV70_280_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364202.Sherpa_221_NN30NNLO_Zmm_Mll10_40_MAXHTPTV280_E_CMS_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364203.Sherpa_221_NN30NNLO_Zmm_Mll10_40_MAXHTPTV280_E_CMS_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364204.Sherpa_221_NN30NNLO_Zee_Mll10_40_MAXHTPTV0_70_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364205.Sherpa_221_NN30NNLO_Zee_Mll10_40_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364206.Sherpa_221_NN30NNLO_Zee_Mll10_40_MAXHTPTV70_280_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364207.Sherpa_221_NN30NNLO_Zee_Mll10_40_MAXHTPTV70_280_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364208.Sherpa_221_NN30NNLO_Zee_Mll10_40_MAXHTPTV280_E_CMS_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364209.Sherpa_221_NN30NNLO_Zee_Mll10_40_MAXHTPTV280_E_CMS_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364210.Sherpa_221_NN30NNLO_Ztt_Mll10_40_MAXHTPTV0_70_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364211.Sherpa_221_NN30NNLO_Ztt_Mll10_40_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364212.Sherpa_221_NN30NNLO_Ztt_Mll10_40_MAXHTPTV70_280_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364213.Sherpa_221_NN30NNLO_Ztt_Mll10_40_MAXHTPTV70_280_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364214.Sherpa_221_NN30NNLO_Ztt_Mll10_40_MAXHTPTV280_E_CMS_BVeto.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364215.Sherpa_221_NN30NNLO_Ztt_Mll10_40_MAXHTPTV280_E_CMS_BFilter.deriv.DAOD_TOPQ1.e5421_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_Wjets_Sherpa221").datasets = [ + 'mc16_13TeV.364156.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV0_70_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364157.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV0_70_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364158.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364159.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV70_140_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364160.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV70_140_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364161.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV70_140_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364162.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV140_280_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364163.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV140_280_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364164.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV140_280_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364165.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV280_500_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364166.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV280_500_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364167.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV280_500_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364168.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV500_1000.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364169.Sherpa_221_NNPDF30NNLO_Wmunu_MAXHTPTV1000_E_CMS.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364170.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV0_70_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364171.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV0_70_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364172.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364173.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV70_140_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364174.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV70_140_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364175.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV70_140_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364176.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV140_280_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364177.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV140_280_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364178.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV140_280_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364179.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV280_500_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364180.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV280_500_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364181.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV280_500_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364182.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV500_1000.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364183.Sherpa_221_NNPDF30NNLO_Wenu_MAXHTPTV1000_E_CMS.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364184.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV0_70_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364185.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV0_70_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364186.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV0_70_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364187.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV70_140_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364188.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV70_140_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364189.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV70_140_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364190.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV140_280_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364191.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV140_280_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364192.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV140_280_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364193.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV280_500_CVetoBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364194.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV280_500_CFilterBVeto.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364195.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV280_500_BFilter.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364196.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV500_1000.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + 'mc16_13TeV.364197.Sherpa_221_NNPDF30NNLO_Wtaunu_MAXHTPTV1000_E_CMS.deriv.DAOD_TOPQ1.e5340_s3126_r9364_r9315_p3215', + ] + +TopExamples.grid.Add("TOPQ1_ttV").datasets = [ + 'mc16_13TeV.410081.MadGraphPythia8EvtGen_A14NNPDF23_ttbarWW.deriv.DAOD_TOPQ1.e4111_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410155.aMcAtNloPythia8EvtGen_MEN30NLO_A14N23LO_ttW.deriv.DAOD_TOPQ1.e5070_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410156.aMcAtNloPythia8EvtGen_MEN30NLO_A14N23LO_ttZnunu.deriv.DAOD_TOPQ1.e5070_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410157.aMcAtNloPythia8EvtGen_MEN30NLO_A14N23LO_ttZqq.deriv.DAOD_TOPQ1.e5070_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410218.aMcAtNloPythia8EvtGen_MEN30NLO_A14N23LO_ttee.deriv.DAOD_TOPQ1.e5070_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410219.aMcAtNloPythia8EvtGen_MEN30NLO_A14N23LO_ttmumu.deriv.DAOD_TOPQ1.e5070_s3126_r9364_r9315_p3215', + 'mc16_13TeV.410220.aMcAtNloPythia8EvtGen_MEN30NLO_A14N23LO_tttautau.deriv.DAOD_TOPQ1.e5070_s3126_r9364_r9315_p3215', + ] diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/getExamples b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/getExamples index 71008675d549..875d6375cc7e 100755 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/getExamples +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/scripts/getExamples @@ -1,6 +1,8 @@ #!/usr/bin/env python import sys import os +import ROOT +from PathResolver import PathResolver output = os.getcwd() + '/grid' if len(sys.argv) == 2: @@ -13,13 +15,25 @@ elif len(sys.argv) > 2: print sys.argv[0], '<directory>' sys.exit() -print 'copying scripts to', output -start = os.getenv('ROOTCOREBIN') + '/user_scripts/TopExamples/*.py' -#print start +# We cannot use a wildcard anymore as everything is stored in /bin/ +list_of_scripts = ["01SubmitToGrid.py", + "02DownloadFromGrid.py", + "03LocalAnalysis.py", + "04Plot.py", + "10AmiYield.py", + "11CrossSection.py", + "DerivationTags.py", + "Data_rel21.py", + "MC16_TOPQ1.py" + ] +print 'Using PathResolver to copy scripts to', output if not os.path.exists(output): os.makedirs(output) -cmd = 'cp ' + start + ' ' + output -#print cmd -os.system(cmd) +for script in list_of_scripts: + full_path = ROOT.PathResolver.find_file(script, "PATH") + print "Copying",full_path + cmd = "cp %s %s"%(full_path, output) + os.system(cmd) + diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/util/combineATOutputs.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/util/combineATOutputs.cxx new file mode 100644 index 000000000000..ce3a13a2f871 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/util/combineATOutputs.cxx @@ -0,0 +1,168 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include <TROOT.h> +#include <TFile.h> +#include <TList.h> +#include <TKey.h> +#include <TString.h> +#include <TObject.h> +#include <TTree.h> + +#include <string> +#include <iostream> +#include <algorithm> +#include <memory> +#include <cstdio> + +// for debugging +// #define XXX std::cout << "I am here: " << __FILE__ << ":" << __LINE__ << std::endl; + +// this function is adapted from René Brun's $ROOTSYS/tutorials/io/copyFiles.C macro +void CopyDirToNewDir(std::shared_ptr<TDirectory> source, std::shared_ptr<TDirectory> outFile, TString prefix="") { + //copy all objects and subdirs of directory source as a subdir of the current directory +// source->ls(); + outFile->cd(); + //loop on all entries of this directory + TKey *key; + TIter nextkey(source->GetListOfKeys()); + while ((key = (TKey*)nextkey())) { + const char *classname = key->GetClassName(); + TClass* cl = gROOT->GetClass(classname); + if (!cl) continue; + if (cl->InheritsFrom(TDirectory::Class())) { + source->cd(key->GetName()); + std::shared_ptr<TDirectory> subdir(gDirectory); + TString name = prefix; + if (prefix != "") name.Append("_"); + name+=subdir->GetName(); + std::shared_ptr<TDirectory> adir{outFile->mkdir(name)}; + outFile->cd(); + CopyDirToNewDir(subdir,adir); // no prefix for sub-directories + adir->Write(); + outFile->cd(); + } else if (cl->InheritsFrom(TTree::Class())) { + std::unique_ptr<TTree> T{(TTree*)source->Get(key->GetName())}; + outFile->cd(); + std::unique_ptr<TTree> newT{T->CloneTree(-1,"fast")}; + TString name = prefix; + if (prefix != "") name.Append("_"); + name+=newT->GetName(); + newT->SetName(name); + newT->Write(); + } else { + source->cd(); + std::unique_ptr<TObject>obj{key->ReadObj()}; + outFile->cd(); + TString name = prefix; + if (prefix != "") name.Append("_"); + name+=obj->GetName(); + obj->Write(name); + } + } +} + +int main(int argc, char** argv) { + + if (argc != 3) { + std::cout<<"Usage:"<<std::endl; + std::cout<<" combineATOuputs outputFile inputFile1[:prefix1][,inputFile2[:prefix2][,inputFile3[:prefix3]]]"<<std::endl; + std::cout<<"Examples:"<<std::endl; + std::cout<<" combineATOuputs out_combined.root out_EMTopo.root:EMTopo,out_EMPflow.root:EMPflow"<<std::endl; + std::cout<<" combineATOuputs out_combined.root out_EMTopo.root,out_EMPflow.root:EMPflow"<<std::endl; + exit(1); + } + + // processing the input files string + std::string outString(argv[2]); + std::vector<std::string> tempStringVector; + + // looping on the input files string and split it + std::string::size_type start = 0, end = 0; + while ((end = outString.find(",", start)) != std::string::npos) { + std::string token = outString.substr(start, end - start); + if(token.size()) tempStringVector.push_back(token); + start = end + 1; + } + tempStringVector.push_back(outString.substr(start, end - start));// the last element + + // separate in intput files and prefixes + std::vector<std::string> inFileNames; + std::vector<std::string> prefixes; + for (auto s: tempStringVector) { + std::vector<std::string> tmp; + std::string::size_type st = 0, ed = 0; + while ((ed = s.find(":", st)) != std::string::npos) { + std::string tk = s.substr(st, ed - st); + if(tk.size()) tmp.push_back(tk); + st = ed + 1; + } + tmp.push_back(s.substr(st, ed - st));// the last element + if (tmp.size()>2) { + std::cout<<"Error: can't interpret "<<s<<std::endl; + exit(1); + } + std::string tmp_fileName = tmp[0]; + std::string tmp_prefix = tmp.size()==2?tmp[1]:""; // if no prefix is provided, empty prefix is assumed + + // checking if the file or prefix is not already used + if (std::find(inFileNames.begin(), inFileNames.end(), tmp_fileName) != inFileNames.end()) { + std::cout<<"Error: can't use twice the same input file "<<tmp_fileName<<std::endl; + exit(1); + } + if (std::find(prefixes.begin(), prefixes.end(), tmp_prefix) != prefixes.end()) { + std::cout<<"Error: can't use twice the same prefix "<<tmp_prefix<<std::endl; + exit(1); + } + // checking if the file is not also the name of the output file + if (std::find(inFileNames.begin(), inFileNames.end(), argv[1]) != inFileNames.end()) { + std::cout<<"Error: can't use the input file "<<argv[1]<<" as name for the output file"<<std::endl; + exit(1); + } + + // now adding the input files and prefixed in the vectors + inFileNames.push_back(tmp_fileName); + prefixes.push_back(tmp_prefix); + } + + // the output file + std::string tempOutFileName(argv[1]); + tempOutFileName+=".tmp"; + std::shared_ptr<TFile> fout{TFile::Open(tempOutFileName.c_str(),"recreate")}; + + // now looping on the input files + for (unsigned int i = 0; i<inFileNames.size(); i++) { + std::shared_ptr<TFile> f{TFile::Open(inFileNames[i].c_str(),"read")}; + if (f == nullptr) { + std::cout<<"Error: impossible to open input file"<<inFileNames[i]<<std::endl; + fout->Close(); + exit(1); + } + else if (f->TestBit(TFile::kWriteError)) { + fout->Close(); + exit(1); + } + else { + std::cout<<"Copy content of file "<<inFileNames[i]<<" in file "<<argv[1]<<" with prefix "<<prefixes[i]<<std::endl; + CopyDirToNewDir(f, fout, TString(prefixes[i])); + f->Close(); + } + } + + // check if output file is buggy + if (fout->TestBit(TFile::kWriteError)) { + std::cout<<"Error: output file looks buggy"<<std::endl; + fout->Close(); + exit(1); + } + fout->Close(); + + // rename output file with its final name - crash if we can't do that + if (std::rename(fout->GetName(), argv[1]) != 0) { + std::cout<<"Error: impossible to rename output file"<<std::endl; + exit(1); + } + + return 0; +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/CMakeLists.txt deleted file mode 100644 index 6c3b0ad7cc72..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -# Auto-generated on: 2017-03-08 14:47:37.415174 - -# Declare the name of this package: -atlas_subdir( TopHLUpgrade None ) - -# This package depends on other packages: -atlas_depends_on_subdirs( PUBLIC - TopConfiguration - TopEvent - xAODTruth - xAODJet - xAODMissingET - TopParticleLevel - UpgradePerformanceFunctions ) - -# This package uses ROOT: -find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) - -# Generate a CINT dictionary source file: -atlas_add_root_dictionary( TopHLUpgrade _cintDictSource - ROOT_HEADERS Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) - -# Build a library that other components can link against: -atlas_add_library( TopHLUpgrade Root/*.cxx Root/*.h Root/*.icc - TopHLUpgrade/*.h TopHLUpgrade/*.icc TopHLUpgrade/*/*.h - TopHLUpgrade/*/*.icc ${_cintDictSource} - PUBLIC_HEADERS TopHLUpgrade - LINK_LIBRARIES TopConfiguration - TopEvent - xAODTruth - xAODJet - xAODMissingET - TopParticleLevel - UpgradePerformanceFunctions - ${ROOT_LIBRARIES} - INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/LinkDef.h deleted file mode 100644 index f9fa452558b6..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/LinkDef.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifdef __CINT__ - -#pragma link off all globals; -#pragma link off all classes; -#pragma link off all functions; -#pragma link C++ nestedclass; - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradeLeptonObjectSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradeLeptonObjectSelector.cxx deleted file mode 100644 index 3775b5e013f9..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradeLeptonObjectSelector.cxx +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Filename: UpgradeLeptonObjectSelector.cxx -// Description: -// Author: Mark Owen -// Created: Sun Feb 22 15:18:45 2015 - -#include "TopHLUpgrade/UpgradeLeptonObjectSelector.h" - -using namespace top; - -UpgradeLeptonObjectSelector::UpgradeLeptonObjectSelector( Options opt /* = Options() */ ) - : m_opt( opt ){ /* Deliberately Empty */ } - -/* virtual */ bool -UpgradeLeptonObjectSelector::apply( const xAOD::TruthParticle & truthParticle ) { - - // -------------------------------------------------- - // Always require 'reco' to pass - if( truthParticle.auxdata<int>("passReco") !=1 ) { return false; } - - // -------------------------------------------------- - // Apply kinematic cut on the (smeared) pT: - // must exceed 25 GeV - if ( truthParticle.pt() < m_opt.pt_min ){ return false; } - - // -------------------------------------------------- - // Apply kinematic cut on the eta: - // must be less than or equal to 2.5 - if ( std::abs( truthParticle.eta() ) > m_opt.eta_max ){ return false; } - - - // -------------------------------------------------- - // Everything that reaches this point has passed the selection - return true; - -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradeObjectLoader.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradeObjectLoader.cxx deleted file mode 100644 index 1e5caa1de8d4..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradeObjectLoader.cxx +++ /dev/null @@ -1,295 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TopHLUpgrade/UpgradeObjectLoader.h" - -#include "TopConfiguration/TopConfig.h" -#include "TopEvent/EventTools.h" -#include "TopHLUpgrade/UpgradeLeptonObjectSelector.h" - -#include "xAODTruth/TruthParticleContainer.h" -#include "xAODTruth/TruthParticleAuxContainer.h" -#include "xAODMissingET/MissingETContainer.h" -#include "xAODJet/JetContainer.h" -#include "xAODJet/JetAuxContainer.h" -#include "xAODCore/ShallowCopy.h" - -#include <algorithm> - -using namespace top; - -bool ptSort(const xAOD::IParticle* p1, const xAOD::IParticle* p2) { - return p1->pt() > p2->pt(); -} - -UpgradeObjectLoader::UpgradeObjectLoader( const std::shared_ptr<top::TopConfig> & cfg ) : - asg::AsgTool( "UpgradeObjectLoader" ), - m_config(cfg), - m_upgrade(), - // tool is active depending on config settings - m_active(m_config->isMC() && m_config->HLLHC()), - // object selection tools setup below - m_objectSelector_Electron( nullptr ), - m_objectSelector_Muon( nullptr ) - { - - if ( m_active ){ - std::cout << "Upgrade level reconstruction is enabled; telling you how I am configured:" << '\n'; - m_upgrade.reset(new UpgradePerformanceFunctionsxAOD(UpgradePerformanceFunctions::gold, 200.0)); //layout & mu hard coded for now - m_upgrade->setElectronWorkingPoint(UpgradePerformanceFunctions::looseElectron); - m_upgrade->setElectronRandomSeed(171); - m_upgrade->setMuonWorkingPoint(UpgradePerformanceFunctions::tightMuon); - m_upgrade->setMETRandomSeed(986); - m_upgrade->loadMETHistograms("UpgradePerformanceFunctions/sumetPU_mu200_ttbar_gold.root"); - m_upgrade->setPileupRandomSeed(121); - m_upgrade->setPileupRandomSeed(771); - m_upgrade->setPileupJetPtThresholdMeV(30000.); - m_upgrade->setPileupEfficiencyScheme(UpgradePerformanceFunctions::PileupEff::HS); - m_upgrade->setPileupEff(0.9); - m_upgrade->setPileupTemplatesPath("/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/UpgradePerformanceFunctions/"); - m_upgrade->setFlavourTaggingCalibrationFilename("UpgradePerformanceFunctions/flavor_tags_v1.1.root"); - - // configure muon selector - auto optMu = UpgradeLeptonObjectSelector::Options{ - m_config->truth_muon_PtCut(), - m_config->truth_muon_EtaCut() - }; - - m_objectSelector_Muon.reset( new UpgradeLeptonObjectSelector( optMu ) ); - - // configure electron selector - auto optEl = UpgradeLeptonObjectSelector::Options{ - m_config->truth_electron_PtCut(), - m_config->truth_electron_EtaCut() - }; - - m_objectSelector_Electron.reset( new UpgradeLeptonObjectSelector( optEl ) ); - } - -}//UpgradeObjectLoader constructor - -UpgradeObjectLoader::~UpgradeObjectLoader( ) { - -} - -/*! - * The main function to do the heavy lifting - get the truth objects, smear them - * and apply efficiency corrections. - * @return ParticleLevelEvent object - */ -ParticleLevelEvent UpgradeObjectLoader::load() { - - // Create the ParticleLevelEvent object - ParticleLevelEvent particleEvent; - - // Load event info object directly into the particleEvent - top::check( evtStore()->retrieve( particleEvent.m_info, m_config->sgKeyEventInfo() ), - "xAOD::TEvent::retrieve failed for EventInfo" ); - - /* ------------------------------ Muons -----------------------------------------------------------*/ - // Get muons - const xAOD::TruthParticleContainer * origmuons(0); - top::check( evtStore()->retrieve( origmuons, m_config->sgKeyTruthMuons() ), - "xAOD::TEvent::retrieve failed for Truth Muons" ); - - // Shallow copy - std::pair< xAOD::TruthParticleContainer*, xAOD::ShallowAuxContainer* > muons_shallowCopy = xAOD::shallowCopyContainer( *origmuons ); - xAOD::TruthParticleContainer* muons = muons_shallowCopy.first; - - // container to put the selected muons in - use view container to avoid deep copies - m_selectedMuons.reset( new xAOD::TruthParticleContainer(SG::VIEW_ELEMENTS)); - - // Smear & efficiency correct muons - for(auto muon : *muons) { - // efficiency (assume pass unsmeared pT here) - const double eff = m_upgrade->getMuonEfficiency( muon->pt(), muon->eta()); - //std::cout << "Muon with pT " << muon->pt() << " has efficiency = " << eff << std::endl; - - // smear - m_upgrade->smearMuon( *muon ); - //std::cout << "\t smeared pT " << muon->pt() << std::endl; - - // store efficiency correction - if(m_upgrade->getRandom3()->Uniform() < eff) { - muon->auxdata<int>("passReco") = 1; - } - else muon->auxdata<int>("passReco") = 0; - - // apply all cuts - if( m_objectSelector_Muon->apply( *muon ) ) m_selectedMuons->push_back( muon ); - - } - - // sort the muons by pT - std::sort(m_selectedMuons->begin(), m_selectedMuons->end(), ptSort); - - // keep hold of the pointers in our private variables (also clears last event) - m_muons.reset(muons); - m_muonsShallowAux.reset(muons_shallowCopy.second); - - // pass the muons to the ParticleLevelEvent object - particleEvent.m_muons = m_selectedMuons.get(); - - /* ------------------------------ Electrons -----------------------------------------------------------*/ - // Get electrons - const xAOD::TruthParticleContainer * origelectrons(0); - top::check( evtStore()->retrieve( origelectrons, m_config->sgKeyTruthElectrons() ), - "xAOD::TEvent::retrieve failed for Truth Electrons" ); - - // Shallow copy - std::pair< xAOD::TruthParticleContainer*, xAOD::ShallowAuxContainer* > electrons_shallowCopy = xAOD::shallowCopyContainer( *origelectrons ); - xAOD::TruthParticleContainer* electrons = electrons_shallowCopy.first; - - // container to put the selected electrons in - use view container to avoid deep copies - m_selectedElectrons.reset( new xAOD::TruthParticleContainer(SG::VIEW_ELEMENTS)); - - // Smear & efficiency correct electrons - for(auto electron : *electrons) { - // efficiency (assume pass unsmeared pT here) - const double eff = m_upgrade->getElectronEfficiency( electron->pt(), electron->eta()); - //std::cout << "Electron with pT " << electron->pt() << " has efficiency = " << eff << std::endl; - - // smear - m_upgrade->smearElectron( *electron ); - //std::cout << "\t smeared pT " << electron->pt() << std::endl; - - // store efficiency result - if(m_upgrade->getRandom3()->Uniform() < eff) { - electron->auxdata<int>("passReco") = 1; - } - else electron->auxdata<int>("passReco") = 0; - - // apply all cuts - if( m_objectSelector_Electron->apply( *electron ) ) m_selectedElectrons->push_back( electron ); - } - - // sort the electrons by pT - std::sort(m_selectedElectrons->begin(), m_selectedElectrons->end(), ptSort); - - // keep hold of the pointers in our private variables (also clears last event) - m_electrons.reset(electrons); - m_electronsShallowAux.reset(electrons_shallowCopy.second); - - // pass the electrons to the ParticleLevelEvent object - particleEvent.m_electrons = m_selectedElectrons.get(); - - - /* ------------------------------ Jets-----------------------------------------------------------*/ - // Get jets - const xAOD::JetContainer * origjets(0); - top::check( evtStore()->retrieve( origjets, m_config->sgKeyTruthJets() ), - "xAOD::TEvent::retrieve failed for Truth Jets" ); - - // Shallow copy - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > jets_shallowCopy = xAOD::shallowCopyContainer( *origjets ); - xAOD::JetContainer* jets = jets_shallowCopy.first; - - // we are going to put selected 'good' jets in to a xAOD::JetContainer - xAOD::JetContainer* selectedJets = new xAOD::JetContainer(); - xAOD::JetAuxContainer* auxJetCont = new xAOD::JetAuxContainer(); - selectedJets->setStore(auxJetCont); // connect container & store - - // Smear & efficiency correct jets - for(auto jet : *jets) { - // smear - m_upgrade->smearJet( *jet ); - - // jets must be above minimum threshold - if ( jet->pt() < m_upgrade->getPileupJetPtThresholdMeV()) continue; - - jet->auxdata<int>("pileUp") = 0; // so we know this jet is not pileup later on - - const float trackEff = m_upgrade->getTrackJetConfirmEff(jet->pt(),jet->eta(), "HS"); - - if(m_upgrade->getRandom3()->Uniform() < trackEff) { - // mark that jet passed track confirmation - jet->auxdata<int>("passTrackConf") = 1; - - // store b-tagging efficiency - - // first work out jet flavour - char type = 'L'; - if(jet->auxdata<int>("GhostBQuarksFinalCount") > 0) type = 'B'; - else if(jet->auxdata<int>("GhostCQuarksFinalCount") > 0) type = 'C'; - - // now get b-tagging efficiency - const double MV1tagEff = m_upgrade->getFlavourTagEfficiency(jet->pt(), jet->eta(), type, "mv1", 70, m_upgrade->getPileupTrackConfSetting()); - jet->auxdata<float>("mv1TagEff") = MV1tagEff; - - // put jet in to selectedJets container, have to deep copy the jet - xAOD::Jet* newjet = new xAOD::Jet(*jet); - selectedJets->push_back( newjet ); - - } - else jet->auxdata<int>("passTrackConf") = 0; - - - //std::cout << "\t smeared pT " << jet->pt() << std::endl; - } - - // now get the pileup jets - std::vector<TLorentzVector> puJets = m_upgrade->getPileupJets(); - // loop over pileup jets - for(auto puJet : puJets) { - - const float trackEff = m_upgrade->getTrackJetConfirmEff(puJet.Pt(),puJet.Eta(),"PU"); - - if(m_upgrade->getRandom3()->Uniform() > trackEff) continue; // ignore jets failing track confirmation - - // jet 4 momentum stored as PtEtaPhiM (see xAODJet/JetTypes.h) - xAOD::JetFourMom_t mom( puJet.Pt(), puJet.Eta(), puJet.Phi(), puJet.M() ); - xAOD::Jet* jet = new xAOD::Jet(); - selectedJets->push_back( jet ); - selectedJets->back()->setJetP4( mom ); - selectedJets->back()->auxdata<int>("pileUp") = 1; // so we know this jet is pileup later on - // now get b-tagging efficiency - const double MV1tagEff = m_upgrade->getFlavourTagEfficiency(jet->pt(), jet->eta(), 'P', "mv1", 70, m_upgrade->getPileupTrackConfSetting()); - selectedJets->back()->auxdata<float>("mv1TagEff") = MV1tagEff; - - }// pileup jet loop - - // sort jets by pT - std::sort(selectedJets->begin(), selectedJets->end(), ptSort); - - // keep hold of the pointers in our private variables (also clears last event) - m_jets.reset(selectedJets); - m_jetsAux.reset(auxJetCont); - - // pass the jets to the ParticleLevelEvent object - particleEvent.m_jets = selectedJets; - - // clean up memory from the shallow copy of jets that is finished with now - delete jets; - delete jets_shallowCopy.second; - - - /* ----------------------------- MET ------------------------------------------*/ - const xAOD::MissingETContainer * origmetcont(0); - top::check( evtStore()->retrieve( origmetcont, m_config->sgKeyTruthMET() ), - "xAOD::TEvent::retrieve failed for Truth MET" ); - - ATH_MSG_DEBUG("N(MET) = " << origmetcont->size()); - - // Maybe we shouldn't hard code this, but probably it will not change.... - const xAOD::MissingET* origmet = (*origmetcont)["NonInt"]; - - // the MET type is just std::pair<double,double>, representing the smeared METx and METy - UpgradePerformanceFunctions::MET smearedMET = m_upgrade->getMETSmeared(origmet->sumet(), origmet->mpx(), origmet->mpy()); - - // Shallow copy - std::pair< xAOD::MissingETContainer*, xAOD::ShallowAuxContainer* > metcont_shallowCopy = xAOD::shallowCopyContainer( *origmetcont ); - xAOD::MissingETContainer* metcont = metcont_shallowCopy.first; - xAOD::MissingET* met = (*metcont)["NonInt"]; - met->setMpx(smearedMET.first); - met->setMpx(smearedMET.second); - - // keep hold of the pointers in our private variables (also clears last event) - m_metCont.reset(metcont); - m_metShallowAux.reset(metcont_shallowCopy.second); - - // pass the MET pointer to the ParticleLevelEvent object - particleEvent.m_met = met; - - return particleEvent; -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradePerformanceFunctionsxAOD.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradePerformanceFunctionsxAOD.cxx deleted file mode 100644 index 63fe0423de0d..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/Root/UpgradePerformanceFunctionsxAOD.cxx +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TopHLUpgrade/UpgradePerformanceFunctionsxAOD.h" - -UpgradePerformanceFunctionsxAOD::UpgradePerformanceFunctionsxAOD() : - UpgradePerformanceFunctions(), - m_randgen(811) //fix random seed -{ - -} - -UpgradePerformanceFunctionsxAOD::UpgradePerformanceFunctionsxAOD(UpgradeLayout layout, double avgMu) : - UpgradePerformanceFunctions(layout, avgMu), - m_randgen(811) // fix random seed -{ - -} - -/** - * Get smeared electron energy from the UpgradePerformanceFunctions and then - * modify the input electron energy accordingly. - */ -void UpgradePerformanceFunctionsxAOD::smearElectron(xAOD::TruthParticle& electron) { - const double newE = getElectronSmearedEnergy( electron.e(), electron.eta() ); - const double newE2 = newE*newE; - const double m2 = electron.m() * electron.m(); - const double p2 = newE2 > m2 ? newE2 - m2 : 0.; - TLorentzVector newvec; - newvec.SetPtEtaPhiE( sqrt(p2) / cosh(electron.eta()), electron.eta(), electron.phi(), newE ); - - // no p4 setter in truth particle, have to set one-by-one - electron.setPx( newvec.Px() ); - electron.setPy( newvec.Py() ); - electron.setPz( newvec.Pz() ); - electron.setE( newvec.E() ); - electron.setM( newvec.M() ); -} - -/** - * Get smeared muon momentum from the UpgradePerformanceFunctions and then - * modify the input muon accordingly. Note, the PdgId will be changed - * if the muon smearing results in a charge flip (since the - * TruthParticle->charge() function uses the PdgId). - */ -void UpgradePerformanceFunctionsxAOD::smearMuon(xAOD::TruthParticle& muon) { - double qoverpt = muon.charge()/muon.pt(); - const double sigma_qoverpt = this->getMuonQOverPtResolution(muon.pt(), muon.eta()); - qoverpt += m_randgen.Gaus(0,sigma_qoverpt); - const double pt_smeared = fabs(1.0/qoverpt); - const double q_smeared = (qoverpt > 0) ? 1.0 : -1.0; - TLorentzVector newvec; - newvec.SetPtEtaPhiM( pt_smeared, muon.eta(), muon.phi(), muon.m() ); - - // no p4 setter in truth particle, have to set one-by-one - muon.setPx( newvec.Px() ); - muon.setPy( newvec.Py() ); - muon.setPz( newvec.Pz() ); - muon.setE( newvec.E() ); - muon.setM( newvec.M() ); - // set pdg id (which is used to get charge) - muon.setPdgId( -1.0 * q_smeared * muon.absPdgId()); -} - -/** - * Get smeared jet pT from the UpgradePerformanceFunctions and then - * modify the input jet accordingly. - */ -void UpgradePerformanceFunctionsxAOD::smearJet(xAOD::Jet& jet) { - // can only smear jets with 10 < pT < 1500 GeV (would be good not to hard code this....) - if(jet.pt() < 10.0*1000.0 or jet.pt() > 1500.0*1000.0) return; - - // function might be called 'SmearedEnergy', but apparently it gives smeared pT (https://twiki.cern.ch/twiki/bin/view/AtlasProtected/UpgradePerformanceFunctions) - const double smearedjetpt = this->getJetSmearedEnergy(jet.pt(), jet.eta(), true); - const double smearedjetE = jet.e() * smearedjetpt/jet.pt(); - // lazy way to calculate the mass after pT smearing - TLorentzVector newjet; - newjet.SetPtEtaPhiE( smearedjetpt, jet.eta(), jet.phi(), smearedjetE ); - // jet 4 momentum stored as PtEtaPhiM (see xAODJet/JetTypes.h) - xAOD::JetFourMom_t mom( smearedjetpt, jet.eta(), jet.phi(), newjet.M() ); - jet.setJetP4( mom ); -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradeLeptonObjectSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradeLeptonObjectSelector.h deleted file mode 100644 index 547c51402c2e..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradeLeptonObjectSelector.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Filename: UpgradeLeptonObjectSelector.h -// Description: -// Author: Mark Owen -// Created: 19 Jan 2017 - -#ifndef _TOP_UPGRADE_LEPTONOBJECTSELECTOR_H_ -#define _TOP_UPGRADE_LEPTONOBJECTSELECTOR_H_ - -#include "TopParticleLevel/ObjectSelectorBase.h" - -#include "xAODTruth/TruthParticleContainer.h" - -namespace top { - - class UpgradeLeptonObjectSelector - : public ObjectSelectorBase<xAOD::TruthParticle> { - public: - // Struct used to store the cut values used by the object selector. It - // is important that the object has a sensible default config because it - // will be default constructed for the trivial constructor of the object - // selector. - struct Options { - Options( double ptMin = 25.e3, - double etaMax = 2.5 ) : - pt_min( ptMin ), - eta_max( etaMax ) {} - double pt_min; - double eta_max; - - }; - public: - UpgradeLeptonObjectSelector( Options opt = Options() ); - virtual bool apply( const xAOD::TruthParticle & truthParticle ); - private: - Options m_opt; - }; - -} - -#endif /* _TOP_UPGRADE_LEPTONOBJECTSELECTOR_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradeObjectLoader.h b/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradeObjectLoader.h deleted file mode 100644 index 49fa5a1efccf..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradeObjectLoader.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef _TOP_UPGRADEOBJECTLOADER_H_ -#define _TOP_UPGRADEOBJECTLOADER_H_ - -#include "AsgTools/AsgTool.h" - -#include "TopHLUpgrade/UpgradePerformanceFunctionsxAOD.h" -#include "TopParticleLevel/ParticleLevelEvent.h" -#include "TopParticleLevel/ObjectSelectorBase.h" - -#include "xAODTruth/TruthParticleContainer.h" -#include "xAODJet/JetContainer.h" -#include "xAODJet/JetAuxContainer.h" -#include "xAODEventInfo/EventInfo.h" -#include "xAODMissingET/MissingETContainer.h" -#include "xAODMuon/MuonContainer.h" -#include "xAODEgamma/Electron.h" -#include "xAODCore/ShallowCopy.h" - -// Forward Declarations -namespace top { - class TopConfig; -} - -namespace top { - - class UpgradeObjectLoader : public asg::AsgTool { - - public: - - /*! - * @brief Constructor of loader tool. - */ - UpgradeObjectLoader( const std::shared_ptr<top::TopConfig> & cfg ); - - /*! - * @brief Destructor of loader tool. - */ - ~UpgradeObjectLoader( ); - - /*! - * @brief Loading function. Does the actual work. This function will - * load the truth information from the #xaodEvent and return this data - * transformed into a smeared level event. The data stored in the - * SmearedLevel is owned by the truth event loader. - * @param xaodEvent The input data event object. - * @return ParticleLevelEvent object. - */ - ParticleLevelEvent load(); - - /*! - * @brief Function that can be used to test whether the UpgradeObjectLoader - * is active. The loader is set to inactive if the names of the truth - * collections are unavailable. This is determined at construction. - */ - bool active() const { return m_active; } - - private: - - // The global config object - const std::shared_ptr<top::TopConfig> & m_config; - - // pointer to smearing function object - std::unique_ptr<UpgradePerformanceFunctionsxAOD> m_upgrade; - - // Flag denoting whether the loader tool is active. Will be set by the - // constructor and remains unchanged afterwards. - const bool m_active; - - // muons - std::unique_ptr<xAOD::TruthParticleContainer> m_muons; - std::unique_ptr<xAOD::ShallowAuxContainer> m_muonsShallowAux; - std::unique_ptr<xAOD::TruthParticleContainer> m_selectedMuons; - - // electrons - std::unique_ptr<xAOD::TruthParticleContainer> m_electrons; - std::unique_ptr<xAOD::ShallowAuxContainer> m_electronsShallowAux; - std::unique_ptr<xAOD::TruthParticleContainer> m_selectedElectrons; - - // jets - std::unique_ptr<xAOD::JetContainer> m_jets; - std::unique_ptr<xAOD::JetAuxContainer> m_jetsAux; - - // MET - std::unique_ptr<xAOD::MissingETContainer> m_metCont; - std::unique_ptr<xAOD::ShallowAuxContainer> m_metShallowAux; - - // Electron selector tool - std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Electron; - - // Muon selector tool - std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Muon; - - };//class UpgradeObjectLoader - -}//namespace top - -#endif //_TOP_UPGRADEOBJECTLOADER_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradePerformanceFunctionsxAOD.h b/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradePerformanceFunctionsxAOD.h deleted file mode 100644 index 158af7891d6a..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopHLUpgrade/TopHLUpgrade/UpgradePerformanceFunctionsxAOD.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef UPGRADEPERFORMANCEFUNCTIONSXAOD_H -#define UPGRADEPERFORMANCEFUNCTIONSXAOD_H - -#include "UpgradePerformanceFunctions/UpgradePerformanceFunctions.h" - -#include "TRandom3.h" - -#include "xAODTruth/TruthParticle.h" -#include "xAODJet/Jet.h" - -/*! - * @brief Class to use the upgrade performance functions to smear xAOD objects. - * - * The class inherits from UpgradePerformanceFunctions and provides a few functions - * to smear electrons, muons and jets. - * - * @author Mark Owen <markowen@cern.ch> - */ -class UpgradePerformanceFunctionsxAOD : public UpgradePerformanceFunctions { - - public: - - /// Default constructor - UpgradePerformanceFunctionsxAOD(); - - /// Constructor specifing layout & mu - UpgradePerformanceFunctionsxAOD(UpgradeLayout layout, double avgMu); - - /// Destructor - ~UpgradePerformanceFunctionsxAOD() {}; - - /// Smear an Electron - void smearElectron(xAOD::TruthParticle& electron); - - /// Smear a Muon - void smearMuon(xAOD::TruthParticle& muon); - - /// Smear a Jet - void smearJet(xAOD::Jet& jet); - - /// Access to random number generator - inline TRandom3* getRandom3() {return &m_randgen;} - - private: - - TRandom3 m_randgen; - -};//class UpgradePerformanceFunctionsxAOD - -#endif //UPGRADEPERFORMANCEFUNCTIONSXAOD_H diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt index 2dd966346238..721474570f2b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt @@ -49,6 +49,3 @@ atlas_add_library( TopJetSubstructure Root/*.cxx Root/*.h Root/*.icc ${FASTJET_INCLUDE_DIRS} ${FASTJETCONTRIB_INCLUDE_DIRS}) -# Install data files from the package: -atlas_install_data( share/* ) - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/ElectronInJetSubtractionAlgorithm.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/ElectronInJetSubtractionAlgorithm.cxx index ef63f2d9adce..e9ffb27ae11a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/ElectronInJetSubtractionAlgorithm.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/ElectronInJetSubtractionAlgorithm.cxx @@ -1,26 +1,23 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: ElectronInJetSubtractionAlgorithm.cxx 654856 2015-03-17 19:00:30Z dferreir $ #include "TopJetSubstructure/ElectronInJetSubtractionAlgorithm.h" #include <iostream> -namespace top{ - +namespace top { ElectronInJetSubtractionAlgorithm::ElectronInJetSubtractionAlgorithm() : m_doLooseCuts(false), m_passPreORSelection("passPreORSelection"), - m_passPreORSelectionLoose("passPreORSelectionLoose") - { - + m_passPreORSelectionLoose("passPreORSelectionLoose") { } - - void ElectronInJetSubtractionAlgorithm::apply( xAOD::ElectronContainer* electrons , xAOD::JetContainer* jets , const bool useLooseElectrons ) - { + + void ElectronInJetSubtractionAlgorithm::apply(xAOD::ElectronContainer* electrons, xAOD::JetContainer* jets, + const bool useLooseElectrons) { std::string leptonDef; - if (!useLooseElectrons){ + if (!useLooseElectrons) { leptonDef = m_passPreORSelection; } if (useLooseElectrons) { @@ -33,7 +30,7 @@ namespace top{ ++passedElectronsBefore; } } - + m_o.Load(jets, electrons, leptonDef); m_o.AnalyzeEvent(leptonDef); @@ -43,11 +40,11 @@ namespace top{ ++passedElectrons; } } - + bool debug(false); if (debug) { - std::cout<<"Total number of electrons = "<<electrons->size()<<" that pass cuts = "<<passedElectrons<<"/" << passedElectronsBefore << " :: Total number of jets = "<<jets->size()<<std::endl; + std::cout << "Total number of electrons = " << electrons->size() << " that pass cuts = " << passedElectrons << + "/" << passedElectronsBefore << " :: Total number of jets = " << jets->size() << std::endl; } } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/LargeJetTrimmer.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/LargeJetTrimmer.cxx index 9ef40ba675d3..b36599dcaec6 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/LargeJetTrimmer.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/LargeJetTrimmer.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopJetSubstructure/LargeJetTrimmer.h" @@ -27,12 +27,13 @@ top::LargeJetTrimmer::~LargeJetTrimmer() { void top::LargeJetTrimmer::correctJet(xAOD::Jet& jet) { JetConstituentVector vec = jet.getConstituents(); + std::vector<fastjet::PseudoJet> p_c; xAOD::JetConstituentVector::iterator it = vec.begin(); xAOD::JetConstituentVector::iterator itE = vec.end(); - for( ; it != itE; it++){ - PseudoJet p(0,0,0,0); + for (; it != itE; it++) { + PseudoJet p(0, 0, 0, 0); float pt = (*it)->pt(); float y = (*it)->rapidity(); float phi = (*it)->phi(); @@ -40,7 +41,7 @@ void top::LargeJetTrimmer::correctJet(xAOD::Jet& jet) { p.reset_PtYPhiM(pt, y, phi, m); p_c.push_back(p); } - + JetDefinition jet_def_large = JetDefinition(antikt_algorithm, 1.0, fastjet::E_scheme, fastjet::Best); ClusterSequence cs_large(p_c, jet_def_large); std::vector<PseudoJet> ljets = sorted_by_pt(cs_large.inclusive_jets(50e3)); @@ -55,4 +56,3 @@ void top::LargeJetTrimmer::correctJet(xAOD::Jet& jet) { void top::LargeJetTrimmer::print(std::ostream& o) const { o << "LargeJetTrimmer" << std::endl; } - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/SubjetMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/SubjetMaker.cxx index 67745de04259..78e742973387 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/SubjetMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/SubjetMaker.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopJetSubstructure/SubjetMaker.h" @@ -29,20 +29,18 @@ void top::SubjetMaker::correctJet(xAOD::Jet& jet) { xAOD::JetConstituentVector vec = jet.getConstituents(); std::vector<fastjet::PseudoJet> p_c; - for(auto it : vec){ - PseudoJet p(0,0,0,0); + for (auto it : vec) { + PseudoJet p(0, 0, 0, 0); float pt = (*it)->pt(); float y = (*it)->rapidity(); float phi = (*it)->phi(); float m = (*it)->m(); if (y != y) { continue; + } else { + p.reset_PtYPhiM(pt, y, phi, m); + p_c.push_back(p); } - else { - p.reset_PtYPhiM(pt, y, phi, m); - p_c.push_back(p); - } - } JetDefinition jet_def_small = JetDefinition(cambridge_algorithm, 0.2, fastjet::E_scheme, fastjet::Best); @@ -51,18 +49,17 @@ void top::SubjetMaker::correctJet(xAOD::Jet& jet) { if (ljets.size() == 0) { return; } - std::vector<float> sje,sjpx,sjpy,sjpz; + std::vector<float> sje, sjpx, sjpy, sjpz; for (size_t z = 0; z < ljets.size(); ++z) { sje.push_back(ljets[z].e()); sjpx.push_back(ljets[z].px()); sjpy.push_back(ljets[z].py()); sjpz.push_back(ljets[z].pz()); } - jet.auxdata<std::vector<float> >("Subjet_E") = sje; - jet.auxdata<std::vector<float> >("Subjet_Px") = sjpx; - jet.auxdata<std::vector<float> >("Subjet_Py") = sjpy; - jet.auxdata<std::vector<float> >("Subjet_Pz") = sjpz; - + jet.auxdata<std::vector<float> >("Subjet_E") = sje; + jet.auxdata<std::vector<float> >("Subjet_Px") = sjpx; + jet.auxdata<std::vector<float> >("Subjet_Py") = sjpy; + jet.auxdata<std::vector<float> >("Subjet_Pz") = sjpz; } void top::SubjetMaker::print(std::ostream& o) const { diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/TTBarElectronJetOverlap.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/TTBarElectronJetOverlap.cxx index 99421df6c3fc..606633128db0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/TTBarElectronJetOverlap.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/TTBarElectronJetOverlap.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopJetSubstructure/TTBarElectronJetOverlap.h" @@ -13,336 +13,349 @@ using namespace std; -void TTBarElectronJetOverlap::Load(xAOD::JetContainer *jets, xAOD::ElectronContainer *electrons, const std::string &leptonDef) { - m_jets = jets; - m_electrons = electrons; - fDebug = false; - - size_t se = m_electrons->size(); - fElClTLVs.resize(se); - fElTLVs.resize(se); - fElGood.resize(se); - - size_t sj = m_jets->size(); - fJetTLVs.resize(sj); - fOrigJetTLVs.resize(sj); - fJetJVFs.resize(sj); - fJetD3PDTrkPtSums.resize(sj); - fJetD3PDTrkPtPVSums.resize(sj); - - for (size_t i = 0; i < sj; i++) { - fJetTLVs[i].SetPtEtaPhiE(m_jets->at(i)->pt(), m_jets->at(i)->eta(), m_jets->at(i)->phi(), m_jets->at(i)->e()); - fOrigJetTLVs[i].SetPtEtaPhiE(m_jets->at(i)->pt(), m_jets->at(i)->eta(), m_jets->at(i)->phi(), m_jets->at(i)->e()); - - //std::vector<float> JVF = m_jets->at(i)->getAttribute<std::vector<float> >("JVF"); - //fJetJVFs[i] = JVF.size() > 0 ? JVF[0] : -1; // (TODO) NOTA BENE: Assumes PV is the first vertex - //std::vector<float> trkPtSumVec = m_jets->at(i)->getAttribute<std::vector<float> >("SumPtTrkPt500"); - //float trkPtSum = trkPtSumVec.size() > 0 ? trkPtSumVec[0] : 0; // (TODO) NOTA BENE: Assumes PV is the first vertex - //fJetD3PDTrkPtSums[i] = fJetJVFs[i] ? trkPtSum/JVF[0] : -1; - //fJetD3PDTrkPtPVSums[i] = trkPtSum; - if (fDebug) { - cout << " - (pre-OR) Jet # " << i << - " Pt Eta Phi: " << - fJetTLVs[i].Pt() << " " << - fJetTLVs[i].Eta() << " " << - fJetTLVs[i].Phi() << endl; - } +void TTBarElectronJetOverlap::Load(xAOD::JetContainer* jets, xAOD::ElectronContainer* electrons, + const std::string& leptonDef) { + m_jets = jets; + m_electrons = electrons; + fDebug = false; + + size_t se = m_electrons->size(); + fElClTLVs.resize(se); + fElTLVs.resize(se); + fElGood.resize(se); + + size_t sj = m_jets->size(); + fJetTLVs.resize(sj); + fOrigJetTLVs.resize(sj); + fJetJVFs.resize(sj); + fJetD3PDTrkPtSums.resize(sj); + fJetD3PDTrkPtPVSums.resize(sj); + + for (size_t i = 0; i < sj; i++) { + fJetTLVs[i].SetPtEtaPhiE(m_jets->at(i)->pt(), m_jets->at(i)->eta(), m_jets->at(i)->phi(), m_jets->at(i)->e()); + fOrigJetTLVs[i].SetPtEtaPhiE(m_jets->at(i)->pt(), m_jets->at(i)->eta(), m_jets->at(i)->phi(), m_jets->at(i)->e()); + + //std::vector<float> JVF = m_jets->at(i)->getAttribute<std::vector<float> >("JVF"); + //fJetJVFs[i] = JVF.size() > 0 ? JVF[0] : -1; // (TODO) NOTA BENE: Assumes PV is the first vertex + //std::vector<float> trkPtSumVec = m_jets->at(i)->getAttribute<std::vector<float> >("SumPtTrkPt500"); + //float trkPtSum = trkPtSumVec.size() > 0 ? trkPtSumVec[0] : 0; // (TODO) NOTA BENE: Assumes PV is the first vertex + //fJetD3PDTrkPtSums[i] = fJetJVFs[i] ? trkPtSum/JVF[0] : -1; + //fJetD3PDTrkPtPVSums[i] = trkPtSum; + if (fDebug) { + cout << " - (pre-OR) Jet # " << i << + " Pt Eta Phi: " << + fJetTLVs[i].Pt() << " " << + fJetTLVs[i].Eta() << " " << + fJetTLVs[i].Phi() << endl; + } + } + + for (size_t i = 0; i < se; i++) { + fElGood[i] = m_electrons->at(i)->auxdataConst<char>(leptonDef.c_str()); + + if (m_electrons->at(i)->caloCluster()) { + fElClTLVs[i].SetPtEtaPhiM(m_electrons->at(i)->caloCluster()->e() / + std::cosh(m_electrons->at(i)->caloCluster()->eta()), + m_electrons->at(i)->caloCluster()->eta(), m_electrons->at( + i)->caloCluster()->phi(), 0.511); + } else { + fElClTLVs[i] = m_electrons->at(i)->p4(); } - for (size_t i = 0; i < se; i++) { - fElGood[i] = m_electrons->at(i)->auxdataConst<char>(leptonDef.c_str()); - - if (m_electrons->at(i)->caloCluster()) { - fElClTLVs[i].SetPtEtaPhiM(m_electrons->at(i)->caloCluster()->e()/std::cosh(m_electrons->at(i)->caloCluster()->eta()), - m_electrons->at(i)->caloCluster()->eta(), m_electrons->at(i)->caloCluster()->phi(), 0.511); - } else { - fElClTLVs[i] = m_electrons->at(i)->p4(); - } - - if (m_electrons->at(i)->trackParticle() && m_electrons->at(i)->caloCluster()) { - fElTLVs[i].SetPtEtaPhiM(m_electrons->at(i)->caloCluster()->e()/std::cosh(m_electrons->at(i)->trackParticle()->eta()), - m_electrons->at(i)->trackParticle()->eta(), m_electrons->at(i)->trackParticle()->phi(), 0.511); - } else { - fElTLVs[i] = m_electrons->at(i)->p4(); - } - if (fDebug) { - cout << " - (pre-OR) El # " << i << - " Pt Eta Phi: " << - fElTLVs[i].Pt() << " " << - fElTLVs[i].Eta() << " " << - fElTLVs[i].Phi() << endl; - } + if (m_electrons->at(i)->trackParticle() && m_electrons->at(i)->caloCluster()) { + fElTLVs[i].SetPtEtaPhiM(m_electrons->at(i)->caloCluster()->e() / + std::cosh(m_electrons->at(i)->trackParticle()->eta()), + m_electrons->at(i)->trackParticle()->eta(), m_electrons->at( + i)->trackParticle()->phi(), 0.511); + } else { + fElTLVs[i] = m_electrons->at(i)->p4(); + } + if (fDebug) { + cout << " - (pre-OR) El # " << i << + " Pt Eta Phi: " << + fElTLVs[i].Pt() << " " << + fElTLVs[i].Eta() << " " << + fElTLVs[i].Phi() << endl; } + } } void TTBarElectronJetOverlap::FindAssocEls() { - size_t nJets = m_jets->size(); - fJetAssocElCls = vector<set<int> >(nJets); - size_t nEls = m_electrons->size(); - fElClAssocJet = vector<int>(nEls, -1); - - // find the associated electron clusters in each jet - double drmin, dr; - TLorentzVector elcl, jet; - for (size_t z = 0 ; z < nEls; ++z) { - if (!fElGood[z]) continue; - elcl = fElClTLVs[z]; - drmin = 0.4; - int drmin_idx = -1; - for (size_t y = 0 ; y < nJets; ++y) { - jet = fJetTLVs[y]; - dr = elcl.DeltaR(jet); - // attempt to match the jet to the electron. - if (dr < drmin) { - drmin = dr; - drmin_idx = y; - } - } - if (drmin_idx == -1) - continue; - fJetAssocElCls[drmin_idx].insert(z); - fElClAssocJet[z] = drmin_idx; + size_t nJets = m_jets->size(); + + fJetAssocElCls = vector<set<int> >(nJets); + size_t nEls = m_electrons->size(); + fElClAssocJet = vector<int>(nEls, -1); + + // find the associated electron clusters in each jet + double drmin, dr; + TLorentzVector elcl, jet; + for (size_t z = 0; z < nEls; ++z) { + if (!fElGood[z]) continue; + elcl = fElClTLVs[z]; + drmin = 0.4; + int drmin_idx = -1; + for (size_t y = 0; y < nJets; ++y) { + jet = fJetTLVs[y]; + dr = elcl.DeltaR(jet); + // attempt to match the jet to the electron. + if (dr < drmin) { + drmin = dr; + drmin_idx = y; + } } + if (drmin_idx == -1) continue; + fJetAssocElCls[drmin_idx].insert(z); + fElClAssocJet[z] = drmin_idx; + } } void TTBarElectronJetOverlap::SubtractEls() { - size_t nJets = m_jets->size(); - size_t nEls = m_electrons->size(); - int ElIdx; - - fSubJets.resize(nJets); - for (int k=0; k<nJets; ++k) { - fSubJets[k] = 0; - } - - for (size_t iJet = 0; iJet < nJets; iJet++) { - TLorentzVector originalJet = fOrigJetTLVs[iJet]; - for (set<int>::iterator iEl = fJetAssocElCls[iJet].begin(); iEl != fJetAssocElCls[iJet].end(); iEl++) { - ElIdx = *iEl; - TLorentzVector elcorr = fElTLVs[ElIdx]; - fJetTLVs[iJet] -= elcorr; - fSubJets[iJet] = 1; - } + size_t nJets = m_jets->size(); + int ElIdx; + + fSubJets.resize(nJets); + for (unsigned int k = 0; k < nJets; ++k) { + fSubJets[k] = 0; + } + + for (size_t iJet = 0; iJet < nJets; iJet++) { + TLorentzVector originalJet = fOrigJetTLVs[iJet]; + for (set<int>::iterator iEl = fJetAssocElCls[iJet].begin(); iEl != fJetAssocElCls[iJet].end(); iEl++) { + ElIdx = *iEl; + TLorentzVector elcorr = fElTLVs[ElIdx]; + fJetTLVs[iJet] -= elcorr; + fSubJets[iJet] = 1; } + } } void TTBarElectronJetOverlap::FindGoodObjects() { - size_t nEls = m_electrons->size(); - fGoodEls = vector<bool>(nEls, true); - - size_t nJets = fJetTLVs.size(); - vector<TLorentzVector> TmpJetTLVs = fJetTLVs; - vector<TLorentzVector> TmpOrigJetTLVs = fOrigJetTLVs; - TLorentzVector el, jet, jetOrig; - - for (size_t iEl = 0; iEl < nEls; iEl++) { - if (!fElGood[iEl]) continue; - - el = fElTLVs[iEl]; - - if (fDebug) { - cout << " - (good) El # " << iEl << - " Pt Eta Phi: " << - el.Pt() << " " << - el.Eta() << " " << - el.Phi() << endl; - } + size_t nEls = m_electrons->size(); - for (size_t iJet = 0; iJet < nJets; iJet++) { - jet = fJetTLVs[iJet]; - jetOrig = fOrigJetTLVs[iJet]; - if (fDebug) { - cout << " - (good) Jet # " << iJet << - " Pt Eta Phi M: " << - jet.Pt() << " " << - jet.Eta() << " " << - jet.Phi() << " " << - jet.M() << endl; - } - - //if (jet.Pt() < 25e3) - //continue; - - // New overlap removal procedure: - // subtracted ets failing the pT cut are assumed to be a result of electron energy deposits. Continue to the next jet. - - if ((jetOrig.Pt() >= 30e3 && jetOrig.Pt() < 50e3) && jet.Pt() < 20e3) { - continue; - } else if (( jetOrig.Pt() >= 50e3 && jetOrig.Pt() < 100e3) && jet.Pt() <30e3) { - continue; - } else if ((jetOrig.Pt() >= 100e3 && jetOrig.Pt() < 400e3) && jet.Pt() <90e3) { - continue; - } else if ((jetOrig.Pt() >= 400e3 && jetOrig.Pt() < 800e3) && jet.Pt() <130e3) { - continue; - } else if ((jetOrig.Pt() >= 800e3 && jetOrig.Pt() <1200e3) && jet.Pt() <230e3) { - continue; - } else if ((jetOrig.Pt() >=1200e3 && jetOrig.Pt() <1600e3) && jet.Pt() <700e3) { - continue; - } else if ((jetOrig.Pt() >=1600e3 && jetOrig.Pt() <2000e3) && jet.Pt() < 1250e3) { - continue; - } else if ((jetOrig.Pt() >=2000e3 && jetOrig.Pt()<2200e3) && jet.Pt() < 1300e3) { - continue; - } else if (jetOrig.Pt()>2200e3 && jet.Pt()<1350e3) { - continue; - } - - // if the electron is too close to a subtracted jet... - if (jet.DeltaR(el) < 0.2) { - - if (fDebug) - cout << " El too close to jet. Removing." << endl; - - // remove from good electrons list. - fGoodEls[iEl] = false; - - if (fElClAssocJet[iEl] >= 0) { - // add electron 4-vector back to jet. - TmpJetTLVs[fElClAssocJet[iEl]] += el; - //remove from subtracted jets list - fSubJets[iJet] = 0; - // remove this electron from the association. - fJetAssocElCls[iJet].erase(iEl); - } - } - } - } - - fJetTLVs = TmpJetTLVs; - fOrigJetTLVs = TmpOrigJetTLVs; - fGoodJets = vector<bool>(nJets,true); - - for (size_t iJet = 0; iJet < nJets; iJet++) { - jetOrig = fOrigJetTLVs[iJet]; - - if (jetOrig.Pt() >= 30e3 && jetOrig.Pt() < 50e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 20e3; - } else if (jetOrig.Pt() >= 50e3 && jetOrig.Pt() < 100e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 30e3; - } else if (jetOrig.Pt() >= 100e3 && jetOrig.Pt() < 400e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 90e3; - } else if (jetOrig.Pt() >= 400e3 && jetOrig.Pt() < 800e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 130e3; - } else if (jetOrig.Pt() >= 800e3 && jetOrig.Pt() < 1200e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 230e3; - } else if (jetOrig.Pt() >= 1200e3 && jetOrig.Pt() < 1600e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 700e3; - } else if (jetOrig.Pt() >= 1600e3 && jetOrig.Pt() < 2000e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 1250e3; - } else if (jetOrig.Pt() >= 2000e3 && jetOrig.Pt() < 2200e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 1300e3; - } else if (jetOrig.Pt() > 2200e3) { - fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 1350e3; - } - } -} - -void TTBarElectronJetOverlap::RecalcJVF() { + fGoodEls = vector<bool>(nEls, true); - size_t nJets = m_jets->size(); - int ElIdx; - //int TrkIdx; - TLorentzVector trk; + size_t nJets = fJetTLVs.size(); + vector<TLorentzVector> TmpJetTLVs = fJetTLVs; + vector<TLorentzVector> TmpOrigJetTLVs = fOrigJetTLVs; + TLorentzVector el, jet, jetOrig; - for (size_t iJet = 0; iJet < nJets; iJet++) { + for (size_t iEl = 0; iEl < nEls; iEl++) { + if (!fElGood[iEl]) continue; - // if jvf == 0 or -1, no need to recalulate... - if (!fJetJVFs[iJet] || - fJetJVFs[iJet] < 0) - continue; + el = fElTLVs[iEl]; - for (set<int>::iterator iEl = fJetAssocElCls[iJet].begin(); - iEl != fJetAssocElCls[iJet].end(); iEl++) { + if (fDebug) { + cout << " - (good) El # " << iEl << + " Pt Eta Phi: " << + el.Pt() << " " << + el.Eta() << " " << + el.Phi() << endl; + } - ElIdx = *iEl; + for (size_t iJet = 0; iJet < nJets; iJet++) { + jet = fJetTLVs[iJet]; + jetOrig = fOrigJetTLVs[iJet]; + if (fDebug) { + cout << " - (good) Jet # " << iJet << + " Pt Eta Phi M: " << + jet.Pt() << " " << + jet.Eta() << " " << + jet.Phi() << " " << + jet.M() << endl; + } - trk.SetPtEtaPhiE(m_electrons->at(ElIdx)->trackParticle()->pt(), - m_electrons->at(ElIdx)->trackParticle()->eta(), m_electrons->at(ElIdx)->trackParticle()->phi(), m_electrons->at(ElIdx)->trackParticle()->e()); + //if (jet.Pt() < 25e3) + //continue; + + // New overlap removal procedure: + // subtracted ets failing the pT cut are assumed to be a result of electron energy deposits. Continue to the next + // jet. + + if ((jetOrig.Pt() >= 30e3 && jetOrig.Pt() < 50e3) && jet.Pt() < 20e3) { + continue; + } else if ((jetOrig.Pt() >= 50e3 && jetOrig.Pt() < 100e3) && jet.Pt() < 30e3) { + continue; + } else if ((jetOrig.Pt() >= 100e3 && jetOrig.Pt() < 400e3) && jet.Pt() < 90e3) { + continue; + } else if ((jetOrig.Pt() >= 400e3 && jetOrig.Pt() < 800e3) && jet.Pt() < 130e3) { + continue; + } else if ((jetOrig.Pt() >= 800e3 && jetOrig.Pt() < 1200e3) && jet.Pt() < 230e3) { + continue; + } else if ((jetOrig.Pt() >= 1200e3 && jetOrig.Pt() < 1600e3) && jet.Pt() < 700e3) { + continue; + } else if ((jetOrig.Pt() >= 1600e3 && jetOrig.Pt() < 2000e3) && jet.Pt() < 1250e3) { + continue; + } else if ((jetOrig.Pt() >= 2000e3 && jetOrig.Pt() < 2200e3) && jet.Pt() < 1300e3) { + continue; + } else if (jetOrig.Pt() > 2200e3 && jet.Pt() < 1350e3) { + continue; + } - // not in the associated tracks. - bool foundMatch = false; - std::vector<const xAOD::TrackParticle*> jetTracks; - //bool haveJetTracks = m_jets->at(iJet)->getAssociatedObjects(xAOD::JetAttribute::GhostTrack, jetTracks); - for (size_t t = 0; t < jetTracks.size(); ++t) { - TLorentzVector jet_trk; - jet_trk.SetPtEtaPhiE(jetTracks[t]->pt(), jetTracks[t]->eta(), jetTracks[t]->phi(), jetTracks[t]->e()); - if (jet_trk.DeltaR(trk) < 0.01) { - foundMatch = true; - } - } + // if the electron is too close to a subtracted jet... + if (jet.DeltaR(el) < 0.2) { + if (fDebug) cout << " El too close to jet. Removing." << endl; - if (!foundMatch) - continue; + // remove from good electrons list. + fGoodEls[iEl] = false; - // recompute JVF. - fJetD3PDTrkPtSums[iJet] -= trk.Pt(); + if (fElClAssocJet[iEl] >= 0) { + // add electron 4-vector back to jet. + TmpJetTLVs[fElClAssocJet[iEl]] += el; + //remove from subtracted jets list + fSubJets[iJet] = 0; + // remove this electron from the association. + fJetAssocElCls[iJet].erase(iEl); + } + } + } + } + + fJetTLVs = TmpJetTLVs; + fOrigJetTLVs = TmpOrigJetTLVs; + fGoodJets = vector<bool>(nJets, true); + + for (size_t iJet = 0; iJet < nJets; iJet++) { + jetOrig = fOrigJetTLVs[iJet]; + + if (jetOrig.Pt() >= 30e3 && jetOrig.Pt() < 50e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 20e3; + } else if (jetOrig.Pt() >= 50e3 && jetOrig.Pt() < 100e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 30e3; + } else if (jetOrig.Pt() >= 100e3 && jetOrig.Pt() < 400e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 90e3; + } else if (jetOrig.Pt() >= 400e3 && jetOrig.Pt() < 800e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 130e3; + } else if (jetOrig.Pt() >= 800e3 && jetOrig.Pt() < 1200e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 230e3; + } else if (jetOrig.Pt() >= 1200e3 && jetOrig.Pt() < 1600e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 700e3; + } else if (jetOrig.Pt() >= 1600e3 && jetOrig.Pt() < 2000e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 1250e3; + } else if (jetOrig.Pt() >= 2000e3 && jetOrig.Pt() < 2200e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 1300e3; + } else if (jetOrig.Pt() > 2200e3) { + fGoodJets[iJet] = fJetTLVs[iJet].Pt() > 1350e3; + } + } +} - if (std::fabs(std::sin(m_electrons->at(ElIdx)->trackParticle()->theta())*m_electrons->at(ElIdx)->trackParticle()->z0()) < 1.0 && - std::fabs(m_electrons->at(ElIdx)->trackParticle()->d0()) < 1.0) - fJetD3PDTrkPtPVSums[iJet] -= trk.Pt(); +void TTBarElectronJetOverlap::RecalcJVF() { + size_t nJets = m_jets->size(); + int ElIdx; + //int TrkIdx; + TLorentzVector trk; + + for (size_t iJet = 0; iJet < nJets; iJet++) { + // if jvf == 0 or -1, no need to recalulate... + if (!fJetJVFs[iJet] || + fJetJVFs[iJet] < 0) continue; + + for (set<int>::iterator iEl = fJetAssocElCls[iJet].begin(); + iEl != fJetAssocElCls[iJet].end(); iEl++) { + ElIdx = *iEl; + + trk.SetPtEtaPhiE(m_electrons->at(ElIdx)->trackParticle()->pt(), + m_electrons->at(ElIdx)->trackParticle()->eta(), m_electrons->at( + ElIdx)->trackParticle()->phi(), m_electrons->at(ElIdx)->trackParticle()->e()); + + // not in the associated tracks. + bool foundMatch = false; + std::vector<const xAOD::TrackParticle*> jetTracks; + //bool haveJetTracks = m_jets->at(iJet)->getAssociatedObjects(xAOD::JetAttribute::GhostTrack, jetTracks); + for (size_t t = 0; t < jetTracks.size(); ++t) { + TLorentzVector jet_trk; + jet_trk.SetPtEtaPhiE(jetTracks[t]->pt(), jetTracks[t]->eta(), jetTracks[t]->phi(), jetTracks[t]->e()); + if (jet_trk.DeltaR(trk) < 0.01) { + foundMatch = true; } + } + + if (!foundMatch) continue; - // we subtracted too much for some reason? - if (fJetD3PDTrkPtSums[iJet] < 0 || - fJetD3PDTrkPtPVSums[iJet] < 0) - fJetJVFs[iJet] = 0; - // no tracks associated with the jet. - else if (fJetD3PDTrkPtSums[iJet] == 0) - fJetJVFs[iJet] = -1; - // all good. recalculate JVF. - else - fJetJVFs[iJet] = fJetD3PDTrkPtPVSums[iJet]/fJetD3PDTrkPtSums[iJet]; + // recompute JVF. + fJetD3PDTrkPtSums[iJet] -= trk.Pt(); + + if (std::fabs(std::sin(m_electrons->at(ElIdx)->trackParticle()->theta()) * + m_electrons->at(ElIdx)->trackParticle()->z0()) < 1.0 && + std::fabs(m_electrons->at(ElIdx)->trackParticle()->d0()) < 1.0) fJetD3PDTrkPtPVSums[iJet] -= trk.Pt(); } + + // we subtracted too much for some reason? + if (fJetD3PDTrkPtSums[iJet] < 0 || + fJetD3PDTrkPtPVSums[iJet] < 0) fJetJVFs[iJet] = 0; + // no tracks associated with the jet. + else if (fJetD3PDTrkPtSums[iJet] == 0) fJetJVFs[iJet] = -1; + // all good. recalculate JVF. + else fJetJVFs[iJet] = fJetD3PDTrkPtPVSums[iJet] / fJetD3PDTrkPtSums[iJet]; + } } -void TTBarElectronJetOverlap::AnalyzeEvent(const std::string &leptonDef) { +void TTBarElectronJetOverlap::AnalyzeEvent(const std::string& leptonDef) { FindAssocEls(); SubtractEls(); FindGoodObjects(); //RecalcJVF(); - // put the results back in place - size_t se = m_electrons->size(); - size_t sj = m_jets->size(); - for (size_t i = 0; i < sj; i++) { - m_jets->at(i)->setJetP4(xAOD::JetFourMom_t(fJetTLVs[i].Perp(), fJetTLVs[i].Eta(), fJetTLVs[i].Phi(), fJetTLVs[i].M())); - - if (fGoodJets[i]) m_jets->at(i)->auxdata<char>("passesFancyOR") = 1; // Subtracted jets that pass the OR test and are kept. - else m_jets->at(i)->auxdata<char>("passesFancyOR") = 0; - - if (fSubJets[i]==1) m_jets->at(i)->auxdata<char>("subtractedJet") = 1; // Jets close to electrons that undergo the OR test. - else m_jets->at(i)->auxdata<char>("subtractedJet") = 0; - - - //std::vector<float> newJVF; - //newJVF.push_back(fJetJVFs[i]); - //m_jets->at(i)->setAttribute<std::vector<float> >("JVF", newJVF); - if (fDebug) { - cout << " - (final) Jet # " << i << - " Pt Eta Phi M: " << - m_jets->at(i)->pt() << " " << - m_jets->at(i)->eta() << " " << - m_jets->at(i)->phi() << " " << - m_jets->at(i)->m() << " good " << (int) m_jets->at(i)->auxdata<char>(leptonDef.c_str())<< endl; - } + // put the results back in place + size_t se = m_electrons->size(); + size_t sj = m_jets->size(); + for (size_t i = 0; i < sj; i++) { + m_jets->at(i)->setJetP4(xAOD::JetFourMom_t(fJetTLVs[i].Perp(), fJetTLVs[i].Eta(), fJetTLVs[i].Phi(), + fJetTLVs[i].M())); + + if (fGoodJets[i]) m_jets->at(i)->auxdata<char>("passesFancyOR") = 1; // Subtracted + // jets + // that + // pass + // the + // OR + // test + // and + // are + // kept. + else m_jets->at(i)->auxdata<char>("passesFancyOR") = 0; + + if (fSubJets[i] == 1) m_jets->at(i)->auxdata<char>("subtractedJet") = 1; // Jets + // close + // to + // electrons + // that + // undergo + // the + // OR + // test. + else m_jets->at(i)->auxdata<char>("subtractedJet") = 0; + + + //std::vector<float> newJVF; + //newJVF.push_back(fJetJVFs[i]); + //m_jets->at(i)->setAttribute<std::vector<float> >("JVF", newJVF); + if (fDebug) { + cout << " - (final) Jet # " << i << + " Pt Eta Phi M: " << + m_jets->at(i)->pt() << " " << + m_jets->at(i)->eta() << " " << + m_jets->at(i)->phi() << " " << + m_jets->at(i)->m() << " good " << (int) m_jets->at(i)->auxdata<char>(leptonDef.c_str()) << endl; } + } - for (size_t j = 0; j < se; j++) { - if (!fGoodEls[j] || !fElGood[j]) { - m_electrons->at(j)->auxdata<char>(leptonDef.c_str()) = 0; - } else { - m_electrons->at(j)->auxdata<char>(leptonDef.c_str()) = 1; - } - - if (fDebug) { - cout << " - (final) El # " << j << - " Pt Eta Phi M: " << - m_electrons->at(j)->pt() << " " << - m_electrons->at(j)->eta() << " " << - m_electrons->at(j)->phi() << " " << - m_electrons->at(j)->m() << " good " << (int) m_electrons->at(j)->auxdata<char>(leptonDef.c_str()) << endl; - } + for (size_t j = 0; j < se; j++) { + if (!fGoodEls[j] || !fElGood[j]) { + m_electrons->at(j)->auxdata<char>(leptonDef.c_str()) = 0; + } else { + m_electrons->at(j)->auxdata<char>(leptonDef.c_str()) = 1; } -} - + if (fDebug) { + cout << " - (final) El # " << j << + " Pt Eta Phi M: " << + m_electrons->at(j)->pt() << " " << + m_electrons->at(j)->eta() << " " << + m_electrons->at(j)->phi() << " " << + m_electrons->at(j)->m() << " good " << (int) m_electrons->at(j)->auxdata<char>(leptonDef.c_str()) << endl; + } + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/TopJetSubstructure.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/TopJetSubstructure.cxx index d0ab71ef6c22..ff7816b9ac69 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/TopJetSubstructure.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/Root/TopJetSubstructure.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopJetSubstructure/TopJetSubstructure.h" @@ -17,4 +17,3 @@ top::TopJetSubstructure::~TopJetSubstructure() { void top::TopJetSubstructure::print(std::ostream& o) const { o << "TopJetSubstructure empty calss" << std::endl; } - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/ElectronInJetSubtractionAlgorithm.h b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/ElectronInJetSubtractionAlgorithm.h index 86161df3042d..584995d195f4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/ElectronInJetSubtractionAlgorithm.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/ElectronInJetSubtractionAlgorithm.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: ElectronInJetSubtractionAlgorithm.h 654856 2015-03-17 19:00:30Z dferreir $ #ifndef ANALYSISTOP_TOPJETSUBSTRUCTURE_ELECTRONINJETSUBTRACTIONALGORITHM_H @@ -10,25 +10,24 @@ #include "xAODJet/JetContainer.h" #include "TopJetSubstructure/TTBarElectronJetOverlap.h" -namespace top{ +namespace top { class ElectronInJetSubtractionAlgorithm final { - public: - ElectronInJetSubtractionAlgorithm(); - virtual ~ElectronInJetSubtractionAlgorithm(){} - - ElectronInJetSubtractionAlgorithm(const ElectronInJetSubtractionAlgorithm& rhs) = delete; - ElectronInJetSubtractionAlgorithm(ElectronInJetSubtractionAlgorithm&& rhs) = delete; - ElectronInJetSubtractionAlgorithm& operator=(const ElectronInJetSubtractionAlgorithm& rhs) = delete; - - void apply( xAOD::ElectronContainer* electrons , xAOD::JetContainer* jets , const bool useLooseElectrons=false ); - - private: - bool m_doLooseCuts; - // Pass selection strings - const std::string m_passPreORSelection; - const std::string m_passPreORSelectionLoose; + public: + ElectronInJetSubtractionAlgorithm(); + virtual ~ElectronInJetSubtractionAlgorithm() {} - TTBarElectronJetOverlap m_o; + ElectronInJetSubtractionAlgorithm(const ElectronInJetSubtractionAlgorithm& rhs) = delete; + ElectronInJetSubtractionAlgorithm(ElectronInJetSubtractionAlgorithm&& rhs) = delete; + ElectronInJetSubtractionAlgorithm& operator = (const ElectronInJetSubtractionAlgorithm& rhs) = delete; + + void apply(xAOD::ElectronContainer* electrons, xAOD::JetContainer* jets, const bool useLooseElectrons = false); + private: + bool m_doLooseCuts; + // Pass selection strings + const std::string m_passPreORSelection; + const std::string m_passPreORSelectionLoose; + + TTBarElectronJetOverlap m_o; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/LargeJetTrimmer.h b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/LargeJetTrimmer.h index a2e72fea55b6..b9005b8b2996 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/LargeJetTrimmer.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/LargeJetTrimmer.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef LARGEJETTRIMMER_H #define LARGEJETTRIMMER_H @@ -9,13 +9,12 @@ #include "TopJetSubstructure/TopJetSubstructure.h" namespace top { - /** * @brief JetCorrection-derived class that trims large-R jets while derivations are not ready. */ -class LargeJetTrimmer : public TopJetSubstructure { -public: + class LargeJetTrimmer: public TopJetSubstructure { + public: LargeJetTrimmer(); ~LargeJetTrimmer(); @@ -23,11 +22,8 @@ public: ///Useful messages on the screen. void print(std::ostream&) const; - -private: -}; - + private: + }; } #endif - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/SubjetMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/SubjetMaker.h index 9bf729325d36..d87d56bfc71d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/SubjetMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/SubjetMaker.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef SUBJETMAKER_H #define SUBJETMAKER_H @@ -9,13 +9,12 @@ #include "TopJetSubstructure/TopJetSubstructure.h" namespace top { - /** * @brief Derived class that constructs subjets while derivations are not ready. */ -class SubjetMaker : public TopJetSubstructure { -public: + class SubjetMaker: public TopJetSubstructure { + public: SubjetMaker(); ~SubjetMaker(); @@ -23,11 +22,8 @@ public: ///Useful messages on the screen. void print(std::ostream&) const; - -private: -}; - + private: + }; } #endif - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/TTBarElectronJetOverlap.h b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/TTBarElectronJetOverlap.h index d3a2c02772b3..e8221e3c9ddd 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/TTBarElectronJetOverlap.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/TTBarElectronJetOverlap.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef __TTBARELECTRONJETOVERLAP_H__ #define __TTBARELECTRONJETOVERLAP_H__ @@ -14,60 +14,58 @@ #include "xAODEgamma/ElectronContainer.h" class TTBarElectronJetOverlap { - private: - std::vector<TLorentzVector> fJetTLVs; - std::vector<float> fJetJVFs; - std::vector<float> fJetD3PDTrkPtPVSums; - std::vector<float> fJetD3PDTrkPtSums; - - std::vector<bool> fGoodJets; - std::vector<int> fSubJets; - std::vector<std::set<int> > fJetAssocElCls; - - std::vector<TLorentzVector> fElTLVs; - std::vector<TLorentzVector> fOrigJetTLVs; - std::vector<TLorentzVector> fElClTLVs; - std::vector<bool> fElGood; // this registers if the electron passed the object definition - - std::vector<bool> fGoodEls; - std::vector<int> fElClAssocJet; - - bool fDebug; - - void FindAssocEls(); - void SubtractEls(); - void FindGoodObjects(); - void RecalcJVF(); - - - xAOD::JetContainer *m_jets; //! - xAOD::ElectronContainer *m_electrons; //! - - public: - TTBarElectronJetOverlap() : fDebug(false), m_jets(nullptr), m_electrons(nullptr) { - } - - ~TTBarElectronJetOverlap() { } - - void AnalyzeEvent(const std::string &leptonDef); - - // sets the debug level (info will print if set true). - void SetDebug(bool db) { - fDebug = db; - } - - bool GetDebug() { - return fDebug; - } - - // load all anti-kt 0.4 LCTopo jets in the event. - // these variables should correspond to the *corrected* jet - // quantities. Every jet in the D3PD should be passed. - // load selected electrons. - // these variables should only be filled for /selected/ - // electrons (i.e. pass ID and isolation cuts). - void Load(xAOD::JetContainer *jets, xAOD::ElectronContainer *electrons, const std::string &leptonDef); - +private: + std::vector<TLorentzVector> fJetTLVs; + std::vector<float> fJetJVFs; + std::vector<float> fJetD3PDTrkPtPVSums; + std::vector<float> fJetD3PDTrkPtSums; + + std::vector<bool> fGoodJets; + std::vector<int> fSubJets; + std::vector<std::set<int> > fJetAssocElCls; + + std::vector<TLorentzVector> fElTLVs; + std::vector<TLorentzVector> fOrigJetTLVs; + std::vector<TLorentzVector> fElClTLVs; + std::vector<bool> fElGood; // this registers if the electron passed the object definition + + std::vector<bool> fGoodEls; + std::vector<int> fElClAssocJet; + + bool fDebug; + + void FindAssocEls(); + void SubtractEls(); + void FindGoodObjects(); + void RecalcJVF(); + + + xAOD::JetContainer* m_jets; //! + xAOD::ElectronContainer* m_electrons; //! +public: + TTBarElectronJetOverlap() : fDebug(false), m_jets(nullptr), m_electrons(nullptr) { + } + + ~TTBarElectronJetOverlap() { } + + void AnalyzeEvent(const std::string& leptonDef); + + // sets the debug level (info will print if set true). + void SetDebug(bool db) { + fDebug = db; + } + + bool GetDebug() { + return fDebug; + } + + // load all anti-kt 0.4 LCTopo jets in the event. + // these variables should correspond to the *corrected* jet + // quantities. Every jet in the D3PD should be passed. + // load selected electrons. + // these variables should only be filled for /selected/ + // electrons (i.e. pass ID and isolation cuts). + void Load(xAOD::JetContainer* jets, xAOD::ElectronContainer* electrons, const std::string& leptonDef); }; #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/TopJetSubstructure.h b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/TopJetSubstructure.h index c9a916c747c5..271b76074c4b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/TopJetSubstructure.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/TopJetSubstructure/TopJetSubstructure.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPJETSUBSTRUCTURE_H #define TOPJETSUBSTRUCTURE_H @@ -8,25 +8,21 @@ #include "xAODJet/JetContainer.h" namespace top { - /** * @brief JetCorrection-derived class that applies a jet substructure action on the object */ -class TopJetSubstructure { -public: + class TopJetSubstructure { + public: TopJetSubstructure(); - ~TopJetSubstructure(); + virtual ~TopJetSubstructure(); virtual void correctJet(xAOD::Jet& /*jet*/) = 0; ///Useful messages on the screen. void print(std::ostream&) const; - -private: -}; - + private: + }; } #endif - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt index 421048d9bed4..fd5bbb17159d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt @@ -1,6 +1,7 @@ +# Auto-generated on: 2017-03-08 14:47:37.990954 # Declare the name of this package: -atlas_subdir( TopObjectSelectionTools ) +atlas_subdir( TopObjectSelectionTools None ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -11,29 +12,41 @@ atlas_depends_on_subdirs( PUBLIC xAODMuon xAODTau xAODTracking + FourMomUtils ElectronPhotonSelectorTools - MuonSelectorTools + TopDataPreparation TopEvent TopSystematicObjectMaker AssociationUtils + TrigBunchCrossingTool TrigConfInterfaces TrigDecisionTool TriggerMatchingTool TrigTauMatching + TriggerAnalysisInterfaces + #TrigGlobalEfficiencyCorrection GoodRunsLists - JetJvtEfficiency - xAODBTaggingEfficiency + InDetTrackSelectionTool + JetAnalysisInterfaces JetSubStructureMomentTools JetSubStructureUtils - JetReclustering ) + JetReclustering + #BoostedJetTaggers + MuonAnalysisInterfaces + FTagAnalysisInterfaces + JetAnalysisInterfaces + PATCore) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) +# Custom definitions needed for this package: +add_definitions( -g ) + # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopObjectSelectionTools _cintDictSource - ROOT_HEADERS TopObjectSelectionTools/RCJetMC15.h Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) # Build a library that other components can link against: atlas_add_library( TopObjectSelectionTools Root/*.cxx Root/*.h Root/*.icc @@ -47,22 +60,29 @@ atlas_add_library( TopObjectSelectionTools Root/*.cxx Root/*.h Root/*.icc xAODMuon xAODTau xAODTracking + FourMomUtils ElectronPhotonSelectorToolsLib - MuonSelectorToolsLib TopEvent TopSystematicObjectMaker AssociationUtilsLib + TrigBunchCrossingTool TrigConfInterfaces TrigDecisionToolLib TriggerMatchingToolLib TrigTauMatchingLib + #TrigGlobalEfficiencyCorrectionLib GoodRunsListsLib - JetJvtEfficiencyLib - xAODBTaggingEfficiencyLib + InDetTrackSelectionToolLib + JetAnalysisInterfacesLib JetSubStructureMomentToolsLib JetSubStructureUtils JetReclusteringLib - ${ROOT_LIBRARIES} + #BoostedJetTaggersLib + MuonAnalysisInterfacesLib + FTagAnalysisInterfacesLib + JetAnalysisInterfacesLib + PATCoreLib + ${ROOT_LIBRARIES} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) # Install data files from the package: diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/AntiMuonMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/AntiMuonMC15.cxx index aee050b03609..979bd53901cd 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/AntiMuonMC15.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/AntiMuonMC15.cxx @@ -1,69 +1,61 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -#include "TopObjectSelectionTools/AntiMuonMC15.h" - -#include "TopEvent/EventTools.h" - -namespace top { - -AntiMuonMC15::AntiMuonMC15(const double ptcut, IsolationBase* /* isolation */) : - m_ptcut(ptcut), - m_muonSelectionTool("CP::MuonSelectionTool") - //m_muonSelectionToolLoose("CP::MuonSelectionToolLoose"), - //m_isolation(isolation) -{ - top::check( m_muonSelectionTool.retrieve() , "Failed to retrieve muonSelectionTool" ); -// top::check( m_muonSelectionToolLoose.retrieve() , "Failed to retrieve muonSelectionToolLoose" ); -} - -bool AntiMuonMC15::passSelection(const xAOD::Muon& mu) const -{ - if (mu.pt() < m_ptcut) - return false; - - ///-- https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15 --/// - if (!m_muonSelectionTool->accept(mu)) - return false; - - - if (mu.energyLossType()!=xAOD::Muon::NotIsolated) return false; - float eloss=0; - bool ok=mu.parameter(eloss,xAOD::Muon::EnergyLoss); - if (ok && eloss>6000) return false; - float etcone20=0,ptvarcone40=0; - ok=mu.isolation(etcone20,xAOD::Iso::etcone20); - if (ok && etcone20/mu.pt()<0.03) return false; - //if (mu.auxdataConst<float>("miniIso")/mu.pt() > .1) return false; - ok=mu.isolation(ptvarcone40,xAOD::Iso::ptvarcone40); - if (ok && ptvarcone40/mu.pt()>0.1) return false; - - return true; -} - -bool AntiMuonMC15::passSelectionLoose(const xAOD::Muon& /*mu*/) const -{ - - // code does not compile without this function - - return true; -} - - void AntiMuonMC15::print(std::ostream& os) const { - os << "AntiMuonMC15\n" - << " * pT > " << m_ptcut << "\n" -// << " * |eta| < " << m_etamax << "\n" -// << " * quality=" << m_quality << " (tight=0, medium=1, loose=2, v.loose=3)\n" - << " * Everything else from muon tool - fill this in?\n"; - -// if (!m_isolation) -// os << " * No isolation requirement\n"; -// else -// m_isolation->print(os); - } - - - -} - +#include "TopObjectSelectionTools/AntiMuonMC15.h" + +#include "TopEvent/EventTools.h" + +namespace top { + AntiMuonMC15::AntiMuonMC15(const double ptcut, IsolationBase* /* isolation */) : + m_ptcut(ptcut), + m_muonSelectionTool("CP::MuonSelectionTool") { + //m_muonSelectionToolLoose("CP::MuonSelectionToolLoose"), + //m_isolation(isolation) + top::check(m_muonSelectionTool.retrieve(), "Failed to retrieve muonSelectionTool"); +// top::check( m_muonSelectionToolLoose.retrieve() , "Failed to retrieve muonSelectionToolLoose" ); + } + + bool AntiMuonMC15::passSelection(const xAOD::Muon& mu) const { + if (mu.pt() < m_ptcut) return false; + + ///-- https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15 --/// + if (!m_muonSelectionTool->accept(mu)) return false; + + + if (mu.energyLossType() != xAOD::Muon::NotIsolated) return false; + + float eloss = 0; + bool ok = mu.parameter(eloss, xAOD::Muon::EnergyLoss); + if (ok && eloss > 6000) return false; + + float etcone20 = 0, ptvarcone40 = 0; + ok = mu.isolation(etcone20, xAOD::Iso::etcone20); + if (ok && etcone20 / mu.pt() < 0.03) return false; + + //if (mu.auxdataConst<float>("miniIso")/mu.pt() > .1) return false; + ok = mu.isolation(ptvarcone40, xAOD::Iso::ptvarcone40); + if (ok && ptvarcone40 / mu.pt() > 0.1) return false; + + return true; + } + + bool AntiMuonMC15::passSelectionLoose(const xAOD::Muon& /*mu*/) const { + // code does not compile without this function + + return true; + } + + void AntiMuonMC15::print(std::ostream& os) const { + os << "AntiMuonMC15\n" + << " * pT > " << m_ptcut << "\n" +// << " * |eta| < " << m_etamax << "\n" +// << " * quality=" << m_quality << " (tight=0, medium=1, loose=2, v.loose=3)\n" + << " * Everything else from muon tool - fill this in?\n"; + +// if (!m_isolation) +// os << " * No isolation requirement\n"; +// else +// m_isolation->print(os); + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronCutBasedMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronCutBasedMC15.cxx index ce47f1b7edb7..c9f99cc96ef4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronCutBasedMC15.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronCutBasedMC15.cxx @@ -1,53 +1,44 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/ElectronCutBasedMC15.h" namespace top { - -ElectronCutBasedMC15::ElectronCutBasedMC15(double ptcut, bool vetoCrack, const std::string& quality, const std::string& qualityLoose, IsolationBase* isolation) : + ElectronCutBasedMC15::ElectronCutBasedMC15(double ptcut, bool vetoCrack, const std::string& quality, + const std::string& qualityLoose, IsolationBase* isolation) : m_ptcut(ptcut), m_vetoCrack(vetoCrack), m_quality(quality), m_qualityLoose(qualityLoose), - m_isolation(isolation) -{ -} + m_isolation(isolation) { + } -bool ElectronCutBasedMC15::passSelection(const xAOD::Electron& el) const { + bool ElectronCutBasedMC15::passSelection(const xAOD::Electron& el) const { + if (!passSelectionNoIsolation(el, m_quality)) return false; - if (!passSelectionNoIsolation(el, m_quality)) - return false; + if (m_isolation && !m_isolation->passSelection(el)) return false; - if (m_isolation && !m_isolation->passSelection(el)) - return false; - return true; -} - -bool ElectronCutBasedMC15::passSelectionLoose(const xAOD::Electron& el) const { + } - if (!passSelectionNoIsolation(el, m_qualityLoose)) - return false; + bool ElectronCutBasedMC15::passSelectionLoose(const xAOD::Electron& el) const { + if (!passSelectionNoIsolation(el, m_qualityLoose)) return false; - if (m_isolation && !m_isolation->passSelectionLoose(el)) - return false; + if (m_isolation && !m_isolation->passSelectionLoose(el)) return false; return true; -} + } -bool ElectronCutBasedMC15::passSelectionNoIsolation(const xAOD::Electron& el, const std::string& quality) const { + bool ElectronCutBasedMC15::passSelectionNoIsolation(const xAOD::Electron& el, const std::string& quality) const { // if (el.author() != xAOD::EgammaParameters::AuthorElectron && el.author() != xAOD::EgammaParameters::AuthorSofte) // return false; - if (el.pt() < m_ptcut) - return false; + if (el.pt() < m_ptcut) return false; // This will be replaced with the proper AsgElectronIsEMSelector // Once the calib files are on afs (cvmfs?) - not there yet..... - if (!el.passSelection(quality)) - return false; + if (!el.passSelection(quality)) return false; //WARNING: Not all electrons keep clusters in the derivation //i.e. bad electrons (which is why we moved the check on the quality @@ -55,26 +46,22 @@ bool ElectronCutBasedMC15::passSelectionNoIsolation(const xAOD::Electron& el, co //Good electrons should always have a cluster, if not then crash to warn us //Better than checking and silently doing nothing... //This stops a crash - if (std::fabs(el.caloCluster()->etaBE(2)) > 2.47) - return false; + if (std::fabs(el.caloCluster()->etaBE(2)) > 2.47) return false; - if (m_vetoCrack && std::fabs(el.caloCluster()->etaBE(2)) > 1.37 && std::fabs(el.caloCluster()->etaBE(2)) < 1.52) - return false; + if (m_vetoCrack && std::fabs(el.caloCluster()->etaBE(2)) > 1.37 && + std::fabs(el.caloCluster()->etaBE(2)) < 1.52) return false; return true; -} + } -void ElectronCutBasedMC15::print(std::ostream& os) const { + void ElectronCutBasedMC15::print(std::ostream& os) const { os << "ElectronCutBasedMC15\n"; os << " * pT > " << m_ptcut << "\n"; os << " * Currently disabled --- |cluster_eta| < 2.47 \n"; os << " * Veto 1.37 < |cluster_eta| < 1.52? " << std::boolalpha << m_vetoCrack << "\n"; os << " * Quality " << m_quality << "\n"; - if (!m_isolation) - os << " * No isolation requirement\n"; - else - m_isolation->print(os); -} - + if (!m_isolation) os << " * No isolation requirement\n"; + else m_isolation->print(os); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronLikelihoodMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronLikelihoodMC15.cxx index b8bf1093b8ed..7ebaf17b8767 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronLikelihoodMC15.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronLikelihoodMC15.cxx @@ -1,16 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/ElectronLikelihoodMC15.h" #include "TopEvent/EventTools.h" -#include "ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h" +//#include "ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h" +#include "ElectronPhotonSelectorTools/ElectronSelectorHelpers.h" #include <iostream> -namespace top { +#include "TopObjectSelectionTools/MsgCategory.h" +using namespace TopObjectSelectionTools; - ElectronLikelihoodMC15::ElectronLikelihoodMC15(const double ptcut, const bool vetoCrack, const std::string& operatingPoint, - const std::string& operatingPointLoose, StandardIsolation* isolation, const bool applyTTVACut) : +namespace top { + ElectronLikelihoodMC15::ElectronLikelihoodMC15(const double ptcut, const bool vetoCrack, + const std::string& operatingPoint, + const std::string& operatingPointLoose, StandardIsolation* isolation, + const bool applyTTVACut, const bool applyChargeIDCut) : m_ptcut(ptcut), m_vetoCrack(vetoCrack), m_operatingPoint("SetMe"), @@ -19,192 +24,195 @@ namespace top { m_operatingPointLoose_DF("SetMe"), m_isolation(isolation), m_applyTTVACut(applyTTVACut), - m_applyChargeIDCut(false) - { + m_applyChargeIDCut(applyChargeIDCut) { /** Egamma use different naming styles for the likelihood in: - * Trigger = HLT_e24_lhmedium_iloose_L1EM20VH HLT_e60_lhmedium - * Derivation Framework = DFCommonElectronsLHMedium - * ElectronPhotonSelectionTools (the LLH tools) = ElectronLikelihoodMediumOfflineConfig2015.conf - * Trigger SF = efficiencySF.e24vhi_medium1_e60_medium1.MediumLLH.2015.13TeV.rel20p0.v02.root - * Trigger SF = efficiencySF.AnyElectronTrigger.MediumLH.2015.13TeV.rel20p0.v01.root - * ID SF = efficiencySF.offline.MediumLH.2015.13TeV.rel20p0.v01.root - * - * It's a bit of a mess - */ - + * Trigger = HLT_e24_lhmedium_iloose_L1EM20VH HLT_e60_lhmedium + * Derivation Framework = DFCommonElectronsLHMedium + * ElectronPhotonSelectionTools (the LLH tools) = ElectronLikelihoodMediumOfflineConfig2015.conf + * Trigger SF = efficiencySF.e24vhi_medium1_e60_medium1.MediumLLH.2015.13TeV.rel20p0.v02.root + * Trigger SF = efficiencySF.AnyElectronTrigger.MediumLH.2015.13TeV.rel20p0.v01.root + * ID SF = efficiencySF.offline.MediumLH.2015.13TeV.rel20p0.v01.root + * + * It's a bit of a mess + */ + std::string egammaNamesAreNotConsistantAnywhere("LikelihoodNotSetProperly"); std::string egammaNamesAreNotConsistantAnywhereLoose("LikelihoodNotSetProperly"); - if (operatingPoint == "LooseLH") {egammaNamesAreNotConsistantAnywhere = "DFCommonElectronsLHLoose";} - if (operatingPoint == "LooseAndBLayerLH") {egammaNamesAreNotConsistantAnywhere = "DFCommonElectronsLHLoose";} - if (operatingPoint == "MediumLH") {egammaNamesAreNotConsistantAnywhere = "DFCommonElectronsLHMedium";} - if (operatingPoint == "TightLH") {egammaNamesAreNotConsistantAnywhere = "DFCommonElectronsLHTight";} - - if (operatingPointLoose == "LooseLH") {egammaNamesAreNotConsistantAnywhereLoose = "DFCommonElectronsLHLoose";} - if (operatingPointLoose == "LooseAndBLayerLH") {egammaNamesAreNotConsistantAnywhereLoose = "DFCommonElectronsLHLoose";} - if (operatingPointLoose == "MediumLH") {egammaNamesAreNotConsistantAnywhereLoose = "DFCommonElectronsLHMedium";} - if (operatingPointLoose == "TightLH") {egammaNamesAreNotConsistantAnywhereLoose = "DFCommonElectronsLHTight";} - - m_operatingPoint_DF = egammaNamesAreNotConsistantAnywhere; - m_operatingPointLoose_DF = egammaNamesAreNotConsistantAnywhereLoose; - m_operatingPoint = operatingPoint; - m_operatingPointLoose = operatingPointLoose; + if (operatingPoint == "LooseLH") { + egammaNamesAreNotConsistantAnywhere = "DFCommonElectronsLHLoose"; + } + if (operatingPoint == "LooseAndBLayerLH") { + egammaNamesAreNotConsistantAnywhere = "DFCommonElectronsLHLooseBL"; + } + if (operatingPoint == "MediumLH") { + egammaNamesAreNotConsistantAnywhere = "DFCommonElectronsLHMedium"; + } + if (operatingPoint == "TightLH") { + egammaNamesAreNotConsistantAnywhere = "DFCommonElectronsLHTight"; + } + + if (operatingPointLoose == "LooseLH") { + egammaNamesAreNotConsistantAnywhereLoose = "DFCommonElectronsLHLoose"; + } + if (operatingPointLoose == "LooseAndBLayerLH") { + egammaNamesAreNotConsistantAnywhereLoose = "DFCommonElectronsLHLooseBL"; + } + if (operatingPointLoose == "MediumLH") { + egammaNamesAreNotConsistantAnywhereLoose = "DFCommonElectronsLHMedium"; + } + if (operatingPointLoose == "TightLH") { + egammaNamesAreNotConsistantAnywhereLoose = "DFCommonElectronsLHTight"; + } - // currently implemented only for this working point - if (m_operatingPoint == "MediumLH" && m_isolation->tightLeptonIsolation() == "FixedCutTight") - m_applyChargeIDCut = true; + m_operatingPoint_DF = egammaNamesAreNotConsistantAnywhere; + m_operatingPointLoose_DF = egammaNamesAreNotConsistantAnywhereLoose; + m_operatingPoint = operatingPoint; + m_operatingPointLoose = operatingPointLoose; } ElectronLikelihoodMC15::ElectronLikelihoodMC15(const bool, - const double ptcut, const bool vetoCrack, const std::string& operatingPoint, - const std::string& operatingPointLoose, StandardIsolation* isolation, const bool applyTTVACut) : - ElectronLikelihoodMC15::ElectronLikelihoodMC15(ptcut, vetoCrack, operatingPoint, - operatingPointLoose, isolation, applyTTVACut) {} + const double ptcut, const bool vetoCrack, + const std::string& operatingPoint, + const std::string& operatingPointLoose, StandardIsolation* isolation, + const bool applyTTVACut, const bool applyChargeIDCut) : + ElectronLikelihoodMC15::ElectronLikelihoodMC15(ptcut, vetoCrack, operatingPoint, + operatingPointLoose, isolation, applyTTVACut, applyChargeIDCut) {} bool ElectronLikelihoodMC15::passSelection(const xAOD::Electron& el) const { - if (!passSelectionNoIsolation(el, m_operatingPoint_DF, m_operatingPoint)) - return false; + if (!passSelectionNoIsolation(el, m_operatingPoint_DF, m_operatingPoint)) return false; - if (m_isolation && !m_isolation->passSelection(el)) - return false; + if (m_isolation && !m_isolation->passSelection(el)) return false; return true; } bool ElectronLikelihoodMC15::passSelectionLoose(const xAOD::Electron& el) const { - if (!passSelectionNoIsolation(el, m_operatingPointLoose_DF, m_operatingPointLoose)) - return false; + if (!passSelectionNoIsolation(el, m_operatingPointLoose_DF, m_operatingPointLoose)) return false; - if (m_isolation && !m_isolation->passSelectionLoose(el)) - return false; + if (m_isolation && !m_isolation->passSelectionLoose(el)) return false; return true; } - bool ElectronLikelihoodMC15::passSelectionNoIsolation(const xAOD::Electron& el, const std::string& operatingPoint_DF, const std::string& operatingPoint) const { + bool ElectronLikelihoodMC15::passSelectionNoIsolation(const xAOD::Electron& el, const std::string& operatingPoint_DF, + const std::string& operatingPoint) const { + if (el.pt() < m_ptcut) return false; - if (el.pt() < m_ptcut) - return false; + // removing bad electron cluser - see + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EGammaIdentificationRun2#Bad_Electron_Photon_Cluster + if (!el.isGoodOQ(xAOD::EgammaParameters::BADCLUSELECTRON)) return false; - // removing bad electron cluser - see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/EGammaIdentificationRun2#Bad_Electron_Photon_Cluster - if( !el.isGoodOQ(xAOD::EgammaParameters::BADCLUSELECTRON) ) return false; + // Try to catch instances for derivations using a different type for this variable + try { + if (el.auxdataConst<int>(operatingPoint_DF) != 1) return false; + } + catch (const SG::ExcAuxTypeMismatch& e) { + if (el.auxdataConst<char>(operatingPoint_DF) != 1) return false; + } + + if (operatingPoint == "LooseAndBLayerLH") { + if (!passBLayerCuts(el)) return false; + } + //WARNING: There has been a bug previously in our derivations where looseLH failed, but tighter WP succeed + //WARNING: This results in a "good" electron with no clusters (due to thinning), and then we crash and burn + //WARNING: We are therefore going to test whether the looseLH WP is also passed before we check the cluster eta + //WARNING: If it does not (and we passed ID checks above) then this is a dodgy electron + //WARNING: So we print a warning to alert the user that this was found, but then we proceed as normal + //WARNING: and this electron is vetoed from the selection try { - if (el.auxdataConst<int>(operatingPoint_DF) != 1) + if (el.auxdataConst<int>("DFCommonElectronsLHLoose") != 1) { + ATH_MSG_ERROR("This electron fails the DFCommonElectronsLHLoose and has an incorrect decoration.\n pt (" + << el.pt() << "), eta (" << el.eta() << ")"); return false; - } catch(std::exception& e) { - if (el.auxdataConst<char>(operatingPoint_DF) != 1) + } + } + catch (const SG::ExcAuxTypeMismatch& e) { + if (el.auxdataConst<char>("DFCommonElectronsLHLoose") != 1) { + ATH_MSG_ERROR("This electron fails the DFCommonElectronsLHLoose and has an incorrect decoration.\n pt (" + << el.pt() << "), eta (" << el.eta() << ")"); return false; + } } - if(operatingPoint == "LooseAndBLayerLH"){ - - if(!passBLayerCuts(el)) - return false; - - } - //WARNING: Not all electrons keep clusters in the derivation //i.e. bad electrons (which is why we moved the check on the likelihood //before the check on the calo cluster) //This stops a crash //Good electrons should always have a cluster, if not then crash to warn us //Better than checking and silently doing nothing... - if (std::fabs(el.caloCluster()->etaBE(2)) > 2.47) - return false; + if (std::fabs(el.caloCluster()->etaBE(2)) > 2.47) return false; - if (m_vetoCrack && std::fabs(el.caloCluster()->etaBE(2)) > 1.37 && std::fabs(el.caloCluster()->etaBE(2)) < 1.52) - return false; + //Veto electrons suffering from the 2015+2016/mc16a crack+topocluster association bug + //See https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/HowToCleanJets2017#EGamma_Crack_Electron_topocluste for details + if (el.isAvailable<char>("DFCommonCrackVetoCleaning")) + if (!el.auxdataConst<char>("DFCommonCrackVetoCleaning")) return false; + + if (m_vetoCrack && std::fabs(el.caloCluster()->etaBE(2)) > 1.37 && + std::fabs(el.caloCluster()->etaBE(2)) < 1.52) return false; // Track-to-vertex association - if (m_applyTTVACut){ - if (!passTTVACuts(el)) - return false; + if (m_applyTTVACut) { + if (!passTTVACuts(el)) return false; } // Electron Charge ID Selector Tool // apply decoration only - if (m_applyChargeIDCut && !passChargeIDCut(el)) - el.auxdecor<char>("passChargeID") = 0; - else - el.auxdecor<char>("passChargeID") = 1; - + if (m_applyChargeIDCut && !passChargeIDCut(el)) el.auxdecor<char>("passChargeID") = 0; + else el.auxdecor<char>("passChargeID") = 1; + return true; } -bool ElectronLikelihoodMC15::passBLayerCuts(const xAOD::Electron& el) const -{ - - // this is taken from ElectronPhotonSelectorTools/Root/AsgElectronLikelihoodTool.cxx - const xAOD::TrackParticle* t = el.trackParticle(); - - if (!t) return false; - - uint8_t expectBlayer(true); - uint8_t nBlayerHits(0); - uint8_t nBlayerOutliers(0); - - t -> summaryValue(expectBlayer, xAOD::expectBLayerHit); - t -> summaryValue(nBlayerHits, xAOD::numberOfBLayerHits); - t -> summaryValue(nBlayerOutliers, xAOD::numberOfBLayerOutliers); - - if(expectBlayer && (nBlayerHits+nBlayerOutliers) < 1) return false; - else return true; - -} - -bool ElectronLikelihoodMC15::passTTVACuts(const xAOD::Electron& el) const -{ + bool ElectronLikelihoodMC15::passBLayerCuts(const xAOD::Electron& el) const { - // TTVA: - // see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TrackingCPEOYE2015#Track_to_Vertex_Association - if( !el.isAvailable<float>("d0sig") ){ - std::cout << "d0 significance not found for electron. " - << "Maybe no primary vertex? Won't accept." << std::endl; - return false; + const xAOD::TrackParticle* t = el.trackParticle(); + return ElectronSelectorHelpers::passBLayerRequirement(t); } - - float d0sig = el.auxdataConst<float>("d0sig"); - if( std::abs(d0sig) >= 5 ) - return false; - - if( !el.isAvailable<float>("delta_z0_sintheta") ){ - std::cout << "delta z0*sin(theta) not found for electron. " - << "Maybe no primary vertex? Won't accept." << std::endl; - return false; + + bool ElectronLikelihoodMC15::passTTVACuts(const xAOD::Electron& el) const { + // TTVA: + // see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TrackingCPEOYE2015#Track_to_Vertex_Association + if (!el.isAvailable<float>("d0sig")) { + ATH_MSG_WARNING("d0 significance not found for electron. Maybe no primary vertex? Won't accept."); + return false; + } + + float d0sig = el.auxdataConst<float>("d0sig"); + if (std::abs(d0sig) >= 5) return false; + + if (!el.isAvailable<float>("delta_z0_sintheta")) { + ATH_MSG_WARNING("delta z0*sin(theta) not found for electron. Maybe no primary vertex? Won't accept."); + return false; + } + + float delta_z0_sintheta = el.auxdataConst<float>("delta_z0_sintheta"); + if (std::abs(delta_z0_sintheta) >= 0.5) return false; + + return true; } - - float delta_z0_sintheta = el.auxdataConst<float>("delta_z0_sintheta"); - if( std::abs(delta_z0_sintheta) >= 0.5 ) - return false; - - return true; - -} -bool ElectronLikelihoodMC15::passChargeIDCut(const xAOD::Electron& el) const -{ + bool ElectronLikelihoodMC15::passChargeIDCut(const xAOD::Electron& el) const { + static const SG::AuxElement::ConstAccessor<char> acc_ECIDS("DFCommonElectronsECIDS"); - // Electron Charge ID Selector Tool - // see https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/ElectronChargeFlipTaggerTool - if ( asg::ToolStore::contains<AsgElectronChargeIDSelectorTool> ("ECIDS_medium") ) { - AsgElectronChargeIDSelectorTool* electronChargeIDSelectorTool = asg::ToolStore::get<AsgElectronChargeIDSelectorTool> ("ECIDS_medium"); - if (!electronChargeIDSelectorTool->accept(el)) return false; + top::check(acc_ECIDS.isAvailable( + el), "ElectronLikelihoodMC15::passChargeIDCut: DFCommonElectronsECIDS is not available"); + return acc_ECIDS(el) ? true : false; } - return true; -} void ElectronLikelihoodMC15::print(std::ostream& os) const { - os << "ElectronLikelihoodMC15\n"; - os << " * pT > " << m_ptcut << "\n"; - os << " * Currently disabled --- |cluster_eta| < 2.47 \n"; - os << " * Veto 1.37 < |cluster_eta| < 1.52? " << std::boolalpha << m_vetoCrack << "\n"; - if (!m_isolation) { - os << " * No isolation requirement\n"; - } else { - m_isolation->print(os); - } - os << " * LH Tool Operating Point: " << m_operatingPoint_DF << " \t\t LH Tool Loose Operating Point: " <<m_operatingPointLoose_DF << " \n"; + os << "ElectronLikelihoodMC15\n"; + os << " * pT > " << m_ptcut << "\n"; + os << " * Currently disabled --- |cluster_eta| < 2.47 \n"; + os << " * Veto 1.37 < |cluster_eta| < 1.52? " << std::boolalpha << m_vetoCrack << "\n"; + if (!m_isolation) { + os << " * No isolation requirement\n"; + } else { + m_isolation->print(os); + } + os << " * LH Tool Operating Point: " << m_operatingPoint_DF << " \t\t LH Tool Loose Operating Point: " << + m_operatingPointLoose_DF << " \n"; } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronSelectionBase.cxx index a4aed6c324cf..0c9df9486517 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronSelectionBase.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/ElectronSelectionBase.cxx @@ -1,22 +1,20 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/ElectronSelectionBase.h" #include <iostream> namespace top { + ElectronSelectionBase::ElectronSelectionBase() { + } -ElectronSelectionBase::ElectronSelectionBase() { -} - -ElectronSelectionBase::~ElectronSelectionBase() { -} - -} + ElectronSelectionBase::~ElectronSelectionBase() { + } -std::ostream& operator<<(std::ostream& os, const top::ElectronSelectionBase& selection) { + std::ostream& operator << (std::ostream& os, const top::ElectronSelectionBase& selection) { selection.print(os); return os; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/EventCleaningSelection.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/EventCleaningSelection.cxx index f5c228878c0e..ab04baaeb8ca 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/EventCleaningSelection.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/EventCleaningSelection.cxx @@ -1,8 +1,7 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ -// $Id: EventCleaningSelection.cxx 802748 2017-04-11 20:29:03Z iconnell $ #include "TopObjectSelectionTools/EventCleaningSelection.h" #include "TopEvent/EventTools.h" #include "TopConfiguration/TopConfig.h" @@ -13,15 +12,17 @@ #include "xAODMuon/MuonContainer.h" #include "xAODTau/TauJetContainer.h" #include "xAODTracking/VertexContainer.h" +//#include "TrigGlobalEfficiencyCorrection/ImportData.h" +#include <algorithm> #include <sstream> #include <list> +#include <boost/algorithm/string.hpp> namespace top { - - EventCleaningSelection::EventCleaningSelection( const std::string& name ) : - asg::AsgTool( name ), + EventCleaningSelection::EventCleaningSelection(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), m_grlTool("GoodRunsListSelectionTool"), @@ -30,99 +31,288 @@ namespace top { m_trigDecisionTool("Trig::TrigDecisionTool"), m_trigMatchTool("Trig::MatchingTool"), m_trigMatchTauTool("Trig::TrigTauMatchingTool"), + m_globalTriggerSF("TrigGlobalEfficiencyCorrectionTool::TrigGlobal"), + m_globalTriggerSFLoose("TrigGlobalEfficiencyCorrectionTool::TrigGlobalLoose"), m_vetoEventsTrigger(false), m_vetoEventsGRL(false), m_vetoEventsGoodCalo(false), - m_vetoEventsPriVtx(false) { - declareProperty( "config" , m_config ); + m_vetoEventsPriVtx(true) { + declareProperty("config", m_config); - declareProperty( "GRLTool" , m_grlTool ); + declareProperty("GRLTool", m_grlTool); - declareProperty( "TrigConfigTool", m_trigConfTool ); - declareProperty( "TrigDecisionTool", m_trigDecisionTool ); - declareProperty( "TrigMatchTool", m_trigMatchTool ); - declareProperty( "TrigMatchTauTool" , m_trigMatchTauTool ); + declareProperty("TrigConfigTool", m_trigConfTool); + declareProperty("TrigDecisionTool", m_trigDecisionTool); + declareProperty("TrigMatchTool", m_trigMatchTool); + declareProperty("TrigMatchTauTool", m_trigMatchTauTool); } - StatusCode EventCleaningSelection::initilize() - { + StatusCode EventCleaningSelection::initialize() { // If running on a Truth DxAOD we don't need anything so // just return successfully... if (m_config->isTruthDxAOD()) return StatusCode::SUCCESS; - top::check( m_trigConfTool.retrieve() , "Failed to retrieve TrigConfTool" ); - top::check( m_trigDecisionTool.retrieve() , "Failed to retrieve TrigDecisionTool" ); - top::check( m_trigMatchTool.retrieve(), - "Failed to retrieve trigger matching tool"); - if (m_config->useTaus()) - top::check(m_trigMatchTauTool.retrieve(), - "Failed to retrieve TrigMatchTauTool" ); + top::check(m_trigConfTool.retrieve(), "Failed to retrieve TrigConfTool"); + top::check(m_trigDecisionTool.retrieve(), "Failed to retrieve TrigDecisionTool"); + top::check(m_trigMatchTool.retrieve(), + "Failed to retrieve trigger matching tool"); + if (m_config->useTaus()) top::check(m_trigMatchTauTool.retrieve(), + "Failed to retrieve TrigMatchTauTool"); if (!m_config->isMC()) { - top::check( m_grlTool.retrieve() , "Failed to retrieve TrigDecisionTool" ); + top::check(m_grlTool.retrieve(), "Failed to retrieve TrigDecisionTool"); } + m_vetoEventsPriVtx = m_config->demandPriVtx(); + return StatusCode::SUCCESS; } - void EventCleaningSelection::setEventSelections( const std::vector<top::SelectionConfigurationData>& selections ) - { - std::list<std::string> tmpAllTriggers; + void EventCleaningSelection::setEventSelections(const std::vector<top::SelectionConfigurationData>& selections) { + std::unordered_set<std::string> tmpAllTriggers_Tight; + std::unordered_set<std::string> tmpAllTriggers_Loose; + + // get full list of global triggers + std::vector<std::string> globalTriggers_Tight; + std::vector<std::string> globalTriggers_Loose; + std::vector<std::string> globalElectronTriggers_Tight; + std::vector<std::string> globalElectronTriggers_Loose; + std::vector<std::string> globalMuonTriggers_Tight; + std::vector<std::string> globalMuonTriggers_Loose; + if (m_config->useGlobalTrigger()) { + std::set<std::string> tmp; + for (auto const& triggermap : {m_config->getGlobalTriggers()}) { + for (auto const& pair : triggermap) { + auto const& triggers = getIndividualFromGlobalTriggers(pair.second); + tmp.insert(triggers.begin(), triggers.end()); + } + } + globalTriggers_Tight.assign(tmp.begin(), tmp.end()); + for (std::string const& trigger : globalTriggers_Tight) { + if (isElectronTrigger(trigger)) globalElectronTriggers_Tight.push_back(trigger); + if (isMuonTrigger(trigger)) globalMuonTriggers_Tight.push_back(trigger); + } + tmp.clear(); + // and the usual copy-paste-s/Tight/Loose/g story: + for (auto const& triggermap : {m_config->getGlobalTriggersLoose()}) { + for (auto const& pair : triggermap) { + auto const& triggers = getIndividualFromGlobalTriggers(pair.second); + tmp.insert(triggers.begin(), triggers.end()); + } + } + globalTriggers_Loose.assign(tmp.begin(), tmp.end()); + for (std::string const& trigger : globalTriggers_Loose) { + if (isElectronTrigger(trigger)) globalElectronTriggers_Loose.push_back(trigger); + if (isMuonTrigger(trigger)) globalMuonTriggers_Loose.push_back(trigger); + } + } - m_allTriggers.clear(); - m_electronTriggers.clear(); - m_muonTriggers.clear(); - m_tauTriggers.clear(); + m_allTriggers_Tight.clear(); + m_electronTriggers_Tight.clear(); + m_muonTriggers_Tight.clear(); + m_tauTriggers_Tight.clear(); + m_allTriggers_Loose.clear(); + m_electronTriggers_Loose.clear(); + m_muonTriggers_Loose.clear(); + m_tauTriggers_Loose.clear(); // Trigger maps for TopConfig - to be used by individual selectors - std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> allTriggers_perSelector - ( new std::unordered_map<std::string,std::vector<std::string>> ); - - std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> electronTriggers_perSelector - ( new std::unordered_map<std::string,std::vector<std::string>> ); - - std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> muonTriggers_perSelector - ( new std::unordered_map<std::string,std::vector<std::string>> ); - - std::shared_ptr<std::unordered_map<std::string,std::vector<std::string>>> tauTriggers_perSelector - ( new std::unordered_map<std::string,std::vector<std::string>> ); + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > allTriggers_perSelector_Tight + (new std::unordered_map<std::string, std::vector<std::string> > ); + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > electronTriggers_perSelector_Tight + (new std::unordered_map<std::string, std::vector<std::string> > ); + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > muonTriggers_perSelector_Tight + (new std::unordered_map<std::string, std::vector<std::string> > ); + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > tauTriggers_perSelector_Tight + (new std::unordered_map<std::string, std::vector<std::string> > ); + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > allTriggers_perSelector_Loose + (new std::unordered_map<std::string, std::vector<std::string> > ); + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > electronTriggers_perSelector_Loose + (new std::unordered_map<std::string, std::vector<std::string> > ); + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > muonTriggers_perSelector_Loose + (new std::unordered_map<std::string, std::vector<std::string> > ); + std::shared_ptr<std::unordered_map<std::string, std::vector<std::string> > > tauTriggers_perSelector_Loose + (new std::unordered_map<std::string, std::vector<std::string> > ); // Loop over all selections m_vetoEventsTrigger = true; m_vetoEventsGRL = true; m_vetoEventsGoodCalo = true; - m_vetoEventsPriVtx = true; for (auto sel : selections) { - - std::list<std::string> listAllTriggers_thisSelector; - std::vector<std::string> allTriggers_thisSelector; - std::vector<std::string> electronTriggers_thisSelector; - std::vector<std::string> muonTriggers_thisSelector; - std::vector<std::string> tauTriggers_thisSelector; + std::list<std::string> listAllTriggers_thisSelector_Tight; + std::vector<std::string> allTriggers_thisSelector_Tight; + std::vector<std::string> electronTriggers_thisSelector_Tight; + std::vector<std::string> muonTriggers_thisSelector_Tight; + std::vector<std::string> tauTriggers_thisSelector_Tight; + std::list<std::string> listAllTriggers_thisSelector_Loose; + std::vector<std::string> allTriggers_thisSelector_Loose; + std::vector<std::string> electronTriggers_thisSelector_Loose; + std::vector<std::string> muonTriggers_thisSelector_Loose; + std::vector<std::string> tauTriggers_thisSelector_Loose; // Loop over cut names and look for TRIGDEC, GRL, GOODCALO, PRIVTX - bool selectionHasTriggerCut(false),selectionHasGRLCut(false); - bool selectionHasGOODCALOCut(false),selectionHasPRIVTXCut(false); - for (auto cut : sel.m_cutnames) { - - if (cut.find("GRL") != std::string::npos) { + bool selectionHasTriggerCut(false); + bool selectionHasTriggerCut_Tight(false); + bool selectionHasTriggerCut_Loose(false); + bool selectionHasGRLCut(false); + bool selectionHasGOODCALOCut(false); + for (std::string cut : sel.m_cutnames) { + using boost::algorithm::starts_with; + cut.append(" "); + + if (starts_with(cut, "GRL ")) { selectionHasGRLCut = true; } - if (cut.find("GOODCALO") != std::string::npos) { + if (starts_with(cut, "GOODCALO ")) { selectionHasGOODCALOCut = true; } - if (cut.find("PRIVTX") != std::string::npos) { - selectionHasPRIVTXCut = true; + if (starts_with(cut, "GTRIGDEC ")) { + if (selectionHasTriggerCut || selectionHasTriggerCut_Loose || selectionHasTriggerCut_Tight) { + throw std::runtime_error("You have multiple TRIGDEC selectors for selection " + + sel.m_name + ". Only one per selection is allowed."); + } + if (!m_config->useGlobalTrigger()) { + throw std::runtime_error("The GTRIGDEC selector cannot be used without UseGlobalLeptonTriggerSF option."); + } + selectionHasTriggerCut = true; + allTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, + std::vector<std::string>(globalTriggers_Tight.begin(), + globalTriggers_Tight.end()))); + allTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, + std::vector<std::string>(globalTriggers_Loose.begin(), + globalTriggers_Loose.end()))); + electronTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, + std::vector<std::string>( + globalElectronTriggers_Tight.begin(), + globalElectronTriggers_Tight.end()))); + electronTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, + std::vector<std::string>( + globalElectronTriggers_Loose.begin(), + globalElectronTriggers_Loose.end()))); + muonTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, + std::vector<std::string>(globalMuonTriggers_Tight.begin(), + globalMuonTriggers_Tight.end()))); + muonTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, + std::vector<std::string>(globalMuonTriggers_Loose.begin(), + globalMuonTriggers_Loose.end()))); } - if (cut.find("TRIGDEC") != std::string::npos) { + if (starts_with(cut, "TRIGDEC_TIGHT ")) { + if (selectionHasTriggerCut_Tight) { + throw std::runtime_error("You have multiple TRIGDEC_TIGHT selectors for selection " + + sel.m_name + ". Only one per selection is allowed."); + } + if (selectionHasTriggerCut) { + throw std::runtime_error("Both TRIGDEC and TRIGDEC_TIGHT selectors used for selection " + + sel.m_name + ". Only one of the two per selection is allowed."); + } + selectionHasTriggerCut_Tight = true; + ATH_MSG_INFO("Tight Triggers for Selection \t" << sel.m_name << "\tare " << cut); + + //split the trigger string at spaces + std::stringstream ss(cut); + std::string item; + char delim = ' '; + while (std::getline(ss, item, delim)) { + if (item.size() > 0 && item.find("TRIGDEC_TIGHT") == std::string::npos) { + tmpAllTriggers_Tight.insert(item); + listAllTriggers_thisSelector_Tight.push_back(item); + } + } + listAllTriggers_thisSelector_Tight.sort(); + listAllTriggers_thisSelector_Tight.unique(); + + // Turn list into vector + for (auto trigger : listAllTriggers_thisSelector_Tight) { + allTriggers_thisSelector_Tight.push_back(trigger); + } + + // Split triggers into electron, muon and tau + for (const auto& trigger : allTriggers_thisSelector_Tight) { + if (isElectronTrigger(trigger)) { + electronTriggers_thisSelector_Tight.push_back(trigger); + } + if (isMuonTrigger(trigger)) { + muonTriggers_thisSelector_Tight.push_back(trigger); + } + if ((trigger.find("_tau") != std::string::npos)) { + tauTriggers_thisSelector_Tight.push_back(trigger); + } + } + + allTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, allTriggers_thisSelector_Tight)); + electronTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, electronTriggers_thisSelector_Tight)); + muonTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, muonTriggers_thisSelector_Tight)); + tauTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, tauTriggers_thisSelector_Tight)); + } // Cut requested is TRIGDEC_TIGHT + else if (starts_with(cut, "TRIGDEC_LOOSE ")) { + if (selectionHasTriggerCut_Loose) { + throw std::runtime_error("You have multiple TRIGDEC_LOOSE selectors for selection " + + sel.m_name + ". Only one per selection is allowed."); + } + if (selectionHasTriggerCut) { + throw std::runtime_error("Both TRIGDEC and TRIGDEC_LOOSE selectors used for selection " + + sel.m_name + ". Only one of the two per selection is allowed."); + } + selectionHasTriggerCut_Loose = true; + ATH_MSG_INFO("Loose Triggers for Selection \t" << sel.m_name << "\tare " << cut); + + //split the trigger string at spaces + std::stringstream ss(cut); + std::string item; + char delim = ' '; + while (std::getline(ss, item, delim)) { + if (item.size() > 0 && item.find("TRIGDEC_LOOSE") == std::string::npos) { + tmpAllTriggers_Loose.insert(item); + listAllTriggers_thisSelector_Loose.push_back(item); + } + } + listAllTriggers_thisSelector_Loose.sort(); + listAllTriggers_thisSelector_Loose.unique(); + + // Turn list into vector + for (auto trigger : listAllTriggers_thisSelector_Loose) { + allTriggers_thisSelector_Loose.push_back(trigger); + } + + // Split triggers into electron, muon and tau + for (const auto& trigger : allTriggers_thisSelector_Loose) { + if (isElectronTrigger(trigger)) { + electronTriggers_thisSelector_Loose.push_back(trigger); + } + if (isMuonTrigger(trigger)) { + muonTriggers_thisSelector_Loose.push_back(trigger); + } + if ((trigger.find("_tau") != std::string::npos)) { + tauTriggers_thisSelector_Loose.push_back(trigger); + } + } + + allTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, allTriggers_thisSelector_Loose)); + electronTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, electronTriggers_thisSelector_Loose)); + muonTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, muonTriggers_thisSelector_Loose)); + tauTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, tauTriggers_thisSelector_Loose)); + } // Cut requested is TRIGDEC_LOOSE + else if (starts_with(cut, "TRIGDEC ")) { + if (selectionHasTriggerCut) { + throw std::runtime_error("GTRIGDEC/TRIGDEC already used for selection " + + sel.m_name + ". Cannot be used multiple times."); + } + if (selectionHasTriggerCut_Tight) { + throw std::runtime_error("Both TRIGDEC and TRIGDEC_TIGHT already used for selection " + + sel.m_name + ". Cannot be used simultaneously."); + } + if (selectionHasTriggerCut_Loose) { + throw std::runtime_error("Both TRIGDEC and TRIGDEC_LOOSE already used for selection " + + sel.m_name + ". Cannot be used simultaneously."); + } selectionHasTriggerCut = true; - ATH_MSG_INFO("Triggers for Selection \t"<<sel.m_name<<"\tare "<<cut); + ATH_MSG_INFO("Triggers for Selection \t" << sel.m_name << "\tare " << cut); //split the trigger string at spaces std::stringstream ss(cut); @@ -130,37 +320,58 @@ namespace top { char delim = ' '; while (std::getline(ss, item, delim)) { if (item.size() > 0 && item.find("TRIGDEC") == std::string::npos) { - tmpAllTriggers.push_back(item); - listAllTriggers_thisSelector.push_back(item); + tmpAllTriggers_Tight.insert(item); + listAllTriggers_thisSelector_Tight.push_back(item); + tmpAllTriggers_Loose.insert(item); + listAllTriggers_thisSelector_Loose.push_back(item); } } - tmpAllTriggers.sort(); - tmpAllTriggers.unique(); - listAllTriggers_thisSelector.sort(); - listAllTriggers_thisSelector.unique(); + listAllTriggers_thisSelector_Tight.sort(); + listAllTriggers_thisSelector_Tight.unique(); + listAllTriggers_thisSelector_Loose.sort(); + listAllTriggers_thisSelector_Loose.unique(); // Turn list into vector - for (auto trigger : listAllTriggers_thisSelector) { - allTriggers_thisSelector.push_back( trigger ); + for (auto trigger : listAllTriggers_thisSelector_Tight) { + allTriggers_thisSelector_Tight.push_back(trigger); + } + for (auto trigger : listAllTriggers_thisSelector_Loose) { + allTriggers_thisSelector_Loose.push_back(trigger); } // Split triggers into electron, muon and tau - for (const auto& trigger : allTriggers_thisSelector) { - if ( (trigger.find("HLT_e") != std::string::npos) || (trigger.find("HLT_2e") != std::string::npos) ) { - electronTriggers_thisSelector.push_back(trigger); + for (const auto& trigger : allTriggers_thisSelector_Tight) { + if (isElectronTrigger(trigger)) { + electronTriggers_thisSelector_Tight.push_back(trigger); + } + if (isMuonTrigger(trigger)) { + muonTriggers_thisSelector_Tight.push_back(trigger); + } + if ((trigger.find("_tau") != std::string::npos)) { + tauTriggers_thisSelector_Tight.push_back(trigger); } - if ( (trigger.find("HLT_mu") != std::string::npos) || (trigger.find("HLT_2mu") != std::string::npos) || (trigger.find("_mu") != std::string::npos) ) { - muonTriggers_thisSelector.push_back(trigger); + } + + for (const auto& trigger : allTriggers_thisSelector_Loose) { + if (isElectronTrigger(trigger)) { + electronTriggers_thisSelector_Loose.push_back(trigger); } - if ( (trigger.find("_tau") != std::string::npos) ) { - tauTriggers_thisSelector.push_back(trigger); + if (isMuonTrigger(trigger)) { + muonTriggers_thisSelector_Loose.push_back(trigger); + } + if ((trigger.find("_tau") != std::string::npos)) { + tauTriggers_thisSelector_Loose.push_back(trigger); } } - allTriggers_perSelector->insert( std::make_pair( sel.m_name , allTriggers_thisSelector ) ); - electronTriggers_perSelector->insert( std::make_pair( sel.m_name , electronTriggers_thisSelector ) ); - muonTriggers_perSelector->insert( std::make_pair( sel.m_name , muonTriggers_thisSelector ) ); - tauTriggers_perSelector->insert( std::make_pair( sel.m_name , tauTriggers_thisSelector ) ); + allTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, allTriggers_thisSelector_Tight)); + electronTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, electronTriggers_thisSelector_Tight)); + muonTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, muonTriggers_thisSelector_Tight)); + tauTriggers_perSelector_Tight->insert(std::make_pair(sel.m_name, tauTriggers_thisSelector_Tight)); + allTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, allTriggers_thisSelector_Loose)); + electronTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, electronTriggers_thisSelector_Loose)); + muonTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, muonTriggers_thisSelector_Loose)); + tauTriggers_perSelector_Loose->insert(std::make_pair(sel.m_name, tauTriggers_thisSelector_Loose)); } // Cut requested is TRIGDEC } // Loop over all cuts @@ -172,50 +383,77 @@ namespace top { m_vetoEventsGoodCalo = false; } - if (!selectionHasPRIVTXCut) { - m_vetoEventsPriVtx = false; - } - if (!selectionHasTriggerCut) { m_vetoEventsTrigger = false; - ATH_MSG_INFO("Selection "<<sel.m_name<<" Does not request a trigger. No event veto will be applied"); + ATH_MSG_INFO("Selection " << sel.m_name << " Does not request a trigger. No event veto will be applied"); } } // Loop over all selections + // Add triggers configured for the global trigger SF tool + tmpAllTriggers_Tight.insert(globalTriggers_Tight.begin(), globalTriggers_Tight.end()); + tmpAllTriggers_Loose.insert(globalTriggers_Loose.begin(), globalTriggers_Loose.end()); + // Turn list into vector - for (auto trigger : tmpAllTriggers) { - m_allTriggers.push_back( trigger ); + { + std::vector<std::string> tmp; + tmp.assign(tmpAllTriggers_Tight.begin(), tmpAllTriggers_Tight.end()); + std::sort(tmp.begin(), tmp.end()); + m_allTriggers_Tight.swap(tmp); + tmp.clear(); + tmp.assign(tmpAllTriggers_Loose.begin(), tmpAllTriggers_Loose.end()); + std::sort(tmp.begin(), tmp.end()); + m_allTriggers_Loose.swap(tmp); } - ATH_MSG_INFO("All requested triggers are:"); - for (const auto& trigger : m_allTriggers) { - ATH_MSG_INFO(" "<<trigger); + ATH_MSG_INFO("All requested Tight triggers are:"); + for (const auto& trigger : m_allTriggers_Tight) { + ATH_MSG_INFO(" " << trigger); + } + ATH_MSG_INFO("All requested Loose triggers are:"); + for (const auto& trigger : m_allTriggers_Loose) { + ATH_MSG_INFO(" " << trigger); } std::string outputInfoString("True"); if (!m_vetoEventsTrigger) { outputInfoString = "False"; } - ATH_MSG_INFO("Apply event veto on trigger decision = "<<outputInfoString); + ATH_MSG_INFO("Apply event veto on trigger decision = " << outputInfoString); // Split triggers into electron, muon and tau - for (const auto& trigger : m_allTriggers) { - if ( (trigger.find("HLT_e") != std::string::npos) || (trigger.find("HLT_2e") != std::string::npos) ) { - m_electronTriggers.push_back(trigger); + for (const auto& trigger : m_allTriggers_Tight) { + if (isElectronTrigger(trigger)) { + m_electronTriggers_Tight.push_back(trigger); } - if ( (trigger.find("HLT_mu") != std::string::npos) || (trigger.find("HLT_2mu") != std::string::npos) || (trigger.find("_mu") != std::string::npos) ) { - m_muonTriggers.push_back(trigger); + if (isMuonTrigger(trigger)) { + m_muonTriggers_Tight.push_back(trigger); } - if ( (trigger.find("_tau") != std::string::npos) ) { - m_tauTriggers.push_back(trigger); + if ((trigger.find("_tau") != std::string::npos)) { + m_tauTriggers_Tight.push_back(trigger); + } + } + // Split triggers into electron, muon and tau + for (const auto& trigger : m_allTriggers_Loose) { + if (isElectronTrigger(trigger)) { + m_electronTriggers_Loose.push_back(trigger); + } + if (isMuonTrigger(trigger)) { + m_muonTriggers_Loose.push_back(trigger); + } + if ((trigger.find("_tau") != std::string::npos)) { + m_tauTriggers_Loose.push_back(trigger); } } // Tell TopConfig about the triggers - m_config->allTriggers( allTriggers_perSelector ); - m_config->electronTriggers( electronTriggers_perSelector ); - m_config->muonTriggers( muonTriggers_perSelector ); - m_config->tauTriggers( tauTriggers_perSelector ); + m_config->allTriggers_Tight(allTriggers_perSelector_Tight); + m_config->electronTriggers_Tight(electronTriggers_perSelector_Tight); + m_config->muonTriggers_Tight(muonTriggers_perSelector_Tight); + m_config->tauTriggers_Tight(tauTriggers_perSelector_Tight); + m_config->allTriggers_Loose(allTriggers_perSelector_Loose); + m_config->electronTriggers_Loose(electronTriggers_perSelector_Loose); + m_config->muonTriggers_Loose(muonTriggers_perSelector_Loose); + m_config->tauTriggers_Loose(tauTriggers_perSelector_Loose); // If the user has requested that all events are saved, then we'd better turn off the vetos if (!m_config->saveOnlySelectedEvents()) { @@ -223,22 +461,21 @@ namespace top { m_vetoEventsGoodCalo = false; m_vetoEventsTrigger = false; } - } - bool EventCleaningSelection::applyGRL() const - { + bool EventCleaningSelection::applyGRL() const { const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo,m_config->sgKeyEventInfo()),"Failed to retrieve EventInfo"); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); ///-- Apply GRL to data --/// char passGRL(1); if (!m_config->isMC() && asg::ToolStore::contains<IGoodRunsListSelectionTool> ("GoodRunsListSelectionTool")) { - if (!m_grlTool->passRunLB( *eventInfo )) { + if (!m_grlTool->passRunLB(*eventInfo)) { passGRL = 0; } } - eventInfo->auxdecor<char>("AnalysisTop_GRL") = passGRL; + eventInfo->auxdecor<char>("AnalysisTop_GRL") = passGRL; // Do we veto events? Only if ALL selectors request GRL and GRL fails if (m_vetoEventsGRL) { @@ -254,10 +491,10 @@ namespace top { return true; } - bool EventCleaningSelection::applyGoodCalo() const - { + bool EventCleaningSelection::applyGoodCalo() const { const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo,m_config->sgKeyEventInfo()),"Failed to retrieve EventInfo"); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); ///-- Apply GoodCalo tests to data --/// ///-- https://twiki.cern.ch/twiki/bin/view/AtlasProtected/PhysicsAnalysisWorkBookRel20CPRec --/// @@ -266,12 +503,12 @@ namespace top { bool badTile(false), badLAr(false), badSCT(false), incompleteEvent(false); ///-- Remove bad events due to problems in TileCal --/// - if (eventInfo->errorState(xAOD::EventInfo::Tile)==xAOD::EventInfo::Error) { + if (eventInfo->errorState(xAOD::EventInfo::Tile) == xAOD::EventInfo::Error) { badTile = true; } ///-- Remove bad events due to problems in LAr --/// - if (eventInfo->errorState(xAOD::EventInfo::LAr)==xAOD::EventInfo::Error) { + if (eventInfo->errorState(xAOD::EventInfo::LAr) == xAOD::EventInfo::Error) { badLAr = true; } @@ -289,13 +526,13 @@ namespace top { passGoodCalo = 0; } } - eventInfo->auxdecor<char>("AnalysisTop_GOODCALO") = passGoodCalo; + eventInfo->auxdecor<char>("AnalysisTop_GOODCALO") = passGoodCalo; // Do we veto events? Only if ALL selectors request GOODCALO and GOODCALO fails if (m_vetoEventsGoodCalo) { if (passGoodCalo == 1) { return true; - } + } if (passGoodCalo == 0) { return false; } @@ -305,14 +542,14 @@ namespace top { return true; } - bool EventCleaningSelection::applyPrimaryVertex() const - { + bool EventCleaningSelection::applyPrimaryVertex() const { ///-- https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/InDetTrackingPerformanceGuidelines#Vertexing --/// const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo,m_config->sgKeyEventInfo()),"Failed to retrieve EventInfo"); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); const xAOD::VertexContainer* vertices(nullptr); - top::check(evtStore()->retrieve(vertices,m_config->sgKeyPrimaryVertices()), "Failed to retrieve Primary Vertices"); + top::check(evtStore()->retrieve(vertices, m_config->sgKeyPrimaryVertices()), "Failed to retrieve Primary Vertices"); char passPriVtx(0); float pri_vtx_z(0); @@ -320,13 +557,12 @@ namespace top { for (auto vtx : *vertices) { if (vtx->vertexType() == xAOD::VxType::PriVtx) { passPriVtx = 1; - pri_vtx_z = vtx->z(); + pri_vtx_z = vtx->z(); break; // No need to loop over all vertices, we only need one } } eventInfo->auxdecor<char>("AnalysisTop_PRIVTX") = passPriVtx; - if( passPriVtx == 1 ) - eventInfo->auxdecor<float>("AnalysisTop_PRIVTX_z_position") = pri_vtx_z; + if (passPriVtx == 1) eventInfo->auxdecor<float>("AnalysisTop_PRIVTX_z_position") = pri_vtx_z; // Do we veto events? Only if ALL selectors request PRIVTX and PRIVTX fails if (m_vetoEventsPriVtx) { @@ -342,25 +578,27 @@ namespace top { return true; } - bool EventCleaningSelection::applyTrigger() - { + bool EventCleaningSelection::applyTrigger() { const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo,m_config->sgKeyEventInfo()),"Failed to retrieve EventInfo"); + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); bool orOfAllTriggers(false); - for (const auto& trigger : m_allTriggers) { + std::unordered_set<std::string> triggers; + triggers.insert(m_allTriggers_Tight.begin(), m_allTriggers_Tight.end()); + triggers.insert(m_allTriggers_Loose.begin(), m_allTriggers_Loose.end()); + for (const auto& trigger : triggers) { //decorating event with trigger decision - bool passThisTrigger = m_trigDecisionTool->isPassed(trigger); + bool passThisTrigger = m_trigDecisionTool->isPassed(trigger); char decoration = passThisTrigger ? 1 : 0; - eventInfo->auxdecor<char>( "TRIGDEC_" + trigger ) = decoration; + eventInfo->auxdecor<char>("TRIGDEC_" + trigger) = decoration; orOfAllTriggers |= passThisTrigger; //decorating event with trigger prescale (on Data) if (!m_config->isMC()) { auto cg = m_trigDecisionTool->getChainGroup(trigger); float prescale = cg->getPrescale(); - eventInfo->auxdecor<float>( "TRIGPS_" + trigger ) = prescale; + eventInfo->auxdecor<float>("TRIGPS_" + trigger) = prescale; } } @@ -371,82 +609,102 @@ namespace top { // Do we veto events? Only if ALL selectors request TRIGDEC and no trigger passes if (m_vetoEventsTrigger) { - return orOfAllTriggers; + return orOfAllTriggers; } // otherwise, we don't veto the event return true; } - void EventCleaningSelection::matchElectrons() - { + void EventCleaningSelection::matchElectrons() { const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo,m_config->sgKeyEventInfo()),"Failed to retrieve EventInfo"); - // Take muons from input file. Decorate these before doing any calibration/shallow copies + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); + + // Take electrons from input file. Decorate these before doing any calibration/shallow copies const xAOD::ElectronContainer* electrons(nullptr); - top::check(evtStore()->retrieve(electrons,m_config->sgKeyElectrons()),"Failed to retrieve electrons"); + if(m_config->useElectrons()) top::check(evtStore()->retrieve(electrons, m_config->sgKeyElectrons()), "Failed to retrieve electrons"); - // Loop over muons + // Loop over electrons + std::unordered_set<std::string> triggers; + triggers.insert(m_electronTriggers_Tight.begin(), m_electronTriggers_Tight.end()); + triggers.insert(m_electronTriggers_Loose.begin(), m_electronTriggers_Loose.end()); for (const auto* el : *electrons) { - // Loop over muon triggers - for (const auto& trigger : m_electronTriggers) { + // Loop over electron triggers + for (const auto& trigger : triggers) { bool match(false); // Match even if event fails trigger decistion - it's important in case of pre-scaled menus - if (el->isAvailable<char>(m_config->getDerivationStream() + "_" + trigger)) { - match = el->auxdataConst<char>( m_config->getDerivationStream() + "_" + trigger); + if (!m_config->useGlobalTrigger() && el->isAvailable<char>(m_config->getDerivationStream() + "_" + trigger)) { + match = el->auxdataConst<char>(m_config->getDerivationStream() + "_" + trigger); } else { match = m_trigMatchTool->match(*el, trigger); } char decoration = match ? 1 : 0; - el->auxdecor<char>("TRIGMATCH_" + trigger ) = decoration; + el->auxdecor<char>("TRIGMATCH_" + trigger) = decoration; } } } - void EventCleaningSelection::matchMuons() - { + void EventCleaningSelection::matchMuons() { const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo,m_config->sgKeyEventInfo()),"Failed to retrieve EventInfo"); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); // Take muons from input file. Decorate these before doing any calibration/shallow copies const xAOD::MuonContainer* muons(nullptr); - top::check(evtStore()->retrieve(muons,m_config->sgKeyMuons()),"Failed to retrieve muons"); + if(m_config->useMuons()) top::check(evtStore()->retrieve(muons, m_config->sgKeyMuons()), "Failed to retrieve muons in EventCleaningSelection::matchMuons() "); // Loop over muons + std::unordered_set<std::string> triggers; + triggers.insert(m_muonTriggers_Tight.begin(), m_muonTriggers_Tight.end()); + triggers.insert(m_muonTriggers_Loose.begin(), m_muonTriggers_Loose.end()); for (const auto* mu : *muons) { // Loop over muon triggers - for (const auto& trigger : m_muonTriggers) { + for (const auto& trigger : triggers) { bool match(false); // Match even if event fails trigger decistion - it's important in case of pre-scaled menus - if (mu->isAvailable<char>(m_config->getDerivationStream() + "_" + trigger)) { + if (!m_config->useGlobalTrigger() && mu->isAvailable<char>(m_config->getDerivationStream() + "_" + trigger)) { match = mu->auxdataConst<char>(m_config->getDerivationStream() + "_" + trigger); } else { match = m_trigMatchTool->match(*mu, trigger); } char decoration = match ? 1 : 0; - mu->auxdecor<char>("TRIGMATCH_" + trigger ) = decoration; + mu->auxdecor<char>("TRIGMATCH_" + trigger) = decoration; } } } - void EventCleaningSelection::matchTaus() - { - + void EventCleaningSelection::matchTaus() { const xAOD::EventInfo* eventInfo(nullptr); - top::check(evtStore()->retrieve(eventInfo,m_config->sgKeyEventInfo()), - "Failed to retrieve EventInfo"); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), + "Failed to retrieve EventInfo"); // Take taus from input file. // Decorate these before doing any calibration/shallow copies const xAOD::TauJetContainer* taus(nullptr); - top::check(evtStore()->retrieve(taus,m_config->sgKeyTaus()), - "Failed to retrieve taus"); + top::check(evtStore()->retrieve(taus, m_config->sgKeyTaus()), + "Failed to retrieve taus"); // Loop over taus for (const auto* tau : *taus) { // Loop over tau triggers - for (const auto& trigger : m_tauTriggers) { + for (const auto& trigger : m_tauTriggers_Tight) { + bool match(false); + // Match even if event fails trigger decistion - it's important in case of pre-scaled menus + match = m_trigMatchTauTool->match(tau, trigger); + if (tau->isAvailable<char>(m_config->getDerivationStream() + "_" + trigger)) { + match = tau->auxdataConst<char>(m_config->getDerivationStream() + "_" + trigger); + } else { + match = m_trigMatchTool->match(*tau, trigger); + } + char decoration = match ? 1 : 0; + tau->auxdecor<char>("TRIGMATCH_" + trigger) = decoration; + } + // Loop over tau triggers + for (const auto& trigger : m_tauTriggers_Loose) { + // let's make sure this isn't done twice + if (tau->isAvailable<char>("TRIGMATCH_" + trigger)) continue; bool match(false); // Match even if event fails trigger decistion - it's important in case of pre-scaled menus match = m_trigMatchTauTool->match(tau, trigger); @@ -456,23 +714,56 @@ namespace top { match = m_trigMatchTool->match(*tau, trigger); } char decoration = match ? 1 : 0; - tau->auxdecor<char>("TRIGMATCH_" + trigger ) = decoration; + tau->auxdecor<char>("TRIGMATCH_" + trigger) = decoration; } } } - void EventCleaningSelection::addExtraBranches( std::vector<std::string>& extraBranchList) { - - for (const auto& trigger : m_allTriggers) - extraBranchList.push_back( "TRIGDEC_" + trigger ); - + void EventCleaningSelection::addExtraBranches(std::vector<std::string>& extraBranchList) { + for (const auto& trigger : m_allTriggers_Tight) + extraBranchList.push_back("TRIGDEC_" + trigger); + for (const auto& trigger : m_allTriggers_Loose) { + if (std::find(extraBranchList.begin(), extraBranchList.end(), + std::string {"TRIGDEC_"} +trigger) == extraBranchList.end()) { // to not add them twice + extraBranchList.push_back("TRIGDEC_" + trigger); + } + } } - void EventCleaningSelection::printTriggers() const - { + void EventCleaningSelection::printTriggers() const { // printout all HLT chains // Debug only - this is very verbose - m_trigConfTool->chainList()->print("",10); + m_trigConfTool->chainList()->print("", 10); } + std::vector<std::string> EventCleaningSelection::getIndividualFromGlobalTriggers( + std::vector<std::string> const& triggers) { + std::vector<std::string> result; + std::string const delim("_OR_"); + for (std::string const& trigger : triggers) { + size_t cur = 0; + while (true) { + size_t next = trigger.find(delim, cur); + bool last = (next == std::string::npos); + result.emplace_back(std::string("HLT_") + trigger.substr(cur, (last ? std::string::npos : next - cur))); + if (last) break; + cur = next + delim.size(); + } + } + return result; + } + + bool EventCleaningSelection::isElectronTrigger(std::string const& trigger) const { + top::check(trigger.find("HLT_") == 0, "Expected trigger name to start with `HLT_'"); + bool success; + return true; + // return(TrigGlobEffCorr::ImportData::associatedLeptonFlavour(trigger.substr(4), success) == xAOD::Type::Electron); + } + + bool EventCleaningSelection::isMuonTrigger(std::string const& trigger) const { + top::check(trigger.find("HLT_") == 0, "Expected trigger name to start with `HLT_'"); + bool success; + return true; + //return(TrigGlobEffCorr::ImportData::associatedLeptonFlavour(trigger.substr(4), success) == xAOD::Type::Muon); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/FwdElectronSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/FwdElectronSelectionBase.cxx new file mode 100644 index 000000000000..050a440d01b5 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/FwdElectronSelectionBase.cxx @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopObjectSelectionTools/FwdElectronSelectionBase.h" + +#include <iostream> + +namespace top { + FwdElectronSelectionBase::FwdElectronSelectionBase() { + } + + FwdElectronSelectionBase::~FwdElectronSelectionBase() { + } + + std::ostream& operator << (std::ostream& os, const top::FwdElectronSelectionBase& selection) { + selection.print(os); + return os; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/IsolationTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/IsolationTools.cxx index 43345d31a4a4..ece125b44f9b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/IsolationTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/IsolationTools.cxx @@ -1,73 +1,69 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/IsolationTools.h" +#include "TopConfiguration/ConfigurationSettings.h" #include "TopEvent/EventTools.h" #include "xAODEgamma/Photon.h" #include "xAODEgamma/Electron.h" #include "xAODMuon/Muon.h" -namespace top { - -IsolationBase::IsolationBase() { -} +#include "TopObjectSelectionTools/MsgCategory.h" +using namespace TopObjectSelectionTools; -IsolationBase::~IsolationBase() { -} +namespace top { + IsolationBase::IsolationBase() { + } + IsolationBase::~IsolationBase() { + } -AbsoluteIsolationDC14::AbsoluteIsolationDC14(const xAOD::Iso::IsolationType type, double cutvalue) : - m_type(type), - m_cutvalue(cutvalue) { -} + AbsoluteIsolationDC14::AbsoluteIsolationDC14(const xAOD::Iso::IsolationType type, double cutvalue) : + m_type(type), + m_cutvalue(cutvalue) { + } -bool AbsoluteIsolationDC14::passSelection(const xAOD::IParticle& p) const { + bool AbsoluteIsolationDC14::passSelection(const xAOD::IParticle& p) const { //electrons if (p.type() == xAOD::Type::Electron) { - float iso = 0.; - const xAOD::Electron* el = dynamic_cast<const xAOD::Electron*>(&p); - bool exists = el->isolationValue(iso, m_type); - return exists && iso > m_cutvalue; + float iso = 0.; + const xAOD::Electron* el = dynamic_cast<const xAOD::Electron*>(&p); + bool exists = el->isolationValue(iso, m_type); + return exists && iso > m_cutvalue; } //muons if (p.type() == xAOD::Type::Muon) { - float iso = 0.; - const xAOD::Muon* mu = dynamic_cast<const xAOD::Muon*>(&p); - bool exists = mu->isolation(iso, m_type); - return exists && iso > m_cutvalue; + float iso = 0.; + const xAOD::Muon* mu = dynamic_cast<const xAOD::Muon*>(&p); + bool exists = mu->isolation(iso, m_type); + return exists && iso > m_cutvalue; } - std::cout << "IsolationDC14::Not an electron or muon" << std::endl; - exit(1); - - //should never happen (famous last words for a comment, no?) - return false; -} + throw std::runtime_error("TopObjectSelectionTools::IsolationTools::AbsoluteIsolationDC14: Not an electron or muon"); + } ///Implement me! -bool AbsoluteIsolationDC14::passSelectionLoose(const xAOD::IParticle& /*p*/) const { + bool AbsoluteIsolationDC14::passSelectionLoose(const xAOD::IParticle& /*p*/) const { return true; -} + } -void AbsoluteIsolationDC14::print(std::ostream& os) const { + void AbsoluteIsolationDC14::print(std::ostream& os) const { os << " * AbsoluteIsolationDC14\n"; os << " * " << m_type << " > " << m_cutvalue << " MeV\n"; - //missing in xaodprimities-00-00-02 os << " * " << xAOD::Iso::toString(m_type) << " > " << m_cutvalue << " MeV\n"; -} - - + //missing in xaodprimities-00-00-02 os << " * " << xAOD::Iso::toString(m_type) << " > " << m_cutvalue << " + // MeV\n"; + } -RelativePTVarCone::RelativePTVarCone(unsigned int size, double fraction, unsigned int sizeLoose, double fractionLoose) : + RelativePTVarCone::RelativePTVarCone(unsigned int size, double fraction, unsigned int sizeLoose, + double fractionLoose) : m_fraction(fraction), m_fractionLoose(fractionLoose) { - if (size != 20 && size != 30 && size != 40) { - std::cout << "ptvarcone only supports cone sizes of 20, 30, 40" << std::endl; - std::cout << "and you asked for " << size << ". why?" << std::endl; - exit(1); + throw std::runtime_error("TopObjectSelectionTools::IsolationTools::RelativePTVarCone: " + "ptvarcone only supports cone sizes of 20, 30, 40\n and you asked for " + std::to_string (size)); } std::stringstream ss; @@ -77,105 +73,123 @@ RelativePTVarCone::RelativePTVarCone(unsigned int size, double fraction, unsigne ss.str(""); ss << "ptvarcone" << sizeLoose; m_sizeLoose = ss.str(); -} + } -bool RelativePTVarCone::passSelection(const xAOD::IParticle& p) const { - return (p.auxdataConst<float>(m_size) / p.pt() < m_fraction); -} + bool RelativePTVarCone::passSelection(const xAOD::IParticle& p) const { + return(p.auxdataConst<float>(m_size) / p.pt() < m_fraction); + } -bool RelativePTVarCone::passSelectionLoose(const xAOD::IParticle& p) const { - return (p.auxdataConst<float>(m_sizeLoose) / p.pt() < m_fractionLoose); -} + bool RelativePTVarCone::passSelectionLoose(const xAOD::IParticle& p) const { + return(p.auxdataConst<float>(m_sizeLoose) / p.pt() < m_fractionLoose); + } -void RelativePTVarCone::print(std::ostream& os) const { + void RelativePTVarCone::print(std::ostream& os) const { os << " * RelativePTVarCone\n"; os << " * " << m_size << " /pT > " << m_fraction << "\n"; -} - + } -ApproxPTVarCone::ApproxPTVarCone(double fraction, double fractionLoose) : + ApproxPTVarCone::ApproxPTVarCone(double fraction, double fractionLoose) : m_fraction(fraction), m_fractionLoose(fractionLoose) { -} + } -bool ApproxPTVarCone::passSelection(const xAOD::IParticle& p) const { - return (p.auxdataConst<float>("miniIso") / p.pt() < m_fraction); -} + bool ApproxPTVarCone::passSelection(const xAOD::IParticle& p) const { + return(p.auxdataConst<float>("miniIso") / p.pt() < m_fraction); + } -bool ApproxPTVarCone::passSelectionLoose(const xAOD::IParticle& p) const { - return (p.auxdataConst<float>("miniIso") / p.pt() < m_fractionLoose); -} + bool ApproxPTVarCone::passSelectionLoose(const xAOD::IParticle& p) const { + return(p.auxdataConst<float>("miniIso") / p.pt() < m_fractionLoose); + } -void ApproxPTVarCone::print(std::ostream& os) const { + void ApproxPTVarCone::print(std::ostream& os) const { os << " * Approximate Mini Isolation\n"; os << " * iso/pT > " << m_fraction << "\n"; -} - - + } -StandardIsolation::StandardIsolation(const std::string& tightLeptonIsolation,const std::string& looseLeptonIsolation) : - m_tightLeptonDecoration("AnalysisTop_Isol_"+tightLeptonIsolation), - m_looseLeptonDecoration("AnalysisTop_Isol_"+looseLeptonIsolation), - m_doTightIsolation(true), - m_doLooseIsolation(true) -{ - if (tightLeptonIsolation == "None") - m_doTightIsolation = false; - - if (looseLeptonIsolation == "None") - m_doLooseIsolation = false; -} + StandardIsolation::StandardIsolation(const std::string& tightLeptonIsolation, + const std::string& looseLeptonIsolation) : + m_tightLeptonDecoration("AnalysisTop_Isol_" + tightLeptonIsolation), + m_looseLeptonDecoration("AnalysisTop_Isol_" + looseLeptonIsolation), + m_tightLeptonIsolation(tightLeptonIsolation), + m_looseLeptonIsolation(looseLeptonIsolation), + m_doTightIsolation(true), + m_doLooseIsolation(true), + m_doTightPromptLeptonIso(false), + m_doLoosePromptLeptonIso(false), + m_skipUnavailable(!ConfigurationSettings::get()->feature("AbortOnUnavailableIsolation")) { + if (tightLeptonIsolation == "PromptLepton") m_doTightPromptLeptonIso = true; + if (looseLeptonIsolation == "PromptLepton") m_doLoosePromptLeptonIso = true; + + if (tightLeptonIsolation == "None") m_doTightIsolation = false; + + if (looseLeptonIsolation == "None") m_doLooseIsolation = false; + } -bool StandardIsolation::passSelection(const xAOD::IParticle& p) const -{ - // Are we doing isolation? - if (!m_doTightIsolation) - return true; - - // If we get this far then we are doing isolation - if ( p.type() == xAOD::Type::Photon || - p.type() == xAOD::Type::Electron || - p.type() == xAOD::Type::Muon ) - { - if (p.isAvailable<char>(m_tightLeptonDecoration)) { - if (p.auxdataConst<char>(m_tightLeptonDecoration) == 1) { - return true; + bool StandardIsolation::passSelection(const xAOD::IParticle& p) const { + // Are we doing isolation? + if (!m_doTightIsolation) return true; + + // If we get this far then we are doing isolation + if (p.type() == xAOD::Type::Photon || + p.type() == xAOD::Type::Electron || + p.type() == xAOD::Type::Muon) { + if (!m_doTightPromptLeptonIso) { + if (!m_skipUnavailable || p.isAvailable<char>(m_tightLeptonDecoration)) { + if (p.auxdataConst<char>(m_tightLeptonDecoration) == 1) { + return true; + } + } + } else { + // Hardcoded a bit - With PLI we need to check that it passes Loose isolation AND passes the BDT cut + if (!m_skipUnavailable || + (p.isAvailable<char>(m_tightLeptonDecoration) && p.isAvailable<char>("AnalysisTop_Isol_Loose"))) { + if (p.auxdataConst<char>(m_tightLeptonDecoration) == 1 && + p.auxdataConst<char>("AnalysisTop_Isol_Loose") == 1) { + return true; + } + } } } + + // Not a photon, electron or muon? + // Didn't pass isolation? + return false; } - - // Not a photon, electron or muon? - // Didn't pass isolation? - return false; -} -bool StandardIsolation::passSelectionLoose(const xAOD::IParticle& p) const -{ - // Are we doing isolation? - if (!m_doLooseIsolation) - return true; - - // If we get this far then we are doing isolation - if ( p.type() == xAOD::Type::Photon || - p.type() == xAOD::Type::Electron || - p.type() == xAOD::Type::Muon ) - { - if (p.isAvailable<char>(m_looseLeptonDecoration)) { - if (p.auxdataConst<char>(m_looseLeptonDecoration) == 1) { - return true; + bool StandardIsolation::passSelectionLoose(const xAOD::IParticle& p) const { + // Are we doing isolation? + if (!m_doLooseIsolation) return true; + + // If we get this far then we are doing isolation + if (p.type() == xAOD::Type::Photon || + p.type() == xAOD::Type::Electron || + p.type() == xAOD::Type::Muon) { + if (!m_doLoosePromptLeptonIso) { + if (!m_skipUnavailable || p.isAvailable<char>(m_looseLeptonDecoration)) { + if (p.auxdataConst<char>(m_looseLeptonDecoration) == 1) { + return true; + } + } + } else { + // Hardcoded a bit - With PLI we need to check that it passes Loose isolation AND passes the BDT cut + if (!m_skipUnavailable || + (p.isAvailable<char>(m_looseLeptonDecoration) && p.isAvailable<char>("AnalysisTop_Isol_Loose"))) { + if (p.auxdataConst<char>(m_looseLeptonDecoration) == 1 && + p.auxdataConst<char>("AnalysisTop_Isol_Loose") == 1) { + return true; + } + } } } + + // Not a photon, electron or muon? + // Didn't pass isolation? + return false; } - - // Not a photon, electron or muon? - // Didn't pass isolation? - return false; -} -void StandardIsolation::print(std::ostream& os) const { + void StandardIsolation::print(std::ostream& os) const { os << " * Standard Isolation\n"; - os << " * Tight lepton isolation = "<<m_tightLeptonDecoration<< "\n"; - os << " * Loose lepton isolation = "<<m_looseLeptonDecoration<< "\n"; -} - + os << " * Tight lepton isolation = " << m_tightLeptonDecoration << "\n"; + os << " * Loose lepton isolation = " << m_looseLeptonDecoration << "\n"; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetGhostTrackSelection.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetGhostTrackSelection.cxx new file mode 100644 index 000000000000..1a069fb779bd --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetGhostTrackSelection.cxx @@ -0,0 +1,90 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopObjectSelectionTools/JetGhostTrackSelection.h" +#include "InDetTrackSelectionTool/InDetTrackSelectionTool.h" + +#include "xAODTracking/TrackParticle.h" +#include "xAODTracking/Vertex.h" + +#include "TopEvent/EventTools.h" + +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +#include "TopObjectSelectionTools/MsgCategory.h" +using namespace TopObjectSelectionTools; + +namespace top { + + JetGhostTrackSelection::JetGhostTrackSelection(const double ptcut, const double etamax, const std::string vertexassociation, const double ptcut_jet, const double etacut_jet ) : + m_ptcut(ptcut), + m_etamax(etamax), + m_ptcut_jet(ptcut_jet), + m_etamax_jet(etacut_jet), + m_vertexassociation(vertexassociation), + m_trkseltool("top::GhostTrackCPTools::TrkSelTool") + { + + top::check(m_trkseltool.retrieve(), "Failed to retrieve InDetTrackSelectionTool"); + + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TrackingCPRecsRun2Final + if (m_vertexassociation == "nominal"){ + m_d0=2; + m_z0sintheta=3; + } + else if(m_vertexassociation == "tight"){ + m_d0=0.5; + m_z0sintheta=0.5; + } + else { + ATH_MSG_INFO("Not applying any vertex association for GA tracks"); + m_d0=10000; + m_z0sintheta=10000; + + } + + } + + JetGhostTrackSelection::~JetGhostTrackSelection() { + } + +// bool JetGhostTrackSelection::passSelection(const xAOD::TrackParticle& track, const xAOD::Vertex& primaryVertex) const { + +// // Track quality requirements +// if (track.pt() < m_ptcut) return false; +// +// if (std::fabs(track.eta()) > m_etamax) return false; +// +// if ( !m_trkseltool->accept(track, &primaryVertex ) ) return false; +// +// // Vertex association requirements +// float deltaz0 = track.z0() + track.vz() - primaryVertex.z(); +// +// if ((std::fabs(track.d0()) > m_d0) || (std::fabs(sin(track.theta()) * deltaz0) > m_z0sintheta)) +// return false; + +// return true; +// } + + bool JetGhostTrackSelection::JetConsideredForGhostTrackSelection(double pt, const double eta) const{ + if ( (pt > m_ptcut_jet) && (std::abs(eta) < m_etamax_jet) ){ + return true; + } + else { + return false; + } + + } + + void JetGhostTrackSelection::print(std::ostream& os) const { + os << "Ghost Associated Track \n" + << " * pT > " << m_ptcut << "\n" + << " * |eta| < " << m_etamax + << " * |d0| < " << m_d0 + << " * |z0sintheta| < " << m_z0sintheta; + } + + +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetGhostTrackSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetGhostTrackSelectionBase.cxx new file mode 100644 index 000000000000..7a20491934a6 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetGhostTrackSelectionBase.cxx @@ -0,0 +1,18 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TopObjectSelectionTools/JetGhostTrackSelectionBase.h" + +namespace top { + JetGhostTrackSelectionBase::JetGhostTrackSelectionBase() { + } + + JetGhostTrackSelectionBase::~JetGhostTrackSelectionBase() { + } + + std::ostream& operator << (std::ostream& os, const top::JetGhostTrackSelectionBase& selection) { + selection.print(os); + return os; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetMC15.cxx index 0121920e039c..d44c06f5c521 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetMC15.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetMC15.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/JetMC15.h" @@ -9,24 +9,25 @@ #include "TopEvent/EventTools.h" namespace top { - JetMC15::JetMC15(const double ptcut, const double etamax, - const bool doJVTCut, - const std::string fwdJetSel) : + const bool doJVTCut): m_ptcut(ptcut), m_etamax(etamax), m_applyJVTCut(doJVTCut), - m_fwdJetSel(fwdJetSel), m_jvt_tool("JetJvtEfficiencyTool") { top::check(m_jvt_tool.retrieve(), "Failed to retrieve JVT tool"); } - // This version of the constructor always perform JVT cut + // This version of the constructor always perform JVT cut + JetMC15::JetMC15(const double ptcut, + const double etamax) : JetMC15::JetMC15(ptcut, etamax, true) {} + + // DEPRECIATED - fwdJetSel string now defunct, keeping blank string input for backwards compatibility JetMC15::JetMC15(const double ptcut, const double etamax, - const std::string fwdJetSel) : JetMC15::JetMC15(ptcut, etamax, true, fwdJetSel) {} + const std::string) : JetMC15::JetMC15(ptcut, etamax, true) {} // DEPRECATED - only kept for backward compatibility JetMC15::JetMC15(const double ptcut, @@ -34,31 +35,16 @@ namespace top { const double) : JetMC15::JetMC15(ptcut, etamax) {} bool JetMC15::passSelection(const xAOD::Jet& jet) { - if (jet.pt() < m_ptcut) - return false; - - if (std::fabs(jet.eta()) > m_etamax) - return false; - if (m_applyJVTCut) { - if (!m_jvt_tool->passesJvtCut(jet)) { - jet.auxdecor<char>("passJVT") = 0; - } - else { - jet.auxdecor<char>("passJVT") = 1; - } + jet.auxdecor<char>("passJVT") = (m_jvt_tool->passesJvtCut(jet) ? 1 : 0); } + //fJVT pass/fail decision already attatched in CP tools - if (m_fwdJetSel == "fJVT") { - if (!jet.getAttribute<char>("passFJVT")) - return false; - } - else if (m_fwdJetSel == "Tight") { - if (std::fabs(jet.eta()) > 2.5 && jet.pt() < 30e3) - return false; - } + if (jet.pt() < m_ptcut) return false; - jet.auxdecor<char>("good") = 1; + if (std::fabs(jet.eta()) > m_etamax) return false; + + jet.auxdecor<char>("good") = 1; jet.auxdecor<char>("closeToLepton") = 0; return true; @@ -68,5 +54,5 @@ namespace top { os << "JetMC15\n" << " * pT > " << m_ptcut << "\n" << " * |eta| < " << m_etamax << "\n"; - } + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetSelectionBase.cxx index 475c55f4c93e..559ad72d6b03 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetSelectionBase.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/JetSelectionBase.cxx @@ -1,20 +1,18 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/JetSelectionBase.h" namespace top { + JetSelectionBase::JetSelectionBase() { + } -JetSelectionBase::JetSelectionBase() { -} - -JetSelectionBase::~JetSelectionBase() { -} - -} + JetSelectionBase::~JetSelectionBase() { + } -std::ostream& operator<<(std::ostream& os, const top::JetSelectionBase& selection) { + std::ostream& operator << (std::ostream& os, const top::JetSelectionBase& selection) { selection.print(os); return os; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/LinkDef.h index 12b00eda063d..8496427036cc 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/LinkDef.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/LinkDef.h @@ -1,18 +1,12 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TopObjectSelectionTools/RCJetMC15.h" + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #ifdef __CINT__ -#pragma extra_include "TopObjectSelectionTools/RCJetMC15.h"; - #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; #pragma link C++ nestedclass; -#pragma link C++ class RCJetMC15+; - #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MsgCategory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MsgCategory.cxx new file mode 100644 index 000000000000..e8b69082a9b1 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MsgCategory.cxx @@ -0,0 +1,6 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#include "TopObjectSelectionTools/MsgCategory.h" + +ANA_MSG_SOURCE(TopObjectSelectionTools, "TopObjectSelectionTools") diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MuonMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MuonMC15.cxx index 0ded97d78d1e..6e9cfe9c1441 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MuonMC15.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MuonMC15.cxx @@ -1,111 +1,91 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/MuonMC15.h" #include "TopEvent/EventTools.h" -namespace top { +#include "TopObjectSelectionTools/MsgCategory.h" +using namespace TopObjectSelectionTools; +namespace top { MuonMC15::MuonMC15(const double ptcut, IsolationBase* isolation, const bool applyTTVACut) : m_ptcut(ptcut), m_muonSelectionTool("CP::MuonSelectionTool"), m_muonSelectionToolLoose("CP::MuonSelectionToolLoose"), m_isolation(isolation), - m_applyTTVACut(applyTTVACut) -{ - top::check( m_muonSelectionTool.retrieve() , "Failed to retrieve muonSelectionTool" ); - top::check( m_muonSelectionToolLoose.retrieve() , "Failed to retrieve muonSelectionToolLoose" ); - -} + m_applyTTVACut(applyTTVACut) { + top::check(m_muonSelectionTool.retrieve(), "Failed to retrieve muonSelectionTool"); + top::check(m_muonSelectionToolLoose.retrieve(), "Failed to retrieve muonSelectionToolLoose"); + } -bool MuonMC15::passSelection(const xAOD::Muon& mu) const -{ - if (mu.pt() < m_ptcut) - return false; + bool MuonMC15::passSelection(const xAOD::Muon& mu) const { + if (mu.pt() < m_ptcut) return false; ///-- https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15 --/// - if (!m_muonSelectionTool->accept(mu)) - return false; + if (!m_muonSelectionTool->accept(mu)) return false; //isolation, if m_isolation != nullptr - if (m_isolation && !m_isolation->passSelection(mu)) - return false; + if (m_isolation && !m_isolation->passSelection(mu)) return false; // Track-to-vertex association - if (m_applyTTVACut){ - if (!passTTVACuts(mu)) - return false; + if (m_applyTTVACut) { + if (!passTTVACuts(mu)) return false; } return true; -} + } -bool MuonMC15::passSelectionLoose(const xAOD::Muon& mu) const -{ - if (mu.pt() < m_ptcut) - return false; + bool MuonMC15::passSelectionLoose(const xAOD::Muon& mu) const { + if (mu.pt() < m_ptcut) return false; ///-- https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15 --/// - if (!m_muonSelectionToolLoose->accept(mu)) - return false; + if (!m_muonSelectionToolLoose->accept(mu)) return false; //isolation, if m_isolation != nullptr - if (m_isolation && !m_isolation->passSelectionLoose(mu)) - return false; + if (m_isolation && !m_isolation->passSelectionLoose(mu)) return false; // Track-to-vertex association - if (m_applyTTVACut){ - if (!passTTVACuts(mu)) - return false; + if (m_applyTTVACut) { + if (!passTTVACuts(mu)) return false; } return true; -} - -bool MuonMC15::passTTVACuts(const xAOD::Muon& mu) const -{ - - // TTVA: - // see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TrackingCPEOYE2015#Track_to_Vertex_Association - if( !mu.isAvailable<float>("d0sig") ){ - std::cout << "d0 significance not found for muon. " - << "Maybe no primary vertex? Won't accept." << std::endl; - return false; } - float d0sig = mu.auxdataConst<float>("d0sig"); - if( std::abs(d0sig) >= 3 ) - return false; + bool MuonMC15::passTTVACuts(const xAOD::Muon& mu) const { + // TTVA: + // see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TrackingCPEOYE2015#Track_to_Vertex_Association + if (!mu.isAvailable<float>("d0sig")) { + ATH_MSG_WARNING("d0 significance not found for muon. " + << "Maybe no primary vertex? Won't accept."); + return false; + } - if( !mu.isAvailable<float>("delta_z0_sintheta") ){ - std::cout << "delta z0*sin(theta) not found for muon. " - << "Maybe no primary vertex? Won't accept." << std::endl; - return false; - } + float d0sig = mu.auxdataConst<float>("d0sig"); + if (std::abs(d0sig) >= 3) return false; - float delta_z0_sintheta = mu.auxdataConst<float>("delta_z0_sintheta"); - if( std::abs(delta_z0_sintheta) >= 0.5 ) - return false; + if (!mu.isAvailable<float>("delta_z0_sintheta")) { + ATH_MSG_WARNING("delta z0*sin(theta) not found for muon. " + << "Maybe no primary vertex? Won't accept."); + return false; + } - return true; + float delta_z0_sintheta = mu.auxdataConst<float>("delta_z0_sintheta"); + if (std::abs(delta_z0_sintheta) >= 0.5) return false; -} + return true; + } void MuonMC15::print(std::ostream& os) const { - os << "MuonMC15\n" - << " * pT > " << m_ptcut << "\n" + os << "MuonMC15\n" + << " * pT > " << m_ptcut << "\n" // << " * |eta| < " << m_etamax << "\n" // << " * quality=" << m_quality << " (tight=0, medium=1, loose=2, v.loose=3)\n" - << " * Everything else from muon tool - fill this in?\n"; + << " * Everything else from muon tool - fill this in?\n"; - if (!m_isolation) - os << " * No isolation requirement\n"; - else - m_isolation->print(os); + if (!m_isolation) os << " * No isolation requirement\n"; + else m_isolation->print(os); } - - - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MuonSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MuonSelectionBase.cxx index f6dbfdff46c9..e30d3bcbcd75 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MuonSelectionBase.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/MuonSelectionBase.cxx @@ -1,20 +1,18 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/MuonSelectionBase.h" namespace top { + MuonSelectionBase::MuonSelectionBase() { + } -MuonSelectionBase::MuonSelectionBase() { -} - -MuonSelectionBase::~MuonSelectionBase() { -} - -} + MuonSelectionBase::~MuonSelectionBase() { + } -std::ostream& operator<<(std::ostream& os, const top::MuonSelectionBase& selection) { + std::ostream& operator << (std::ostream& os, const top::MuonSelectionBase& selection) { selection.print(os); return os; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalASG.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalASG.cxx index 4d099c3457ba..2ffbfe2cdf71 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalASG.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalASG.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id$ #include "TopObjectSelectionTools/OverlapRemovalASG.h" @@ -9,72 +9,60 @@ #include <list> namespace top { - OverlapRemovalASG::OverlapRemovalASG(bool dolargeJet) : m_overlapRemovalTool("OverlapRemovalTool"), m_overlapRemovalToolLoose("OverlapRemovalToolLoose"), m_passPreORSelection("passPreORSelection"), m_passPreORSelectionLoose("passPreORSelectionLoose"), m_overlaps("overlaps"), - m_doLargeJet(dolargeJet) - { - - top::check( m_overlapRemovalTool.retrieve() , "Failed to retrieve overlap removal tool" ); - top::check( m_overlapRemovalToolLoose.retrieve() , "Failed to retrieve (loose) overlap removal tool" ); - + m_doLargeJet(dolargeJet) { + top::check(m_overlapRemovalTool.retrieve(), "Failed to retrieve overlap removal tool"); + top::check(m_overlapRemovalToolLoose.retrieve(), "Failed to retrieve (loose) overlap removal tool"); } - OverlapRemovalASG::~OverlapRemovalASG() - { + OverlapRemovalASG::~OverlapRemovalASG() { } - void OverlapRemovalASG::overlapremoval(const xAOD::PhotonContainer* photon , - const xAOD::ElectronContainer* el , - const xAOD::MuonContainer* mu , - const xAOD::TauJetContainer* tau , - const xAOD::JetContainer* jet , - const xAOD::JetContainer* ljet, + void OverlapRemovalASG::overlapremoval(const xAOD::PhotonContainer* photon, + const xAOD::ElectronContainer* el, + const xAOD::MuonContainer* mu, + const xAOD::TauJetContainer* tau, + const xAOD::JetContainer* jet, + const xAOD::JetContainer* ljet, std::vector<unsigned int>& goodPhotons, std::vector<unsigned int>& goodElectrons, std::vector<unsigned int>& goodMuons, std::vector<unsigned int>& goodTaus, std::vector<unsigned int>& goodJets, std::vector<unsigned int>& goodLargeRJets, - const bool isLoose ) - { + const bool isLoose) { std::string passTopCuts(""); if (!isLoose) { - if (m_doLargeJet) - top::check( m_overlapRemovalTool->removeOverlaps( el, mu, jet, tau, photon, ljet ) , "Failed to remove overlaps" ); - else - top::check( m_overlapRemovalTool->removeOverlaps( el, mu, jet, tau, photon ) , "Failed to remove overlaps" ); + if (m_doLargeJet) top::check(m_overlapRemovalTool->removeOverlaps(el, mu, jet, tau, photon, + ljet), "Failed to remove overlaps"); + else top::check(m_overlapRemovalTool->removeOverlaps(el, mu, jet, tau, photon), "Failed to remove overlaps"); passTopCuts = m_passPreORSelection; } if (isLoose) { - if (m_doLargeJet) - top::check( m_overlapRemovalToolLoose->removeOverlaps( el, mu, jet, tau, photon, ljet ) , "Failed to remove overlaps" ); - else - top::check( m_overlapRemovalToolLoose->removeOverlaps( el, mu, jet, tau, photon ) , "Failed to remove overlaps" ); + if (m_doLargeJet) top::check(m_overlapRemovalToolLoose->removeOverlaps(el, mu, jet, tau, photon, + ljet), "Failed to remove overlaps"); + else top::check(m_overlapRemovalToolLoose->removeOverlaps(el, mu, jet, tau, photon), "Failed to remove overlaps"); + passTopCuts = m_passPreORSelectionLoose; } - removeObjectOverlap( photon, goodPhotons, passTopCuts ); - removeObjectOverlap( el, goodElectrons, passTopCuts ); - removeObjectOverlap( mu, goodMuons, passTopCuts ); - removeObjectOverlap( tau, goodTaus, passTopCuts ); - removeObjectOverlap( jet, goodJets, passTopCuts ); - if (m_doLargeJet) - removeObjectOverlap( ljet, goodLargeRJets, passTopCuts ); - else - removeObject( ljet, goodLargeRJets, passTopCuts ); - - + removeObjectOverlap(photon, goodPhotons, passTopCuts); + removeObjectOverlap(el, goodElectrons, passTopCuts); + removeObjectOverlap(mu, goodMuons, passTopCuts); + removeObjectOverlap(tau, goodTaus, passTopCuts); + removeObjectOverlap(jet, goodJets, passTopCuts); + if (m_doLargeJet) removeObjectOverlap(ljet, goodLargeRJets, passTopCuts); + else removeObject(ljet, goodLargeRJets, passTopCuts); } - void OverlapRemovalASG::removeObjectOverlap( const xAOD::IParticleContainer* xaod, - std::vector<unsigned int>& OUT_vec, - const std::string passTopCuts) { - + void OverlapRemovalASG::removeObjectOverlap(const xAOD::IParticleContainer* xaod, + std::vector<unsigned int>& OUT_vec, + const std::string passTopCuts) { OUT_vec.clear(); unsigned int index(0); @@ -89,10 +77,9 @@ namespace top { } } - void OverlapRemovalASG::removeObject( const xAOD::IParticleContainer* xaod, - std::vector<unsigned int>& OUT_vec, - const std::string passTopCuts) { - + void OverlapRemovalASG::removeObject(const xAOD::IParticleContainer* xaod, + std::vector<unsigned int>& OUT_vec, + const std::string passTopCuts) { OUT_vec.clear(); unsigned int index(0); @@ -107,12 +94,11 @@ namespace top { } } -void OverlapRemovalASG::print(std::ostream& os) const { + void OverlapRemovalASG::print(std::ostream& os) const { os << "OverlapRemovalASG\n"; os << " (1) remove electron that sharing track with muon\n"; os << " (2) remove single jet closest to an electron (within dR < 0.2)\n"; os << " (3) remove electron with dR < 0.4 of jet\n"; os << " (4) remove muon within dR < 0.4 of any jet\n"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalBase.cxx index 84b3c250edf0..ac0db0261907 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalBase.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalBase.cxx @@ -1,20 +1,18 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/OverlapRemovalBase.h" namespace top { + OverlapRemovalBase::OverlapRemovalBase() { + } -OverlapRemovalBase::OverlapRemovalBase() { -} - -OverlapRemovalBase::~OverlapRemovalBase() { -} - -} + OverlapRemovalBase::~OverlapRemovalBase() { + } -std::ostream& operator<<(std::ostream& os, const top::OverlapRemovalBase& overlapremoval) { + std::ostream& operator << (std::ostream& os, const top::OverlapRemovalBase& overlapremoval) { overlapremoval.print(os); return os; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalIndices.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalIndices.cxx index fa90456dfa5c..467ec7c50b75 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalIndices.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/OverlapRemovalIndices.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: OverlapRemovalIndices.cxx 661110 2015-04-17 00:03:39Z morrisj $ #include "TopObjectSelectionTools/OverlapRemovalIndices.h" @@ -9,111 +9,108 @@ #include <list> namespace top { + OverlapRemovalIndices::OverlapRemovalIndices() { + } -OverlapRemovalIndices::OverlapRemovalIndices() { -} + OverlapRemovalIndices::~OverlapRemovalIndices() { + } -OverlapRemovalIndices::~OverlapRemovalIndices() { -} + void OverlapRemovalIndices::overlapremoval(const xAOD::ElectronContainer* el, + const xAOD::MuonContainer* mu, + const xAOD::JetContainer* jet, + const xAOD::JetContainer* ljet, + std::vector<unsigned int>& OUT_el, + std::vector<unsigned int>& OUT_mu, + std::vector<unsigned int>& OUT_jet, + std::vector<unsigned int>& OUT_ljet, + const bool isLoose) { + std::string passTopCuts(""); + if (!isLoose) { + passTopCuts = "passPreORSelection"; + } + if (isLoose) { + passTopCuts = "passPreORSelectionLoose"; + } -void OverlapRemovalIndices::overlapremoval(const xAOD::ElectronContainer* el, - const xAOD::MuonContainer* mu, - const xAOD::JetContainer* jet, - const xAOD::JetContainer* ljet, - std::vector<unsigned int>& OUT_el, - std::vector<unsigned int>& OUT_mu, - std::vector<unsigned int>& OUT_jet, - std::vector<unsigned int>& OUT_ljet, - const bool isLoose ) -{ - std::string passTopCuts(""); - if (!isLoose) { - passTopCuts = "passPreORSelection"; - } - if (isLoose) { - passTopCuts = "passPreORSelectionLoose"; - } - // Work internally with std::list // What passed the pre-overlap removal selection? - std::vector<unsigned int> IN_el,IN_mu,IN_jet,IN_ljet; - std::list<unsigned int> l_el,l_mu,l_jet,l_ljet; - unsigned int index_el(0),index_mu(0),index_jet(0),index_ljet(0); + std::vector<unsigned int> IN_el, IN_mu, IN_jet, IN_ljet; + std::list<unsigned int> l_el, l_mu, l_jet, l_ljet; + unsigned int index_el(0), index_mu(0), index_jet(0), index_ljet(0); if (el) { - for( auto x : *el ){ - if( x->auxdataConst< char >(passTopCuts) == 1 ){ - IN_el.push_back(index_el); - l_el.push_back(index_el); - } - ++index_el; + for (auto x : *el) { + if (x->auxdataConst< char >(passTopCuts) == 1) { + IN_el.push_back(index_el); + l_el.push_back(index_el); } + ++index_el; + } } if (mu) { - for( auto x : *mu ){ - if( x->auxdataConst< char >(passTopCuts) == 1 ){ - IN_mu.push_back(index_mu); - l_mu.push_back(index_mu); - } - ++index_mu; + for (auto x : *mu) { + if (x->auxdataConst< char >(passTopCuts) == 1) { + IN_mu.push_back(index_mu); + l_mu.push_back(index_mu); } + ++index_mu; + } } if (jet) { - for( auto x : *jet ){ - if( x->auxdataConst< char >(passTopCuts) == 1 ){ - IN_jet.push_back(index_jet); - l_jet.push_back(index_jet); - } - ++index_jet; + for (auto x : *jet) { + if (x->auxdataConst< char >(passTopCuts) == 1) { + IN_jet.push_back(index_jet); + l_jet.push_back(index_jet); } + ++index_jet; + } } if (ljet) { - for( auto x : *ljet ){ - if( x->auxdataConst< char >(passTopCuts) == 1 ){ - IN_ljet.push_back(index_ljet); - l_ljet.push_back(index_ljet); - } - ++index_ljet; + for (auto x : *ljet) { + if (x->auxdataConst< char >(passTopCuts) == 1) { + IN_ljet.push_back(index_ljet); + l_ljet.push_back(index_ljet); } + ++index_ljet; + } } // Jets and Muons - remove muon with dR < 0.4 - for( auto j : IN_jet ){ - for( auto m : IN_mu ){ - if( top::deltaR( *(jet->at(j) ) , *(mu->at(m)) ) < 0.4 ){ - l_mu.remove( m ); - } + for (auto j : IN_jet) { + for (auto m : IN_mu) { + if (top::deltaR(*(jet->at(j)), *(mu->at(m))) < 0.4) { + l_mu.remove(m); } + } } // Jets and Electrons - remove single closest jet with dR < 0.2 for (auto e : IN_el) { - double closestdr = 100.; - int closestJetIndex = -1; - for (auto j : IN_jet) { - const double ejetdr = top::deltaR(*(jet->at(j)) , *(el->at(e))); - - if (ejetdr < 0.2 && ejetdr < closestdr) { - closestdr = ejetdr; - closestJetIndex = j; - } + double closestdr = 100.; + int closestJetIndex = -1; + for (auto j : IN_jet) { + const double ejetdr = top::deltaR(*(jet->at(j)), *(el->at(e))); + + if (ejetdr < 0.2 && ejetdr < closestdr) { + closestdr = ejetdr; + closestJetIndex = j; } + } - if (closestJetIndex > -1) - l_jet.remove(closestJetIndex); + if (closestJetIndex > -1) l_jet.remove(closestJetIndex); } // Electrons and Jets - remove electrons with dR < 0.4 - for( auto j : l_jet ){ - for( auto e : IN_el ){ - if( top::deltaR( *(el->at(e)) , *(jet->at(j)) ) < 0.4 ){ - l_el.remove( e ); - } + for (auto j : l_jet) { + for (auto e : IN_el) { + if (top::deltaR(*(el->at(e)), *(jet->at(j))) < 0.4) { + l_el.remove(e); } + } } // Save what's left of the std::lists into the OUT vectors; @@ -122,36 +119,40 @@ void OverlapRemovalIndices::overlapremoval(const xAOD::ElectronContainer* el, OUT_jet.clear(); OUT_ljet.clear(); - for( auto i : l_el ){OUT_el.push_back(i); } - for( auto i : l_mu ){OUT_mu.push_back(i); } - for( auto i : l_jet ){OUT_jet.push_back(i);} - for( auto i : l_ljet ){OUT_ljet.push_back(i);} -} - -void OverlapRemovalIndices::overlapremoval(const xAOD::PhotonContainer* /*photon*/ , - const xAOD::ElectronContainer* el , - const xAOD::MuonContainer* mu , - const xAOD::TauJetContainer* /*tau*/ , - const xAOD::JetContainer* jet , - const xAOD::JetContainer* ljet, - std::vector<unsigned int>& /*goodPhotons*/, - std::vector<unsigned int>& goodElectrons, - std::vector<unsigned int>& goodMuons, - std::vector<unsigned int>& /*goodTaus*/, - std::vector<unsigned int>& goodJets, - std::vector<unsigned int>& goodLargeRJets, - const bool isLoose ) -{ - - overlapremoval(el, mu, jet, ljet, goodElectrons, goodMuons, goodJets, goodLargeRJets, isLoose ); + for (auto i : l_el) { + OUT_el.push_back(i); + } + for (auto i : l_mu) { + OUT_mu.push_back(i); + } + for (auto i : l_jet) { + OUT_jet.push_back(i); + } + for (auto i : l_ljet) { + OUT_ljet.push_back(i); + } + } -} + void OverlapRemovalIndices::overlapremoval(const xAOD::PhotonContainer* /*photon*/, + const xAOD::ElectronContainer* el, + const xAOD::MuonContainer* mu, + const xAOD::TauJetContainer* /*tau*/, + const xAOD::JetContainer* jet, + const xAOD::JetContainer* ljet, + std::vector<unsigned int>& /*goodPhotons*/, + std::vector<unsigned int>& goodElectrons, + std::vector<unsigned int>& goodMuons, + std::vector<unsigned int>& /*goodTaus*/, + std::vector<unsigned int>& goodJets, + std::vector<unsigned int>& goodLargeRJets, + const bool isLoose) { + overlapremoval(el, mu, jet, ljet, goodElectrons, goodMuons, goodJets, goodLargeRJets, isLoose); + } -void OverlapRemovalIndices::print(std::ostream& os) const { + void OverlapRemovalIndices::print(std::ostream& os) const { os << "OverlapRemovalIndices\n"; os << " (1) remove muon within dR < 0.4 of any jet\n"; os << " (2) remove single jet closest to an electron (within dR < 0.2)\n"; os << " (3) remove electron with dR < 0.4 of jet\n"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/PhotonMC16.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/PhotonMC16.cxx new file mode 100644 index 000000000000..d79c46fa82d3 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/PhotonMC16.cxx @@ -0,0 +1,118 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopObjectSelectionTools/PhotonMC16.h" + +// Include what you use! +#include <map> +#include <string> + +#include "TopEvent/EventTools.h" + +#include "TopObjectSelectionTools/MsgCategory.h" +using namespace TopObjectSelectionTools; + +namespace top { + PhotonMC16::PhotonMC16(double ptcut, double etamax, IsolationBase* isolation, bool usePhotonShowerShapeVariables) : + m_ptcut(ptcut), + m_etamax(etamax), + m_photon_selection("DFCommonPhotonsIsEMTight"), + m_loose_photon_selection("DFCommonPhotonsIsEMLoose"), + m_isolation(isolation), + m_usePhotonShowerShapeVariables(usePhotonShowerShapeVariables) { + } + + PhotonMC16::PhotonMC16(double ptcut, double etamax, + const std::string& tightID, + const std::string& looseID, + IsolationBase* isolation, + bool usePhotonShowerShapeVariables) : + m_ptcut(ptcut), + m_etamax(etamax), + m_photon_selection(tightID), + m_loose_photon_selection(looseID), + m_isolation(isolation), + m_usePhotonShowerShapeVariables(usePhotonShowerShapeVariables) { + // Make a map of shortcuts e.g "Tight = DFCommonPhotonsIsEMTight" + std::map<std::string, std::string> id_map; + id_map["Tight"] = "DFCommonPhotonsIsEMTight"; + id_map["Loose"] = "DFCommonPhotonsIsEMLoose"; + id_map["None"] = "None"; + // If ID in map then set it to full name, else keep as is. + if (id_map.find(tightID) != id_map.end()) m_photon_selection = id_map[tightID]; + if (id_map.find(looseID) != id_map.end()) m_loose_photon_selection = id_map[looseID]; + } + + bool PhotonMC16::passSelection(const xAOD::Photon& ph) const { + if (!passSelectionNoIsolation(ph, m_photon_selection)) return false; + + if (m_isolation && !m_isolation->passSelection(ph)) return false; + + return true; + } + + bool PhotonMC16::passSelectionLoose(const xAOD::Photon& ph) const { + if (!passSelectionNoIsolation(ph, m_loose_photon_selection)) return false; + + if (m_isolation && !m_isolation->passSelectionLoose(ph)) return false; + + return true; + } + + bool PhotonMC16::passSelectionNoIsolation(const xAOD::Photon& ph, + const std::string& photon_selection) const { + // Photon author : AuthorPhoton/AuthorAmbiguous. + // Also, for special-case recovery of soft photons: + // xAOD::EgammaParameters::AuthorCaloTopo35. + if (ph.author() != xAOD::EgammaParameters::AuthorPhoton + && ph.author() != xAOD::EgammaParameters::AuthorAmbiguous) return false; + + if (ph.pt() < m_ptcut) return false; + + // removing bad photon cluser [http://cern.ch/go/kp8F] + if (!ph.isGoodOQ(xAOD::EgammaParameters::BADCLUSPHOTON)) return false; + + // Photon selection using derivation decorations + if (photon_selection != "None") + if (!ph.auxdataConst<char>(photon_selection)) return false; + + if (!ph.caloCluster()) return false; + + float abs_eta = std::abs(ph.caloCluster()->etaBE(2)); + if (abs_eta > m_etamax) return false; + + // Remove crack region + if (abs_eta > 1.37 && abs_eta < 1.52) return false; + + // Photon cleaning [http://cern.ch/go/8RdK] + // <tom.neep@cern.ch>: This is madness!! I *think* this is the right way + // to do this but there should really be a helper function supplied by egamma! + // <iconnell@cern.ch>: Updating the cleaning for R21, using similar options... + if (m_usePhotonShowerShapeVariables) { + try { + if ((ph.OQ() & 1073741824) != 0 || + ((ph.OQ() & 134217728) != 0 && + (ph.showerShapeValue(xAOD::EgammaParameters::Reta) > 0.98 + || ph.showerShapeValue(xAOD::EgammaParameters::f1) > 0.4 + || (ph.OQ() & 67108864) != 0))) return false; + } + catch (const SG::ExcBadAuxVar& e) { + ATH_MSG_WARNING("Didn't find the necessary photon shower shapes variables for photon cleaning! This might be a derivation issue, skipping from now on."); + m_usePhotonShowerShapeVariables = false; + } + } + + return true; + } + + void PhotonMC16::print(std::ostream& os) const { + os << "PhotonMC16\n"; + os << " * pT > " << m_ptcut << "\n"; + os << " * |eta| < " << m_etamax << "\n"; + os << " * Photon PID: " << m_photon_selection << "\n"; + os << " * Loose Photon PID: " << m_loose_photon_selection << "\n"; + if (!m_isolation) os << " * No isolation requirement\n"; + else m_isolation->print(os); + } +} // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/PhotonSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/PhotonSelectionBase.cxx index 20527343eeee..08db6326c80c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/PhotonSelectionBase.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/PhotonSelectionBase.cxx @@ -1,22 +1,20 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/PhotonSelectionBase.h" #include <iostream> namespace top { + PhotonSelectionBase::PhotonSelectionBase() { + } -PhotonSelectionBase::PhotonSelectionBase() { -} - -PhotonSelectionBase::~PhotonSelectionBase() { -} - -} + PhotonSelectionBase::~PhotonSelectionBase() { + } -std::ostream& operator<<(std::ostream& os, const top::PhotonSelectionBase& selection) { + std::ostream& operator << (std::ostream& os, const top::PhotonSelectionBase& selection) { selection.print(os); return os; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/SoftMuonMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/SoftMuonMC15.cxx new file mode 100644 index 000000000000..306fd89d235a --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/SoftMuonMC15.cxx @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopObjectSelectionTools/SoftMuonMC15.h" + +#include "TopEvent/EventTools.h" + +namespace top { + SoftMuonMC15::SoftMuonMC15(const double ptcut) : + m_ptcut(ptcut), + m_softmuonSelectionTool("CP::SoftMuonSelectionTool") { + top::check(m_softmuonSelectionTool.retrieve(), "Failed to retrieve softmuonSelectionTool"); + } + + bool SoftMuonMC15::passSelection(const xAOD::Muon& mu) const { + if (mu.pt() < m_ptcut) return false; + + ///-- https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15 --/// + if (!m_softmuonSelectionTool->accept(mu)) return false; + + return true; + } + + void SoftMuonMC15::print(std::ostream& os) const { + os << "SoftMuonMC15\n" + << " * pT > " << m_ptcut << "\n" + << " * Everything else from muon tool - fill this in?\n"; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/SoftMuonSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/SoftMuonSelectionBase.cxx new file mode 100644 index 000000000000..bc9cdf7979b1 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/SoftMuonSelectionBase.cxx @@ -0,0 +1,18 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopObjectSelectionTools/SoftMuonSelectionBase.h" + +namespace top { + SoftMuonSelectionBase::SoftMuonSelectionBase() { + } + + SoftMuonSelectionBase::~SoftMuonSelectionBase() { + } + + std::ostream& operator << (std::ostream& os, const top::SoftMuonSelectionBase& selection) { + selection.print(os); + return os; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TauMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TauMC15.cxx index df9cbe62f0e3..c169e6a3243e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TauMC15.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TauMC15.cxx @@ -1,54 +1,51 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/TauMC15.h" #include "TopEvent/EventTools.h" namespace top { - -TauMC15::TauMC15() : m_tauSelection("TauAnalysisTools::TauSelectionTool"), - m_tauSelectionLoose - ("TauAnalysisTools::TauSelectionToolLoose") { - top::check(m_tauSelection.retrieve(), - "Failed to retrieve tau selection tool"); - top::check(m_tauSelectionLoose.retrieve(), - "Failed to retrieve loose tau selection tool"); -} - -bool TauMC15::passSelection(const xAOD::TauJet& tau) const { - // Get the WP related decisions from TauSelectionTool - - // HIGG8D1 derivations (and possibly others) skim away - // tau tracks with pT<15 GeV. The tau selector tool - // returns an exception in this case. These taus should - // NOT be selected so return false if an exception is raised. - try { - return m_tauSelection->accept(tau); - } catch (std::runtime_error& e) { - // If an exception is raised (possibly due to no tau track) - // then return false - return false; + TauMC15::TauMC15() : m_tauSelection("TauAnalysisTools::TauSelectionTool"), + m_tauSelectionLoose + ("TauAnalysisTools::TauSelectionToolLoose") { + top::check(m_tauSelection.retrieve(), + "Failed to retrieve tau selection tool"); + top::check(m_tauSelectionLoose.retrieve(), + "Failed to retrieve loose tau selection tool"); } -} -bool TauMC15::passSelectionLoose(const xAOD::TauJet& tau) const { - // get the WP related decisions from TauSelectionTool - // For the reasoning behind try/catch see above... - try { - return m_tauSelectionLoose->accept(tau); - } catch (std::runtime_error& e) { - return false; + bool TauMC15::passSelection(const xAOD::TauJet& tau) const { + // Get the WP related decisions from TauSelectionTool + + // HIGG8D1 derivations (and possibly others) skim away + // tau tracks with pT<15 GeV. The tau selector tool + // returns an exception in this case. These taus should + // NOT be selected so return false if an exception is raised. + try { + return static_cast<bool>(m_tauSelection->accept(tau)); + } catch (std::runtime_error& e) { + // If an exception is raised (possibly due to no tau track) + // then return false + return false; + } } -} - -void TauMC15::print(std::ostream& os) const { - os << "TauMC15\n"; - os << " * Taus are now selected using the TauSelectionTool"<< "\n"; - os << " * Either you have supplied a tau configuration file (expert)\n"; - os << " or set pT, JetIDWP and EleOLR options in your top-xaod\n"; - os << " configuration file."; -} + bool TauMC15::passSelectionLoose(const xAOD::TauJet& tau) const { + // get the WP related decisions from TauSelectionTool + // For the reasoning behind try/catch see above... + try { + return static_cast<bool>(m_tauSelectionLoose->accept(tau)); + } catch (std::runtime_error& e) { + return false; + } + } + void TauMC15::print(std::ostream& os) const { + os << "TauMC15\n"; + os << " * Taus are now selected using the TauSelectionTool" << "\n"; + os << " * Either you have supplied a tau configuration file (expert)\n"; + os << " or set pT, JetIDWP and EleOLR options in your top-xaod\n"; + os << " configuration file."; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TauSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TauSelectionBase.cxx index 99f9366c8bd4..ce8206b962f1 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TauSelectionBase.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TauSelectionBase.cxx @@ -1,20 +1,18 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/TauSelectionBase.h" namespace top { + TauSelectionBase::TauSelectionBase() { + } -TauSelectionBase::TauSelectionBase() { + TauSelectionBase::~TauSelectionBase() { + } } -TauSelectionBase::~TauSelectionBase() { -} - -} - -std::ostream& operator<<(std::ostream& os, const top::TauSelectionBase& selection) { - selection.print(os); - return os; +std::ostream& operator << (std::ostream& os, const top::TauSelectionBase& selection) { + selection.print(os); + return os; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TopObjectSelection.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TopObjectSelection.cxx index 2842e20c999a..def7388b3c75 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TopObjectSelection.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TopObjectSelection.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/TopObjectSelection.h" @@ -14,640 +14,1217 @@ #include "xAODMuon/MuonContainer.h" #include "xAODTau/TauJetContainer.h" #include "xAODJet/JetContainer.h" +#include "xAODTracking/TrackParticleContainer.h" #include "xAODMissingET/MissingETContainer.h" +#include "xAODEventInfo/EventInfo.h" -namespace top { - -TopObjectSelection::TopObjectSelection( const std::string& name ) : - asg::AsgTool( name ), - m_config(nullptr), +#include "FourMomUtils/xAODP4Helpers.h" +//#include "PATCore/TAccept.h" - m_electronSelection(nullptr), - m_muonSelection(nullptr), - m_tauSelection(nullptr), - m_jetSelection(nullptr), - m_photonSelection(nullptr), - m_largeJetSelection(nullptr), - m_trackJetSelection(nullptr), +#include "TopParticleLevel/TruthTools.h" +#include "xAODTruth/TruthParticle.h" +#include "xAODTruth/TruthParticleContainer.h" - m_overlapRemovalToolPostSelection(nullptr), - - m_electronInJetSubtractor(nullptr), - - m_passPreORSelection("passPreORSelection"), - m_passPreORSelectionLoose("passPreORSelectionLoose"), - // the following two are used to give failing JVT jets a lower priority in the OR - m_ORToolDecoration("ORToolDecoration"), - m_ORToolDecorationLoose("ORToolDecorationLoose"), - - m_doLooseCuts(false) -{ - declareProperty( "config" , m_config ); -} +#include "TopDataPreparation/SampleXsection.h" - StatusCode TopObjectSelection::initialize() +namespace top { + TopObjectSelection::TopObjectSelection(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), + m_electronSelection(nullptr), + m_fwdElectronSelection(nullptr), + m_muonSelection(nullptr), + m_softmuonSelection(nullptr), + m_tauSelection(nullptr), + m_jetSelection(nullptr), + m_photonSelection(nullptr), + m_largeJetSelection(nullptr), + m_trackJetSelection(nullptr), + m_jetGhostTrackSelection(nullptr), + m_trackSelection(nullptr), + m_overlapRemovalToolPostSelection(nullptr), + m_electronInJetSubtractor(nullptr), + m_passPreORSelection("passPreORSelection"), + m_passPreORSelectionLoose("passPreORSelectionLoose"), + // the following two are used to give failing JVT and failing fJVT jets a lower priority in the OR + m_ORToolDecoration("ORToolDecoration"), + m_ORToolDecorationLoose("ORToolDecorationLoose"), + m_doLooseCuts(false), + m_overlapRemovalTool_softMuons_PFjets("OverlapRemovalTool_softMuons_PFjets"), + m_overlapRemovalTool_softMuons_Alljets("OverlapRemovalTool_softMuons_Alljets") { - // If there are loose selection requirements, then we need additional computations - // Tight leptons are not constrained to be a sub-set of loose - // We will call the selections in the following order: - // (1) passSelection(); - // (2) passSelectionLoose(); - // - // If your tight is not a sub-set of your loose, then you have 2 different functions - // If your tight is a sub-set of your loose, then I suggest you set a loose flag - // when calling passSelection(), then have passSelectionLoose() return this flag - // - // Requests to process loose selections can come from: - // (1) Data event - // (2) User request overlap removal be done on loose objects - // - The top recommendation is that you do OR on tight objects - // (3) Determination of Fakes control regions in MC - expert fakes mode - // - - if (!m_config->isMC()) - m_doLooseCuts = true; - - if (m_config->doOverlapRemovalOnLooseLeptonDef()) - m_doLooseCuts = true; - - if (m_config->doLooseEvents()) - m_doLooseCuts = true; - - if (m_config->applyElectronInJetSubtraction()) { - m_electronInJetSubtractor = std::unique_ptr<top::ElectronInJetSubtractionCollectionMaker> - ( new top::ElectronInJetSubtractionCollectionMaker( "top::ElectronInJetSubtractionCollectionMaker" ) ); - top::check( m_electronInJetSubtractor->setProperty( "config" , m_config ) , "Failed to setProperty of top::ElectronInJetSubtractionCollectionMaker" ); - top::check( m_electronInJetSubtractor->initialize() , "Failed to initialize top::ElectronInJetSubtractionCollectionMaker" ); + declareProperty("config", m_config); } - - // b-tagging stuff - // for calo jets - std::vector<std::string> availableWPs = m_config->bTagWP_available(); - for (auto& WP : availableWPs) { - m_btagSelTools[WP] = "BTaggingSelectionTool_"+WP+"_"+m_config->sgKeyJets(); - top::check( m_btagSelTools[WP].retrieve(), "Failed to retrieve b-tagging Selection tool" ); - } - // for track jets - availableWPs = m_config->bTagWP_available_trkJet(); - for (auto& WP : availableWPs) { - m_trkjet_btagSelTools[WP] = "BTaggingSelectionTool_"+WP+"_"+m_config->sgKeyTrackJets(); - top::check( m_trkjet_btagSelTools[WP].retrieve(), "Failed to retrieve b-tagging Selection tool" ); - } - - return StatusCode::SUCCESS; -} + StatusCode TopObjectSelection::initialize() { + // If there are loose selection requirements, then we need additional computations + // Tight leptons are not constrained to be a sub-set of loose + // We will call the selections in the following order: + // (1) passSelection(); + // (2) passSelectionLoose(); + // + // If your tight is not a sub-set of your loose, then you have 2 different functions + // If your tight is a sub-set of your loose, then I suggest you set a loose flag + // when calling passSelection(), then have passSelectionLoose() return this flag + // + // Requests to process loose selections can come from: + // (1) Data event + // (2) User request overlap removal be done on loose objects + // - The top recommendation is that you do OR on tight objects + // (3) Determination of Fakes control regions in MC - expert fakes mode + // + + if (m_config->useSoftMuons()) { + top::check(m_overlapRemovalTool_softMuons_PFjets.retrieve(), "Failed to retrieve overlap removal tool for soft muons - PF jets"); + top::check(m_overlapRemovalTool_softMuons_Alljets.retrieve(), "Failed to retrieve overlap removal tool for soft muons - all jets"); + } + + if (!m_config->isMC()) m_doLooseCuts = true; + + if (m_config->doOverlapRemovalOnLooseLeptonDef()) m_doLooseCuts = true; + + if (m_config->doLooseEvents()) m_doLooseCuts = true; + + if(m_config->useLooseObjectsInMETInLooseTree() || m_config->useLooseObjectsInMETInNominalTree() || m_config->writeMETBuiltWithLooseObjects()) m_doLooseCuts = true; + + if (m_config->applyElectronInJetSubtraction()) { + m_electronInJetSubtractor = std::unique_ptr<top::ElectronInJetSubtractionCollectionMaker> + (new top::ElectronInJetSubtractionCollectionMaker( + "top::ElectronInJetSubtractionCollectionMaker")); + top::check(m_electronInJetSubtractor->setProperty("config", + m_config), + "Failed to setProperty of top::ElectronInJetSubtractionCollectionMaker"); + top::check( + m_electronInJetSubtractor->initialize(), "Failed to initialize top::ElectronInJetSubtractionCollectionMaker"); + } + + // b-tagging stuff + // for calo jets + std::vector<std::string> availableWPs = m_config->bTagWP_available(); + for (auto& WP : availableWPs) { + m_btagSelTools[WP] = "BTaggingSelectionTool_" + WP + "_" + m_config->sgKeyJets(); + top::check(m_btagSelTools[WP].retrieve(), "Failed to retrieve b-tagging Selection tool"); + } + // for track jets + availableWPs = m_config->bTagWP_available_trkJet(); + for (auto& WP : availableWPs) { + m_trkjet_btagSelTools[WP] = "BTaggingSelectionTool_" + WP + "_" + m_config->sgKeyTrackJets(); + top::check(m_trkjet_btagSelTools[WP].retrieve(), "Failed to retrieve b-tagging Selection tool"); + } + return StatusCode::SUCCESS; + } -void TopObjectSelection::electronSelection(ElectronSelectionBase* ptr) { + void TopObjectSelection::electronSelection(ElectronSelectionBase* ptr) { m_electronSelection.reset(ptr); -} + } + + void TopObjectSelection::fwdElectronSelection(FwdElectronSelectionBase* ptr) { + m_fwdElectronSelection.reset(ptr); + } -void TopObjectSelection::muonSelection(MuonSelectionBase* ptr) { + void TopObjectSelection::muonSelection(MuonSelectionBase* ptr) { m_muonSelection.reset(ptr); -} + } -void TopObjectSelection::tauSelection(TauSelectionBase* ptr) { + void TopObjectSelection::softmuonSelection(SoftMuonSelectionBase* ptr) { + m_softmuonSelection.reset(ptr); + } + + void TopObjectSelection::tauSelection(TauSelectionBase* ptr) { m_tauSelection.reset(ptr); -} + } -void TopObjectSelection::jetSelection(JetSelectionBase* ptr) { + void TopObjectSelection::jetSelection(JetSelectionBase* ptr) { m_jetSelection.reset(ptr); -} + } -void TopObjectSelection::photonSelection(PhotonSelectionBase* ptr) { - m_photonSelection.reset(ptr); -} - -void TopObjectSelection::largeJetSelection(JetSelectionBase* ptr) { + void TopObjectSelection::photonSelection(PhotonSelectionBase* ptr) { + m_photonSelection.reset(ptr); + } + + void TopObjectSelection::largeJetSelection(JetSelectionBase* ptr) { m_largeJetSelection.reset(ptr); -} + } -void TopObjectSelection::trackJetSelection(JetSelectionBase* ptr) { + void TopObjectSelection::trackJetSelection(JetSelectionBase* ptr) { m_trackJetSelection.reset(ptr); -} + } + + void TopObjectSelection::jetGhostTrackSelection(JetGhostTrackSelectionBase* ptr) { + m_jetGhostTrackSelection.reset(ptr); + } + + void TopObjectSelection::trackSelection(TrackSelectionBase* ptr) { + m_trackSelection.reset(ptr); + } + -void TopObjectSelection::overlapRemovalPostSelection(OverlapRemovalBase* ptr) { + void TopObjectSelection::overlapRemovalPostSelection(OverlapRemovalBase* ptr) { m_overlapRemovalToolPostSelection.reset(ptr); -} + } -StatusCode TopObjectSelection::execute() -{ - applySelectionPreOverlapRemoval(); - top::check( applyOverlapRemoval() , "Failed to apply overlap removal" ); - return StatusCode::SUCCESS; -} + StatusCode TopObjectSelection::execute(bool executeNominal) { + // Set variable to tell us if we are doing this execution on nominal or systematic events + m_executeNominal = executeNominal; + applySelectionPreOverlapRemoval(); + top::check(applyOverlapRemoval(), "Failed to apply overlap removal"); -void TopObjectSelection::applySelectionPreOverlapRemoval() -{ + return StatusCode::SUCCESS; + } + + void TopObjectSelection::applySelectionPreOverlapRemoval() { + // If we are doing Electron in Jet subtraction, + // We need to: + // (1) Apply object selection to the electrons + // (2) Subtract the electron from the jet, which: + // - Changes the jet 4-momentum + // - Reject additional electrons + // (3) Apply object selection to the modified jets + + if (m_config->useElectrons()) { + applySelectionPreOverlapRemovalElectrons(); + } + if (m_config->useFwdElectrons()) { + applySelectionPreOverlapRemovalFwdElectrons(); + } + + if (m_config->applyElectronInJetSubtraction()) { + top::check(m_electronInJetSubtractor->execute( + m_executeNominal), "Failed to execute top::ElectronInJetSubtractionCollectionMaker"); + } + + + if (m_config->usePhotons() && m_photonSelection != nullptr) { + applySelectionPreOverlapRemovalPhotons(); + } + if (m_config->useMuons() && m_muonSelection != nullptr) { + applySelectionPreOverlapRemovalMuons(); + } + if (m_config->useSoftMuons() && m_softmuonSelection != nullptr) { + applySelectionPreOverlapRemovalSoftMuons(); + } + if (m_config->useTaus() && m_tauSelection != nullptr) { + applySelectionPreOverlapRemovalTaus(); + } + if (m_config->useJets() && m_jetSelection != nullptr) { + applySelectionPreOverlapRemovalJets(); + } + if (m_config->useLargeRJets() && m_largeJetSelection != nullptr) { + applySelectionPreOverlapRemovalLargeRJets(); + } + if (m_config->useTrackJets() && m_trackJetSelection != nullptr) { + applySelectionPreOverlapRemovalTrackJets(); + } + if (m_config->useJetGhostTrack() && m_jetGhostTrackSelection != nullptr) { + applySelectionPreOverlapRemovalJetGhostTracks(); + } + if (m_config->useTracks() && m_trackSelection != nullptr) { + applySelectionPreOverlapRemovalTracks(); + } - // If we are doing Electron in Jet subtraction, - // We need to: - // (1) Apply object selection to the electrons - // (2) Subtract the electron from the jet, which: - // - Changes the jet 4-momentum - // - Reject additional electrons - // (3) Apply object selection to the modified jets - - if( m_config->useElectrons() ){applySelectionPreOverlapRemovalElectrons() ;} - - if (m_config->applyElectronInJetSubtraction()) { - top::check( m_electronInJetSubtractor->execute() , "Failed to execute top::ElectronInJetSubtractionCollectionMaker" ); } + void TopObjectSelection::applySelectionPreOverlapRemovalPhotons() { + for (auto currentSystematic : *m_config->systSgKeyMapPhotons()) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; - if( m_config->usePhotons() && m_photonSelection != nullptr ){applySelectionPreOverlapRemovalPhotons() ;} - if( m_config->useMuons() && m_muonSelection != nullptr ){applySelectionPreOverlapRemovalMuons() ;} - if( m_config->useTaus() && m_tauSelection != nullptr ){applySelectionPreOverlapRemovalTaus() ;} - if( m_config->useJets() && m_jetSelection != nullptr ){applySelectionPreOverlapRemovalJets() ;} - if( m_config->useLargeRJets() && m_largeJetSelection != nullptr){applySelectionPreOverlapRemovalLargeRJets() ;} - if( m_config->useTrackJets() && m_trackJetSelection != nullptr){applySelectionPreOverlapRemovalTrackJets() ;} -} + const xAOD::PhotonContainer* photons(nullptr); + top::check(evtStore()->retrieve(photons, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalPhotons() failed to retrieve photons"); + ATH_MSG_DEBUG(" Cut on Photons with key = " << currentSystematic.second); -void TopObjectSelection::applySelectionPreOverlapRemovalPhotons() { - for (auto currentSystematic : *m_config->systSgKeyMapPhotons()) { - const xAOD::PhotonContainer* photons(nullptr); - top::check(evtStore()->retrieve(photons, currentSystematic.second), "TopObjectSelection::applySelectionPreOverlapRemovalPhotons() failed to retrieve photons"); - ATH_MSG_DEBUG(" Cut on Photons with key = "<<currentSystematic.second); - - for (auto photonPtr : *photons) { - photonPtr->auxdecor<char>( m_passPreORSelection ) = m_photonSelection->passSelection(*photonPtr); - photonPtr->auxdecor<char>( m_ORToolDecoration ) = photonPtr->auxdataConst<char>( m_passPreORSelection ) * 2; - if (m_doLooseCuts) { - photonPtr->auxdecor<char>( m_passPreORSelectionLoose ) = m_photonSelection->passSelectionLoose(*photonPtr); - photonPtr->auxdecor<char>( m_ORToolDecorationLoose ) = photonPtr->auxdataConst<char>( m_passPreORSelectionLoose ) * 2; + for (auto photonPtr : *photons) { + photonPtr->auxdecor<char>(m_passPreORSelection) = m_photonSelection->passSelection(*photonPtr); + photonPtr->auxdecor<char>(m_ORToolDecoration) = photonPtr->auxdataConst<char>(m_passPreORSelection) * 2; + if (m_doLooseCuts) { + photonPtr->auxdecor<char>(m_passPreORSelectionLoose) = m_photonSelection->passSelectionLoose(*photonPtr); + photonPtr->auxdecor<char>(m_ORToolDecorationLoose) = + photonPtr->auxdataConst<char>(m_passPreORSelectionLoose) * 2; + } } } } -} /** * @brief For each systematic load each of the electrons and test if they pass * the object selection. */ -void TopObjectSelection::applySelectionPreOverlapRemovalElectrons() -{ + void TopObjectSelection::applySelectionPreOverlapRemovalElectrons() { for (auto currentSystematic : *m_config->systSgKeyMapElectrons()) { - const xAOD::ElectronContainer* electrons(nullptr); - top::check(evtStore()->retrieve(electrons, currentSystematic.second), "TopObjectSelection::applySelectionPreOverlapRemovalElectrons() failed to retrieve electrons"); - ATH_MSG_DEBUG(" Cut on Electrons with key = "<<currentSystematic.second); - - for (auto electronPtr : *electrons) { - electronPtr->auxdecor<char>( m_passPreORSelection ) = m_electronSelection->passSelection(*electronPtr); - electronPtr->auxdecor<char>( m_ORToolDecoration ) = electronPtr->auxdataConst<char>( m_passPreORSelection ) * 2; - if (m_doLooseCuts) { - electronPtr->auxdecor<char>( m_passPreORSelectionLoose ) = m_electronSelection->passSelectionLoose(*electronPtr); - electronPtr->auxdecor<char>( m_ORToolDecorationLoose ) = electronPtr->auxdataConst<char>( m_passPreORSelectionLoose ) * 2; - } + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + + const xAOD::ElectronContainer* electrons(nullptr); + top::check(evtStore()->retrieve(electrons, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalElectrons() failed to retrieve electrons"); + ATH_MSG_DEBUG(" Cut on Electrons with key = " << currentSystematic.second); + + for (auto electronPtr : *electrons) { + electronPtr->auxdecor<char>(m_passPreORSelection) = m_electronSelection->passSelection(*electronPtr); + electronPtr->auxdecor<char>(m_ORToolDecoration) = electronPtr->auxdataConst<char>(m_passPreORSelection) * 2; + if (m_doLooseCuts) { + electronPtr->auxdecor<char>(m_passPreORSelectionLoose) = + m_electronSelection->passSelectionLoose(*electronPtr); + electronPtr->auxdecor<char>(m_ORToolDecorationLoose) = electronPtr->auxdataConst<char>( + m_passPreORSelectionLoose) * 2; } + } } -} + } -void TopObjectSelection::applySelectionPreOverlapRemovalMuons() -{ +/** + * @brief For each systematic load each of the fwd electrons and test if they pass + * the object selection. + */ + void TopObjectSelection::applySelectionPreOverlapRemovalFwdElectrons() { + for (const auto& currentSystematic : *m_config->systSgKeyMapFwdElectrons()) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + + const xAOD::ElectronContainer* fwdelectrons(nullptr); + top::check(evtStore()->retrieve(fwdelectrons, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalFwdElectrons() failed to retrieve fwd electrons"); + ATH_MSG_DEBUG(" Cut on Electrons with key = " << currentSystematic.second); + + int bcid = 0; + int runNumber = 0; + if (!m_config->isMC()) { + const xAOD::EventInfo* eventInfo(nullptr); + top::check(evtStore()->retrieve(eventInfo, + m_config->sgKeyEventInfo()), + "Failed to retrieve EventInfo in TopObjectSelection::applySelectionPreOverlapRemovalFwdElectrons()"); + bcid = eventInfo->bcid(); + runNumber = eventInfo->runNumber(); + } + + for (auto electronPtr : *fwdelectrons) { + electronPtr->auxdecor<char>(m_passPreORSelection) = m_fwdElectronSelection->passSelection(*electronPtr, bcid, + runNumber); + electronPtr->auxdecor<char>(m_ORToolDecoration) = electronPtr->auxdataConst<char>(m_passPreORSelection) * 2; + if (m_doLooseCuts) { + electronPtr->auxdecor<char>(m_passPreORSelectionLoose) = m_fwdElectronSelection->passSelectionLoose( + *electronPtr, bcid, runNumber); + electronPtr->auxdecor<char>(m_ORToolDecorationLoose) = electronPtr->auxdataConst<char>( + m_passPreORSelectionLoose) * 2; + } + }//end of loop on electrons + }//end of loop on systematics + } + + void TopObjectSelection::applySelectionPreOverlapRemovalMuons() { for (auto currentSystematic : *m_config->systSgKeyMapMuons()) { - const xAOD::MuonContainer* muons(nullptr); - top::check(evtStore()->retrieve(muons, currentSystematic.second) , "TopObjectSelection::applySelectionPreOverlapRemovalMuons() failed to retrieve muons" ); - - for (auto muonPtr : *muons) { - muonPtr->auxdecor<char>( m_passPreORSelection ) = m_muonSelection->passSelection(*muonPtr); - muonPtr->auxdecor<char>( m_ORToolDecoration ) = muonPtr->auxdataConst<char>( m_passPreORSelection ) * 2; - if (m_doLooseCuts) { - muonPtr->auxdecor<char>( m_passPreORSelectionLoose ) = m_muonSelection->passSelectionLoose(*muonPtr); - muonPtr->auxdecor<char>( m_ORToolDecorationLoose ) = muonPtr->auxdataConst<char>( m_passPreORSelectionLoose ) * 2; - } + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + const xAOD::MuonContainer* muons(nullptr); + top::check(evtStore()->retrieve(muons, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalMuons() failed to retrieve muons"); + + for (auto muonPtr : *muons) { + muonPtr->auxdecor<char>(m_passPreORSelection) = m_muonSelection->passSelection(*muonPtr); + muonPtr->auxdecor<char>(m_ORToolDecoration) = muonPtr->auxdataConst<char>(m_passPreORSelection) * 2; + if (m_doLooseCuts) { + muonPtr->auxdecor<char>(m_passPreORSelectionLoose) = m_muonSelection->passSelectionLoose(*muonPtr); + muonPtr->auxdecor<char>(m_ORToolDecorationLoose) = muonPtr->auxdataConst<char>(m_passPreORSelectionLoose) * 2; } + } } -} + } -void TopObjectSelection::applySelectionPreOverlapRemovalTaus() -{ - for (auto currentSystematic : *m_config->systSgKeyMapTaus()) { - const xAOD::TauJetContainer* taus(nullptr); - top::check(evtStore()->retrieve(taus, currentSystematic.second) , "TopObjectSelection::applySelectionPreOverlapRemovalTaus() failed to retrieve taus" ); - - for (auto tauPtr : *taus) { - tauPtr->auxdecor<char>( m_passPreORSelection ) = m_tauSelection->passSelection(*tauPtr); - tauPtr->auxdecor<char>( m_ORToolDecoration ) = tauPtr->auxdataConst<char>( m_passPreORSelection ) * 2; - if (m_doLooseCuts) { - tauPtr->auxdecor<char>( m_passPreORSelectionLoose ) = m_tauSelection->passSelectionLoose(*tauPtr); - tauPtr->auxdecor<char>( m_ORToolDecorationLoose ) = tauPtr->auxdataConst<char>( m_passPreORSelectionLoose ) * 2; - } - } - } -} + void TopObjectSelection::applySelectionPreOverlapRemovalSoftMuons() { + for (const std::pair<std::size_t, std::string>& currentSystematic : *m_config->systSgKeyMapSoftMuons()) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + const xAOD::MuonContainer* softmuons(nullptr); + top::check(evtStore()->retrieve(softmuons, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalSoftMuons() failed to retrieve soft muons"); -void TopObjectSelection::applySelectionPreOverlapRemovalJets() -{ - - // Boosted analysis subtract electrons from jets - // If we use Loose electrons we end up with loose jet collections - - bool isLooseJets(false); - - for (auto currentSystematic : *m_config->systSgKeyMapJets(isLooseJets)) { - const xAOD::JetContainer* jets(nullptr); - top::check(evtStore()->retrieve(jets, currentSystematic.second) , "TopObjectSelection::applySelectionPreOverlapRemovalJets() failed to retrieve jets" ); - ATH_MSG_DEBUG(" Cut on Jets with key = "<<currentSystematic.second); - - for (auto jetPtr : *jets) { - ATH_MSG_DEBUG(" Jet pt = "<<(jetPtr)->pt()); - char decoration = m_jetSelection->passSelection(*jetPtr); - jetPtr->auxdecor<char>( m_passPreORSelection ) = decoration; - // if JVT cut enabled: jets that pass JVT get a 2, otherwise the same as passPreORSelection - // if not, passPreORSelection * 2 - if (jetPtr->isAvailable<char>("passJVT")) { - jetPtr->auxdecor<char>( m_ORToolDecoration ) = decoration + jetPtr->auxdataConst<char>( "passJVT" ); - } else { - jetPtr->auxdecor<char>( m_ORToolDecoration ) = decoration * 2; - } - if (m_doLooseCuts) { - jetPtr->auxdecor<char>( m_passPreORSelectionLoose ) = decoration; - if (jetPtr->isAvailable<char>("passJVT")) { - jetPtr->auxdecor<char>( m_ORToolDecorationLoose ) = decoration + jetPtr->auxdataConst<char>( "passJVT" ); - } else { - jetPtr->auxdecor<char>( m_ORToolDecorationLoose ) = decoration * 2; - } + for (const xAOD::Muon* softmuonPtr : *softmuons) { + softmuonPtr->auxdecor<char>(m_passPreORSelection) = m_softmuonSelection->passSelection(*softmuonPtr); + softmuonPtr->auxdecor<char>(m_ORToolDecoration) = softmuonPtr->auxdataConst<char>(m_passPreORSelection) * 2; } - //decorate with b-tagging flags - std::vector<std::string> availableWPs = m_config->bTagWP_available(); - for (auto& WP : availableWPs) { - if (WP!= "Continuous") { - bool isTagged = false; - if (std::fabs(jetPtr->eta()) < 2.5 ) { - ToolHandle<IBTaggingSelectionTool>& btagsel = m_btagSelTools[WP]; - isTagged = btagsel->accept(*jetPtr); - } - jetPtr->auxdecor<char>("isbtagged_"+WP) = isTagged; - } - else { - int tagWeightBin = -2; // AT default - if (std::fabs(jetPtr->eta()) < 2.5 ) { - ToolHandle<IBTaggingSelectionTool>& btagsel = m_btagSelTools[WP]; - tagWeightBin = btagsel->getQuantile(*jetPtr); - } - jetPtr->auxdecor<int>("tagWeightBin") = tagWeightBin; + } + } + + void TopObjectSelection::applySelectionPreOverlapRemovalTaus() { + for (auto currentSystematic : *m_config->systSgKeyMapTaus()) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + const xAOD::TauJetContainer* taus(nullptr); + top::check(evtStore()->retrieve(taus, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalTaus() failed to retrieve taus"); + + for (auto tauPtr : *taus) { + tauPtr->auxdecor<char>(m_passPreORSelection) = m_tauSelection->passSelection(*tauPtr); + tauPtr->auxdecor<char>(m_ORToolDecoration) = tauPtr->auxdataConst<char>(m_passPreORSelection) * 2; + if (m_doLooseCuts) { + tauPtr->auxdecor<char>(m_passPreORSelectionLoose) = m_tauSelection->passSelectionLoose(*tauPtr); + tauPtr->auxdecor<char>(m_ORToolDecorationLoose) = tauPtr->auxdataConst<char>(m_passPreORSelectionLoose) * 2; } } } } - - // Are we using the ElectronInJetSubtraction and running with loose lepton definitons - if (m_doLooseCuts && m_config->applyElectronInJetSubtraction()) { - for (auto currentSystematic : *m_config->systSgKeyMapJets(m_doLooseCuts)) { + + void TopObjectSelection::applySelectionPreOverlapRemovalJets() { + // Boosted analysis subtract electrons from jets + // If we use Loose electrons we end up with loose jet collections + + bool isLooseJets(false); + + for (auto currentSystematic : *m_config->systSgKeyMapJets(isLooseJets)) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + const xAOD::JetContainer* jets(nullptr); - top::check(evtStore()->retrieve(jets, currentSystematic.second) , "TopObjectSelection::applySelectionPreOverlapRemovalJets() failed to retrieve jets" ); - ATH_MSG_DEBUG(" Cut on Jets with key = "<<currentSystematic.second); + top::check(evtStore()->retrieve(jets, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalJets() failed to retrieve jets"); + ATH_MSG_DEBUG(" Cut on Jets with key = " << currentSystematic.second); for (auto jetPtr : *jets) { - char decoration = m_jetSelection->passSelection(*jetPtr); - jetPtr->auxdecor<char>( m_passPreORSelection ) = decoration; - // if JVT cut enabled: jets that pass JVT get a 2, otherwise the same as passPreORSelection - // if not, passPreORSelection * 2 - if (jetPtr->isAvailable<char>("passJVT")) { - jetPtr->auxdecor<char>( m_ORToolDecoration ) = decoration + jetPtr->auxdataConst<char>( "passJVT" ); - } else { - jetPtr->auxdecor<char>( m_ORToolDecoration ) = decoration * 2; + ATH_MSG_DEBUG(" Jet pt = " << (jetPtr)->pt()); + bool passed = m_jetSelection->passSelection(*jetPtr); + + //Forward jets always get JVT=1, Central jets always get fJVT=1 + bool passedJVT_and_fJVT = true; + if (jetPtr->isAvailable<char>("passJVT")) { + if (jetPtr->isAvailable<char>("AnalysisTop_fJVTdecision")) { + passedJVT_and_fJVT = jetPtr->auxdataConst<char>("passJVT") && jetPtr->auxdataConst<char>("AnalysisTop_fJVTdecision"); + } + else { + passedJVT_and_fJVT = jetPtr->auxdataConst<char>("passJVT"); + } + } + else if (jetPtr->isAvailable<char>("AnalysisTop_fJVTdecision")) { //Possibly redundant, fJVT shouldn't really be able to run if passJVT isn't avaliable + passedJVT_and_fJVT = jetPtr->auxdataConst<char>("AnalysisTop_fJVTdecision"); + } + + if (m_config->applyElectronInJetSubtraction()) { + if (jetPtr->isAvailable<char>("passesFancyOR")) { + if (!jetPtr->auxdecor<char>("passesFancyOR")) passed = false; + } } + // if JVT or fJVT cut enabled and valid: jets that pass (f)JVT get passPreORSelection * 2, jets that fail get the same as passPreORSelection + // if no JVT cut and central jet, or no fJVT and forward jet, jet gets: passPreORSelection * 2 + jetPtr->auxdecor<char>(m_passPreORSelection) = passed; + jetPtr->auxdecor<char>(m_ORToolDecoration) = (passed ? (passedJVT_and_fJVT ? 2 : 1) : 0); if (m_doLooseCuts) { - jetPtr->auxdecor<char>( m_passPreORSelectionLoose ) = decoration; - if (jetPtr->isAvailable<char>("passJVT")) { - jetPtr->auxdecor<char>( m_ORToolDecorationLoose ) = decoration + jetPtr->auxdataConst<char>( "passJVT" ); - } else { - jetPtr->auxdecor<char>( m_ORToolDecorationLoose ) = decoration * 2; - } + jetPtr->auxdecor<char>(m_passPreORSelectionLoose) = passed; + jetPtr->auxdecor<char>(m_ORToolDecorationLoose) = (passed ? (passedJVT_and_fJVT ? 2 : 1) : 0); } //decorate with b-tagging flags std::vector<std::string> availableWPs = m_config->bTagWP_available(); for (auto& WP : availableWPs) { - if (WP!= "Continuous") { - bool isTagged = false; - if (std::fabs(jetPtr->eta()) < 2.5 ) { + if (WP.find("Continuous") == std::string::npos) { + bool isTagged = false; + if (std::fabs(jetPtr->eta()) <= 2.5) { ToolHandle<IBTaggingSelectionTool>& btagsel = m_btagSelTools[WP]; - isTagged = btagsel->accept(*jetPtr); + isTagged = static_cast<bool>(btagsel->accept(*jetPtr)); } - jetPtr->auxdecor<char>("isbtagged_"+WP) = isTagged; - } - else { + jetPtr->auxdecor<char>("isbtagged_" + WP) = isTagged; + } else { int tagWeightBin = -2; // AT default - if (std::fabs(jetPtr->eta()) < 2.5 ) { + if (std::fabs(jetPtr->eta()) <= 2.5) { ToolHandle<IBTaggingSelectionTool>& btagsel = m_btagSelTools[WP]; tagWeightBin = btagsel->getQuantile(*jetPtr); } - jetPtr->auxdecor<int>("tagWeightBin") = tagWeightBin; + jetPtr->auxdecor<int>("tagWeightBin_" + WP) = tagWeightBin; } } } - } - } - -} + } + + // Are we using the ElectronInJetSubtraction and running with loose lepton definitons + if (m_doLooseCuts && m_config->applyElectronInJetSubtraction()) { + for (auto currentSystematic : *m_config->systSgKeyMapJets(m_doLooseCuts)) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; -void TopObjectSelection::applySelectionPreOverlapRemovalLargeRJets() -{ - for (auto currentSystematic : *m_config->systSgKeyMapLargeRJets()) { const xAOD::JetContainer* jets(nullptr); - top::check(evtStore()->retrieve(jets, currentSystematic.second) , "TopObjectSelection::applySelectionPreOverlapRemovalLargeRJets() failed to retrieve large R jets" ); + top::check(evtStore()->retrieve(jets, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalJets() failed to retrieve jets"); + ATH_MSG_DEBUG(" Cut on Jets with key = " << currentSystematic.second); for (auto jetPtr : *jets) { - char decoration = m_largeJetSelection->passSelection(*jetPtr); - jetPtr->auxdecor<char>( m_passPreORSelection ) = decoration; - jetPtr->auxdecor<char>( m_ORToolDecoration ) = decoration * 2; - if (m_doLooseCuts) { - jetPtr->auxdecor<char>( m_passPreORSelectionLoose ) = decoration; - jetPtr->auxdecor<char>( m_ORToolDecorationLoose ) = decoration * 2; + bool decoration = m_jetSelection->passSelection(*jetPtr); + + //Forward jets always get JVT=1, Central jets always get fJVT=1 + bool passedJVT_and_fJVT = true; + if (jetPtr->isAvailable<char>("passJVT")) { + if (jetPtr->isAvailable<char>("AnalysisTop_fJVTdecision")) { + passedJVT_and_fJVT = jetPtr->auxdataConst<char>("passJVT") && jetPtr->auxdataConst<char>("AnalysisTop_fJVTdecision"); + } + else { + passedJVT_and_fJVT = jetPtr->auxdataConst<char>("passJVT"); + } + } + else if (jetPtr->isAvailable<char>("AnalysisTop_fJVTdecision")) { //Possibly redundant, fJVT shouldn't really be able to run if passJVT isn't avaliable + passedJVT_and_fJVT = jetPtr->auxdataConst<char>("AnalysisTop_fJVTdecision"); + } + + // if JVT or fJVT cut enabled: jets that pass (f)JVT get passPreORSelection*2, jets which fail get the same as passPreORSelection + // if no JVT cut and central jet, or no fJVT cut and forward jet, jet gets: passPreORSelection * 2 + jetPtr->auxdecor<char>(m_passPreORSelection) = decoration; + jetPtr->auxdecor<char>(m_passPreORSelectionLoose) = decoration; + + jetPtr->auxdecor<char>(m_ORToolDecoration) = (decoration ? (passedJVT_and_fJVT ? 2 : 1) : 0); + jetPtr->auxdecor<char>(m_ORToolDecorationLoose) = (decoration ? (passedJVT_and_fJVT ? 2 : 1) : 0);; + + //decorate with b-tagging flags + std::vector<std::string> availableWPs = m_config->bTagWP_available(); + for (auto& WP : availableWPs) { + if (WP.find("Continuous") == std::string::npos) { + bool isTagged = false; + if (std::fabs(jetPtr->eta()) < 2.5) { + ToolHandle<IBTaggingSelectionTool>& btagsel = m_btagSelTools[WP]; + isTagged = static_cast<bool>(btagsel->accept(*jetPtr)); + } + jetPtr->auxdecor<char>("isbtagged_" + WP) = isTagged; + } else { + int tagWeightBin = -2; // AT default + if (std::fabs(jetPtr->eta()) < 2.5) { + ToolHandle<IBTaggingSelectionTool>& btagsel = m_btagSelTools[WP]; + tagWeightBin = btagsel->getQuantile(*jetPtr); + } + jetPtr->auxdecor<int>("tagWeightBin_" + WP) = tagWeightBin; + } } } + } } -} + } -void TopObjectSelection::applySelectionPreOverlapRemovalTrackJets() -{ - const xAOD::JetContainer* jets(nullptr); - top::check(evtStore()->retrieve(jets, m_config->sgKeyTrackJets()) , "TopObjectSelection::applySelectionPreOverlapRemovalTrackJets() failed to retrieve track jets" ); - for (auto jetPtr : *jets) { - char decoration = m_trackJetSelection->passSelection(*jetPtr); - jetPtr->auxdecor<char>( m_passPreORSelection ) = decoration; - if (m_doLooseCuts) { - jetPtr->auxdecor<char>( m_passPreORSelectionLoose ) = decoration; - } - std::vector<std::string> availableWPs = m_config->bTagWP_available_trkJet(); - for (auto& WP : availableWPs) { - if (WP!= "Continuous") { - bool isTagged = false; - if (std::fabs(jetPtr->eta()) < 2.5 ) { - ToolHandle<IBTaggingSelectionTool>& btagsel = m_trkjet_btagSelTools[WP]; - isTagged = btagsel->accept(*jetPtr); + void TopObjectSelection::applySelectionPreOverlapRemovalLargeRJets() { + for (auto currentSystematic : *m_config->systSgKeyMapLargeRJets()) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + + const xAOD::JetContainer* jets(nullptr); + top::check(evtStore()->retrieve(jets, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalLargeRJets() failed to retrieve large R jets"); + + for (auto jetPtr : *jets) { + //char decoration = m_largeJetSelection->passSelection(*jetPtr); + char decoration = '0'; + jetPtr->auxdecor<char>(m_passPreORSelection) = decoration; + jetPtr->auxdecor<char>(m_ORToolDecoration) = decoration * 2; + if (m_doLooseCuts) { + jetPtr->auxdecor<char>(m_passPreORSelectionLoose) = decoration; + jetPtr->auxdecor<char>(m_ORToolDecorationLoose) = decoration * 2; + } + } + } + } + + void TopObjectSelection::applySelectionPreOverlapRemovalTrackJets() { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (!m_executeNominal) return; + + const xAOD::JetContainer* jets(nullptr); + top::check(evtStore()->retrieve(jets, + m_config->sgKeyTrackJets()), + "TopObjectSelection::applySelectionPreOverlapRemovalTrackJets() failed to retrieve track jets"); + + + + for (const xAOD::Jet* jetPtr : *jets) { + //char decoration = m_trackJetSelection->passSelection(*jetPtr); + char decoration = '0'; + jetPtr->auxdecor<char>(m_passPreORSelection) = decoration; + if (m_doLooseCuts) { + jetPtr->auxdecor<char>(m_passPreORSelectionLoose) = decoration; + } + + if (m_config->sgKeyTrackJetsType() == "AntiKtVR30Rmax4Rmin02TrackJets") { // Event cleaning for variable-R track jets + float pt_baseline = 5e3; + float radius1 = std::max(0.02, std::min(0.4, 30000. / jetPtr->pt())); + + float dr_jets; + bool passDRcut = true; + for (const xAOD::Jet* jet2 : *jets) { + if (jet2->pt() < pt_baseline) continue; + if (jetPtr == jet2) continue; + + float radius2 = std::max(0.02, std::min(0.4, 30000. / jet2->pt())); + + dr_jets = xAOD::P4Helpers::deltaR(jetPtr, jet2, false); + if (dr_jets < std::min(radius1, radius2)) passDRcut = false; } - jetPtr->auxdecor<char>("isbtagged_"+WP) = isTagged; + jetPtr->auxdecor<char>("passDRcut") = passDRcut; } - else { - int tagWeightBin = -2; // AT default - if (std::fabs(jetPtr->eta()) < 2.5 ) { - ToolHandle<IBTaggingSelectionTool>& btagsel = m_btagSelTools[WP]; - tagWeightBin = btagsel->getQuantile(*jetPtr); + + std::vector<std::string> availableWPs = m_config->bTagWP_available_trkJet(); + for (auto& WP : availableWPs) { + if (WP.find("Continuous") == std::string::npos) { + bool isTagged = false; + if (std::fabs(jetPtr->eta()) < 2.5) { + ToolHandle<IBTaggingSelectionTool>& btagsel = m_trkjet_btagSelTools[WP]; + isTagged = static_cast<bool>(btagsel->accept(*jetPtr)); + } + jetPtr->auxdecor<char>("isbtagged_" + WP) = isTagged; + } else { + int tagWeightBin = -2; // AT default + if (std::fabs(jetPtr->eta()) < 2.5) { + ToolHandle<IBTaggingSelectionTool>& btagsel = m_trkjet_btagSelTools[WP]; + tagWeightBin = btagsel->getQuantile(*jetPtr); + } + jetPtr->auxdecor<int>("tagWeightBin_" + WP) = tagWeightBin; } - jetPtr->auxdecor<int>("tagWeightBin") = tagWeightBin; } } } -} -StatusCode TopObjectSelection::applyOverlapRemoval() -{ - bool aLooseEvent(true),aTightEvent(false); - if (!m_config->doLooseTreeOnly()) { - top::check( applyOverlapRemoval(aTightEvent,m_config->sgKeyTopSystematicEvents()) , "Failed to apply overlap removal" ); - } - if (m_config->doLooseEvents()) { - top::check( applyOverlapRemoval(aLooseEvent,m_config->sgKeyTopSystematicEventsLoose()) , "Failed to apply overlap removal" ); - } - return StatusCode::SUCCESS; -} +void TopObjectSelection::applySelectionPreOverlapRemovalJetGhostTracks() { + + auto jetsystematic = *m_config->systSgKeyMapJets(false); + CP::SystematicSet nominal; + std::size_t m_nominalHashValue = nominal.hash(); + + for (auto currentSystematic : *m_config->systMapJetGhostTrack()) { + + // At this point some specific jet collection doesn't exist for tracking systematic so use the nominal jet collection to retrieve the ghost tracks + std::unordered_map<std::size_t, std::string>::const_iterator jetsyst_name = jetsystematic.find(currentSystematic.first); + if (jetsyst_name == jetsystematic.end()) { + jetsyst_name = jetsystematic.find(m_nominalHashValue); + } + + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; -StatusCode TopObjectSelection::applyOverlapRemoval(const bool isLoose,const std::string& sgKey) -{ - // create the xAOD::SystematicEventContainer - xAOD::SystematicEventAuxContainer* systEventAuxCont = new xAOD::SystematicEventAuxContainer{}; - xAOD::SystematicEventContainer* systEventCont = new xAOD::SystematicEventContainer{}; - systEventCont->setStore( systEventAuxCont ); - - for (auto systematicNumber : *m_config->systHashAll()) { - xAOD::SystematicEvent* systEvent = new xAOD::SystematicEvent{}; - systEventCont->push_back( systEvent ); - systEvent->setHashValue( systematicNumber ); - systEvent->setIsLooseEvent( isLoose ); - if (!isLoose) {systEvent->setTtreeIndex( m_config->ttreeIndex( systematicNumber ) );} - if (isLoose) {systEvent->setTtreeIndex( m_config->ttreeIndexLoose( systematicNumber ) );} - systEvent->auxdecor<char> (m_config->passEventSelectionDecoration()) = 0; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; - top::check( applyOverlapRemoval( systEvent ) , "Failed to apply overlap removal" ); - } - - // Save to StoreGate / TStore - std::string outputSGKeyAux = sgKey + "Aux."; - - xAOD::TReturnCode save = evtStore()->tds()->record( systEventCont ,sgKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( systEventAuxCont , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; + + const xAOD::JetContainer* jets(nullptr); + top::check(evtStore()->retrieve(jets, + (*jetsyst_name).second), + "TopObjectSelection::applySelectionPreOverlapRemovalJetGhostTracks() failed to retrieve jets"); + ATH_MSG_DEBUG(" Cut on JetsGhostTracks with key = " << (*jetsyst_name).second); + + + + for (auto jetPtr : *jets) + { + if(!m_jetGhostTrackSelection->JetConsideredForGhostTrackSelection(jetPtr->pt(),jetPtr->eta())) continue; + + + std::vector<const xAOD::TrackParticle*> jetTracks; + + jetTracks = jetPtr->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack(currentSystematic.first)); + + if (jetTracks.size() == 0){ + ATH_MSG_WARNING("TopObjectSelection::applySelectionPreOverlapRemovalJetGhostTracks() failed to retrieve tracks, jet pT and eta:" << jetPtr->pt() << " " << std::fabs(jetPtr->eta()) ); + continue; + } + + const xAOD::VertexContainer* vertices = nullptr; + top::check(evtStore() -> retrieve( vertices, "PrimaryVertices" ), "Failed to get primary vertices"); + const auto it_pv = std::find_if(vertices->cbegin(), vertices->cend(), + [](const xAOD::Vertex* vtx) + {return vtx->vertexType() == xAOD::VxType::PriVtx;}); + const xAOD::Vertex* primaryVertex = (it_pv == vertices->cend()) ? nullptr : *it_pv; + if (primaryVertex == nullptr) ATH_MSG_WARNING("TopObjectSelection No primary vertex found." ); + + + + for (auto jetTrIt : jetTracks){ + + //Decorate the tracks with a flag "passPreORSelection" to indicate if they passed the selection + //jetTrIt->auxdecor<char>(m_passPreORSelection) = m_jetGhostTrackSelection->passSelection(*jetTrIt, *primaryVertex); + jetTrIt->auxdecor<char>(m_passPreORSelection) = '0'; + jetTrIt->auxdecor<char>(m_ORToolDecoration) = jetTrIt->auxdataConst<char>(m_passPreORSelection) * 2; + + } + + } + } } - return StatusCode::SUCCESS; -} -StatusCode TopObjectSelection::applyOverlapRemoval(xAOD::SystematicEvent* currentSystematic) { + void TopObjectSelection::applySelectionPreOverlapRemovalTracks() { - // Which lepton definition are we using for the overlap removal? - // Default for top analysis is "Tight" - // - // Use "Loose" for Fakes estimates - // - // Other physics groups choose to do overlap removal on "Loose" lepton definitions - // As such, this mode is fully supported, simply set: - // OverlapRemovalLeptonDef Loose - // In your configuration file + for (auto currentSystematic : *m_config->systSgKeyMapTracks()) { + + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic.first))) continue; + + const xAOD::TrackParticleContainer* tracks(nullptr); + top::check(evtStore()->retrieve(tracks, + currentSystematic.second), + "TopObjectSelection::applySelectionPreOverlapRemovalTracks() failed to retrieve tracks"); + + ATH_MSG_DEBUG(" Cut on Tracks with key = " << currentSystematic.second); + + const xAOD::VertexContainer* vertices = nullptr; + + top::check(evtStore() -> retrieve( vertices, "PrimaryVertices" ), "Failed to get primary vertices"); + const auto it_pv = std::find_if(vertices->cbegin(), vertices->cend(), + [](const xAOD::Vertex* vtx) + {return vtx->vertexType() == xAOD::VxType::PriVtx;}); + const xAOD::Vertex* primaryVertex = (it_pv == vertices->cend()) ? nullptr : *it_pv; + if (primaryVertex == nullptr) ATH_MSG_WARNING("TopObjectSelection. No primary vertex found." ); + + + int counter = 0; + + for (auto trackPtr : *tracks) { + + //trackPtr -> auxdecor<char>(m_passPreORSelection) = m_trackSelection->passSelection(*trackPtr, *primaryVertex); + trackPtr->auxdecor<char>(m_passPreORSelection) = '0'; + trackPtr -> auxdecor<char>(m_ORToolDecoration) = trackPtr->auxdataConst<char>(m_passPreORSelection) * 2; + + counter++; + + + } + } + + } + - bool looseLeptonOR(false); // default behaviour for top analysis - use the "Tight" definitions - if (currentSystematic->isLooseEvent()) { - looseLeptonOR = true; + StatusCode TopObjectSelection::applyOverlapRemoval() { + bool aLooseEvent(true), aTightEvent(false); + + if (m_config->doTightEvents()) { + top::check(applyOverlapRemoval(aTightEvent, + m_config->sgKeyTopSystematicEvents()), "Failed to apply overlap removal"); + } + if (m_config->doLooseEvents()) { + top::check(applyOverlapRemoval(aLooseEvent, + m_config->sgKeyTopSystematicEventsLoose()), "Failed to apply overlap removal"); + } + return StatusCode::SUCCESS; } - if (m_config->doOverlapRemovalOnLooseLeptonDef()) { - looseLeptonOR = true; + + StatusCode TopObjectSelection::applyOverlapRemoval(const bool isLoose, const std::string& sgKey) { + // create the xAOD::SystematicEventContainer + xAOD::SystematicEventAuxContainer* systEventAuxCont = new xAOD::SystematicEventAuxContainer {}; + xAOD::SystematicEventContainer* systEventCont = new xAOD::SystematicEventContainer {}; + systEventCont->setStore(systEventAuxCont); + + // We need to be able to have the nominal systematic processed first + // but we cannot alter this inside TopConfig as we use unordered_set + // Using an ordered set will only order on hash and not on insertion + // so we still cannot control it there + // Best place to handle it is when the systematic object container is being filled (before it is const) + // We read all hashes into a vector, and then custom sort to be nominal, then alphabetical + std::vector<size_t> sortedSystHashAll(m_config->systHashAll()->begin(), m_config->systHashAll()->end()); + std::sort(sortedSystHashAll.begin(), sortedSystHashAll.end(), + [this](const size_t& lhs, const size_t& rhs) { + // if lhs is nominal, true - move + if (this->m_config->isSystNominal(this->m_config->systematicName(lhs))) return true; + // if rhs is nominal, false - fix + else if (this->m_config->isSystNominal(this->m_config->systematicName(rhs))) return false; + // otherwise alphabetical - sort + else return(this->m_config->systematicName(lhs) < this->m_config->systematicName(rhs)); + }); + + for (auto systematicNumber : sortedSystHashAll) { + ATH_MSG_DEBUG(systematicNumber << " " << m_config->systematicName(systematicNumber)); + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (m_executeNominal && !m_config->isSystNominal(m_config->systematicName(systematicNumber))) continue; + if (!m_executeNominal && m_config->isSystNominal(m_config->systematicName(systematicNumber))) continue; + + if ((!m_config->doTightSysts() && !isLoose) && + !m_config->isSystNominal(m_config->systematicName(systematicNumber))) continue; + if ((!m_config->doLooseSysts() && isLoose) && + !m_config->isSystNominal(m_config->systematicName(systematicNumber))) continue; + + xAOD::SystematicEvent* systEvent = new xAOD::SystematicEvent {}; + systEventCont->push_back(systEvent); + systEvent->setHashValue(systematicNumber); + systEvent->setIsLooseEvent(isLoose); + if (!isLoose) { + systEvent->setTtreeIndex(m_config->ttreeIndex(systematicNumber)); + } + if (isLoose) { + systEvent->setTtreeIndex(m_config->ttreeIndexLoose(systematicNumber)); + } + systEvent->auxdecor<char> (m_config->passEventSelectionDecoration()) = 0; + top::check(applyOverlapRemoval(systEvent), "Failed to apply overlap removal"); + } + + if (m_executeNominal) { + // Create a new StoreGate key + std::string sgKeyNominal = sgKey + "Nominal"; + + // Save to StoreGate / TStore + std::string outputSGKeyNominalAux = sgKeyNominal + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(systEventCont, sgKeyNominal); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(systEventAuxCont, outputSGKeyNominalAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } else { + // Retrieve nominal container, get nominal event, copy into full systematic container + xAOD::SystematicEventContainer* systEventContNominal = new xAOD::SystematicEventContainer {}; + top::check(evtStore()->retrieve(systEventContNominal, sgKey + "Nominal"), "Failed to retrieve nominal container"); + for (auto x: *systEventContNominal) { + xAOD::SystematicEvent* systEventNominal = new xAOD::SystematicEvent {}; + systEventCont->push_back(systEventNominal); + *systEventNominal = *x; + } + + // Save to StoreGate / TStore + std::string outputSGKeyAux = sgKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(systEventCont, sgKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(systEventAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } } - - std::size_t hash = currentSystematic->hashValue(); - // Retrieve the relevant shallow copies - const xAOD::PhotonContainer* xaod_photon(nullptr); - if (m_config->usePhotons()) - top::check(evtStore()->retrieve(xaod_photon, m_config->sgKeyPhotons(hash)) , "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve photons"); + StatusCode TopObjectSelection::applyOverlapRemoval(xAOD::SystematicEvent* currentSystematic) { + // Which lepton definition are we using for the overlap removal? + // Default for top analysis is "Tight" + // + // Use "Loose" for Fakes estimates + // + // Other physics groups choose to do overlap removal on "Loose" lepton definitions + // As such, this mode is fully supported, simply set: + // OverlapRemovalLeptonDef Loose + // In your configuration file + + bool looseLeptonOR(false); // default behaviour for top analysis - use the "Tight" definitions + + if (currentSystematic->isLooseEvent()) { + looseLeptonOR = true; + } + if (m_config->doOverlapRemovalOnLooseLeptonDef()) { + looseLeptonOR = true; + } + + std::size_t hash = currentSystematic->hashValue(); - const xAOD::ElectronContainer* xaod_el(nullptr); - if (m_config->useElectrons()) - top::check(evtStore()->retrieve(xaod_el, m_config->sgKeyElectrons(hash)) , "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve electrons" ); - const xAOD::MuonContainer* xaod_mu(nullptr); - if (m_config->useMuons()) - top::check(evtStore()->retrieve(xaod_mu, m_config->sgKeyMuons(hash)) , "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve muons" ); - - const xAOD::TauJetContainer* xaod_tau(nullptr); - if (m_config->useTaus()) - top::check(evtStore()->retrieve(xaod_tau, m_config->sgKeyTaus(hash)) , "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve taus"); - - const xAOD::JetContainer* xaod_jet(nullptr); - if (m_config->useJets()) - top::check(evtStore()->retrieve(xaod_jet, m_config->sgKeyJets(hash,looseLeptonOR)) , "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve jets" ); + // Retrieve the relevant shallow copies + const xAOD::PhotonContainer* xaod_photon(nullptr); + if (m_config->usePhotons()) top::check(evtStore()->retrieve(xaod_photon, m_config->sgKeyPhotons( + hash)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve photons"); - const xAOD::JetContainer* xaod_ljet(nullptr); - if (m_config->useLargeRJets()) - top::check(evtStore()->retrieve(xaod_ljet, m_config->sgKeyLargeRJets(hash)) , "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve large-R jets"); - const xAOD::JetContainer* xaod_tjet(nullptr); - if (m_config->useTrackJets()) - top::check(evtStore()->retrieve(xaod_tjet, m_config->sgKeyTrackJets()) , "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve track jets"); - - // vectors to store the indices of objects passing selection and overlap removal - std::vector<unsigned int> goodPhotons,goodElectrons,goodMuons,goodTaus,goodJets,goodLargeRJets,goodTrackJets; - - // Apply overlap removal - m_overlapRemovalToolPostSelection->overlapremoval(xaod_photon,xaod_el,xaod_mu,xaod_tau, - xaod_jet,xaod_ljet, - goodPhotons,goodElectrons,goodMuons,goodTaus, - goodJets,goodLargeRJets,looseLeptonOR); - - // Additonal lepton information - std::vector<unsigned int> overlapsEl,overlapsMu; - if (m_overlapRemovalToolPostSelection->overlapsEl(overlapsEl) ) { - currentSystematic->auxdecor< std::vector<unsigned int> >("overlapsEl") = overlapsEl; - } - if (m_overlapRemovalToolPostSelection->overlapsMu(overlapsMu) ) { - currentSystematic->auxdecor< std::vector<unsigned int> >("overlapsMu") = overlapsMu; - } - + const xAOD::ElectronContainer* xaod_el(nullptr); + if (m_config->useElectrons()) top::check(evtStore()->retrieve(xaod_el, m_config->sgKeyElectrons( + hash)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve electrons"); - - // If we did use overlap removal on "Loose" lepton definitions - // We take the remaining leptons and only keep those passing the "Tight" cuts - if (!currentSystematic->isLooseEvent() && m_config->doOverlapRemovalOnLooseLeptonDef()) { - applyTightSelectionPostOverlapRemoval( xaod_photon , goodPhotons ); - applyTightSelectionPostOverlapRemoval( xaod_el , goodElectrons ); - applyTightSelectionPostOverlapRemoval( xaod_mu , goodMuons ); - applyTightSelectionPostOverlapRemoval( xaod_tau , goodTaus ); - applyTightSelectionPostOverlapRemoval( xaod_jet , goodJets ); - applyTightSelectionPostOverlapRemoval( xaod_ljet , goodLargeRJets ); + + const xAOD::ElectronContainer* xaod_fwdel(nullptr); + if (m_config->useFwdElectrons()) top::check(evtStore()->retrieve(xaod_fwdel, m_config->sgKeyFwdElectrons( + hash)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve fwd electrons"); + + + const xAOD::MuonContainer* xaod_mu(nullptr); + if (m_config->useMuons()) top::check(evtStore()->retrieve(xaod_mu, m_config->sgKeyMuons( + hash)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve muons"); + + + const xAOD::MuonContainer* xaod_softmu(nullptr); + if (m_config->useSoftMuons()) top::check(evtStore()->retrieve(xaod_softmu, m_config->sgKeySoftMuons( + hash)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve soft muons"); + + + const xAOD::TauJetContainer* xaod_tau(nullptr); + if (m_config->useTaus()) top::check(evtStore()->retrieve(xaod_tau, m_config->sgKeyTaus( + hash)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve taus"); + + + const xAOD::JetContainer* xaod_jet(nullptr); + if (m_config->useJets()) top::check(evtStore()->retrieve(xaod_jet, m_config->sgKeyJets(hash, + looseLeptonOR)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve jets"); + + + const xAOD::JetContainer* xaod_ljet(nullptr); + if (m_config->useLargeRJets()) top::check(evtStore()->retrieve(xaod_ljet, m_config->sgKeyLargeRJets( + hash)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve large-R jets"); + + + const xAOD::JetContainer* xaod_tjet(nullptr); + if (m_config->useTrackJets()) top::check(evtStore()->retrieve(xaod_tjet, + m_config->sgKeyTrackJets()), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve track jets"); + + const xAOD::TrackParticleContainer* xaod_tracks(nullptr); + if (m_config->useTracks()) top::check(evtStore()->retrieve(xaod_tracks, + m_config->sgKeyTracks(hash)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve tracks"); + + + // vectors to store the indices of objects passing selection and overlap removal + std::vector<unsigned int> goodPhotons, goodElectrons, goodFwdElectrons, goodMuons, goodSoftMuons, goodTaus, + goodJets, goodLargeRJets, goodTrackJets, goodTracks; + + // Apply overlap removal + m_overlapRemovalToolPostSelection->overlapremoval(xaod_photon, xaod_el, xaod_mu, xaod_tau, + xaod_jet, xaod_ljet, + goodPhotons, goodElectrons, goodMuons, goodTaus, + goodJets, goodLargeRJets, looseLeptonOR); + + // Additonal lepton information + std::vector<unsigned int> overlapsEl, overlapsMu; + if (m_overlapRemovalToolPostSelection->overlapsEl(overlapsEl)) { + currentSystematic->auxdecor< std::vector<unsigned int> >("overlapsEl") = overlapsEl; + } + if (m_overlapRemovalToolPostSelection->overlapsMu(overlapsMu)) { + currentSystematic->auxdecor< std::vector<unsigned int> >("overlapsMu") = overlapsMu; + } + + // If we did use overlap removal on "Loose" lepton definitions + // We take the remaining leptons and only keep those passing the "Tight" cuts + if (!currentSystematic->isLooseEvent() && m_config->doOverlapRemovalOnLooseLeptonDef()) { + applyTightSelectionPostOverlapRemoval(xaod_photon, goodPhotons); + applyTightSelectionPostOverlapRemoval(xaod_el, goodElectrons); + applyTightSelectionPostOverlapRemoval(xaod_mu, goodMuons); + applyTightSelectionPostOverlapRemoval(xaod_tau, goodTaus); + applyTightSelectionPostOverlapRemoval(xaod_jet, goodJets); + applyTightSelectionPostOverlapRemoval(xaod_ljet, goodLargeRJets); + } + + if (m_config->useTrackJets()) { + for (unsigned int i = 0; i < xaod_tjet->size(); ++i) goodTrackJets.push_back(i); + trackJetOverlapRemoval(xaod_el, xaod_mu, xaod_tjet, goodElectrons, goodMuons, goodTrackJets); + applyTightSelectionPostOverlapRemoval(xaod_tjet, goodTrackJets); + } + + // for the time being no OR applied on FwdElectrons + if (xaod_fwdel) { + int i(0); + std::string passTopCuts(""); + if (!looseLeptonOR) { + passTopCuts = "passPreORSelection"; + } + if (looseLeptonOR) { + passTopCuts = "passPreORSelectionLoose"; + } + for (const xAOD::Electron* x: *xaod_fwdel) { + if (x->auxdataConst< char >(passTopCuts) == 1) goodFwdElectrons.push_back(i); + + i++; + } + } + + // no OR applied on tracks + if (xaod_tracks) { + int i(0); + std::string passTopCuts = "passPreORSelection"; + + for (const xAOD::TrackParticle* x: *xaod_tracks) { + + if (x->auxdataConst< char >(m_passPreORSelection) == 1) goodTracks.push_back(i); + + i++; + } + } + + + // for the time being the only OR performed on soft muons is wrt prompt muons + if (xaod_softmu) { + + if(m_config->useJets()) + { + top::check(m_overlapRemovalTool_softMuons_Alljets->removeOverlaps(nullptr, xaod_softmu, xaod_jet, nullptr, nullptr), "Failed to identify overlap for soft muons - all jets"); + if(m_config->useParticleFlowJets())top::check(m_overlapRemovalTool_softMuons_PFjets->removeOverlaps(nullptr, xaod_softmu, xaod_jet, nullptr, nullptr), "Failed to identify overlap for soft muons - PFlow jets"); + } + + int i(0); + std::string passTopCuts = "passPreORSelection"; + + for (const xAOD::Muon* x: *xaod_softmu) { + //OR with prompt muons + bool promptMuOR = false; + if (xaod_mu) { + for (unsigned int iMu : goodMuons) { + // Get muon iMu + const xAOD::Muon* muPtr = xaod_mu->at(iMu); + if (muPtr->p4().DeltaR(x->p4()) < 0.01) { + promptMuOR = true; + break; + } + } + } + + float dRmin = 100; //nearest jet dR + if(m_config->useJets()) dRmin=this->calculateMinDRMuonJet(*x, xaod_jet, goodJets, m_config->softmuonDRJetcutUseRapidity()); + + if (x->auxdataConst< char >(passTopCuts) == 1 && !promptMuOR && (!m_config->useJets() || dRmin < m_config->softmuonDRJetcut())) + { + goodSoftMuons.push_back(i);//the dR selection must be done here, because we need the post-OR jets... + } + i++; + } + }//end of OR procedure for soft muons + + if(m_config->isMC() && m_config->useSoftMuons() && m_config->softmuonAdditionalTruthInfo()) decorateSoftMuonsPostOverlapRemoval(xaod_softmu,goodSoftMuons); + + + //Change the collection of ghost tracks associated to jets + //Store the selected ghost associated tracks + //It doesn't work for the nominal systematic + if (m_config->useJetGhostTrack() && m_config->useJets()) { + + std::vector<const xAOD::TrackParticle*> jetTracks; + + xAOD::JetContainer* xaod_jet_ga(nullptr); + top::check(evtStore()->retrieve(xaod_jet_ga, m_config->sgKeyJets(hash,looseLeptonOR)), + "TopObjectSelection::applyOverlapRemovalPostSelection() failed to retrieve jets for ghost matching"); + + unsigned int index= -1; + + for (const auto jetPtr : *xaod_jet_ga){ + + index=index+1; + + if(!m_jetGhostTrackSelection->JetConsideredForGhostTrackSelection(jetPtr->pt(),jetPtr->eta())) + continue; + + if (std::find(goodJets.begin(), goodJets.end(), index) == goodJets.end()){ + continue; + } + + jetTracks.clear(); + + std::vector<const xAOD::TrackParticle*> goodJetGhostTracks; + jetTracks = jetPtr->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack(hash)); + + if (jetTracks.size() != 0) { + + std::string passTopCuts = "passPreORSelection"; + + for (auto& track: jetTracks) { + + if (track->auxdataConst< char >(passTopCuts) == 1) { + goodJetGhostTracks.push_back(track); + } + + } + + jetPtr->setAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack(hash), goodJetGhostTracks); + + } + } + + } + + // set the indices in the xAOD::SystematicEvent + currentSystematic->setGoodPhotons(goodPhotons); + currentSystematic->setGoodElectrons(goodElectrons); + currentSystematic->setGoodFwdElectrons(goodFwdElectrons); + currentSystematic->setGoodMuons(goodMuons); + currentSystematic->setGoodSoftMuons(goodSoftMuons); + currentSystematic->setGoodTaus(goodTaus); + currentSystematic->setGoodJets(goodJets); + currentSystematic->setGoodLargeRJets(goodLargeRJets); + currentSystematic->setGoodTrackJets(goodTrackJets); + currentSystematic->setGoodTracks(goodTracks); + + decorateEventInfoPostOverlapRemoval(goodJets.size(), currentSystematic->isLooseEvent()); + + + + return StatusCode::SUCCESS; } - if (m_config->useTrackJets()){ - for (unsigned int i=0; i<xaod_tjet->size(); ++i) goodTrackJets.push_back(i); - trackJetOverlapRemoval(xaod_el, xaod_mu, xaod_tjet, goodElectrons, goodMuons, goodTrackJets); - applyTightSelectionPostOverlapRemoval( xaod_tjet , goodTrackJets ); - } - - // set the indices in the xAOD::SystematicEvent - currentSystematic->setGoodPhotons( goodPhotons ); - currentSystematic->setGoodElectrons( goodElectrons ); - currentSystematic->setGoodMuons( goodMuons ); - currentSystematic->setGoodTaus( goodTaus ); - currentSystematic->setGoodJets( goodJets ); - currentSystematic->setGoodLargeRJets( goodLargeRJets ); - currentSystematic->setGoodTrackJets( goodTrackJets ); - - return StatusCode::SUCCESS; -} + void TopObjectSelection::decorateSoftMuonsPostOverlapRemoval(const xAOD::MuonContainer* xaod_softmu,std::vector<unsigned int>& goodSoftMuons) + { -void TopObjectSelection::applyTightSelectionPostOverlapRemoval( const xAOD::IParticleContainer* xaod , std::vector<unsigned int>& indices ) -{ - // Copy the original indices of the xAOD objects in - // the collection that pass the overlap removal - std::vector<unsigned int> tmpCopy; - for (auto i : indices) { - tmpCopy.push_back( i ); + for (auto iMu : goodSoftMuons) { + // Get muon iMu + const xAOD::Muon* muon = xaod_softmu->at(iMu); + + top::truth::initRecoMuonHistoryInfo(muon,m_config->softmuonAdditionalTruthInfoCheckPartonOrigin()); //it's safer if we initialize everything to default for each muon before filling the muon history + top::truth::getRecoMuonHistory(muon,m_config->softmuonAdditionalTruthInfoCheckPartonOrigin(),m_config->getShoweringAlgorithm(),m_config->softmuonAdditionalTruthInfoDoVerbose()); + }//end of loop on soft muons } - - // Clear the original indices - indices.clear(); - - // Only save indices that are in tmpCopy && passPreORSelection - // This will keep the objects that pass the "Loose" overlap selection - // and pass the "Tight" cuts - for (auto i : tmpCopy) { - if (xaod->at(i)->isAvailable< char> ( m_passPreORSelection )) { - if (xaod->at(i)->auxdataConst< char >( m_passPreORSelection ) == 1) { - indices.push_back( i ); + void TopObjectSelection::applyTightSelectionPostOverlapRemoval(const xAOD::IParticleContainer* xaod, + std::vector<unsigned int>& indices) { + // Copy the original indices of the xAOD objects in + // the collection that pass the overlap removal + std::vector<unsigned int> tmpCopy; + for (auto i : indices) { + tmpCopy.push_back(i); + } + + // Clear the original indices + indices.clear(); + + // Only save indices that are in tmpCopy && passPreORSelection + // This will keep the objects that pass the "Loose" overlap selection + // and pass the "Tight" cuts + for (auto i : tmpCopy) { + if (xaod->at(i)->isAvailable< char> (m_passPreORSelection)) { + if (xaod->at(i)->auxdataConst< char >(m_passPreORSelection) == 1) { + indices.push_back(i); + } } } } -} -void TopObjectSelection::trackJetOverlapRemoval(const xAOD::IParticleContainer* xaod_el, - const xAOD::IParticleContainer* xaod_mu, - const xAOD::IParticleContainer* xaod_tjet, - std::vector<unsigned int>& goodElectrons, - std::vector<unsigned int>& goodMuons, - std::vector<unsigned int>& goodTrackJets) -{ - - // Copy the original indices of the xAOD objects in - // the collection that pass the overlap removal - std::vector<unsigned int> tmpGoodTrackJets; - for (auto i : goodTrackJets) { - tmpGoodTrackJets.push_back( i ); - } - - // Clear the original indices - goodTrackJets.clear(); - - int counterTrk = 0; - for (auto jet : *xaod_tjet){ - bool matchEl(false); - int counterEl = 0; - for (auto el : *xaod_el){ - if ((std::find(goodElectrons.begin(), goodElectrons.end(), counterEl) != goodElectrons.end())){ - if ( el->p4().DeltaR(jet->p4())<0.2){ - matchEl = true; - break; + void TopObjectSelection::trackJetOverlapRemoval(const xAOD::IParticleContainer* xaod_el, + const xAOD::IParticleContainer* xaod_mu, + const xAOD::IParticleContainer* xaod_tjet, + std::vector<unsigned int>& goodElectrons, + std::vector<unsigned int>& goodMuons, + std::vector<unsigned int>& goodTrackJets) { + // Copy the original indices of the xAOD objects in + // the collection that pass the overlap removal + std::vector<unsigned int> tmpGoodTrackJets; + for (auto i : goodTrackJets) { + tmpGoodTrackJets.push_back(i); + } + + // Clear the original indices + goodTrackJets.clear(); + + int counterTrk = 0; + for (auto jet : *xaod_tjet) { + bool matchEl(false); + int counterEl = 0; + for (auto el : *xaod_el) { + if ((std::find(goodElectrons.begin(), goodElectrons.end(), counterEl) != goodElectrons.end())) { + if (el->p4().DeltaR(jet->p4()) < 0.2) { + matchEl = true; + break; + } } + counterEl++; } - counterEl++; - } - bool matchMu(false); - int counterMu = 0; - for (auto mu : *xaod_mu){ - if ((std::find(goodMuons.begin(), goodMuons.end(), counterMu) != goodMuons.end())){ - if ( mu->p4().DeltaR(jet->p4())<0.2){ - matchMu = true; - break; + bool matchMu(false); + int counterMu = 0; + for (auto mu : *xaod_mu) { + if ((std::find(goodMuons.begin(), goodMuons.end(), counterMu) != goodMuons.end())) { + if (mu->p4().DeltaR(jet->p4()) < 0.2) { + matchMu = true; + break; + } } + counterMu++; } - counterMu++; + + if (!(matchEl || matchMu)) goodTrackJets.push_back(counterTrk); + counterTrk++; } + } - if (!(matchEl || matchMu)) goodTrackJets.push_back(counterTrk); - counterTrk++; + float TopObjectSelection::calculateMinDRMuonJet(const xAOD::Muon& mu, const xAOD::JetContainer* xaod_jet, std::vector<unsigned int>& goodJets, bool useRapidity) { + + float dRMin = 100.0; + + // Loop over jets, calculate dR and record smallest value + for (auto iJet : goodJets) { + const xAOD::Jet* jetPtr = xaod_jet->at(iJet); + if(jetPtr->isAvailable<char>("passJVT") && !(jetPtr->auxdataConst<char>("passJVT") )) continue; //at this level we still have jets not passing the JVT cut in the ntuple + float dR = xAOD::P4Helpers::deltaR(mu,*jetPtr,useRapidity); + if (dR < dRMin) + { + dRMin = dR; + } + } + + return dRMin; } -} -void TopObjectSelection::print() const -{ - asg::AsgTool::print(); -} + void TopObjectSelection::decorateEventInfoPostOverlapRemoval(int nGoodJets, bool isLoose) { + ///-- Decorate event info with number of nominal jets for flavour composition + // Only continue if this is nominal processing + if (!m_executeNominal) return; -void TopObjectSelection::print(std::ostream& os) const { + bool UseLooseNJets = false; + // If we only run on loose nominal, we need to use loose event, otherwise use tight + if (m_config->doLooseEvents() && !m_config->doTightEvents()) UseLooseNJets = true; + // If we use loose, but this is tight, skip + if (UseLooseNJets && !isLoose) return; + + // Get the EventInfo object + const xAOD::EventInfo* eventInfo(nullptr); + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); + // Decorate with number of good jets + eventInfo->auxdecor< int >("Njet") = nGoodJets; + + return; + } + + void TopObjectSelection::print() const { + asg::AsgTool::print(); + } + + void TopObjectSelection::print(std::ostream& os) const { os << "TopObjectSelection configuration\n"; os << "\n"; os << "Electrons\n"; os << " ContainerName: " << m_config->sgKeyElectrons() << "\n"; if (m_config->useElectrons()) { - os << " Selection: "; - if (!m_electronSelection) - os << "All"; - else - os << *m_electronSelection; + os << " Selection: "; + if (!m_electronSelection) os << "All"; + else os << *m_electronSelection; + } + + os << "\n"; + os << "FwdElectrons\n"; + os << " ContainerName: " << m_config->sgKeyFwdElectrons() << "\n"; + if (m_config->useFwdElectrons()) { + os << " Selection: "; + if (!m_fwdElectronSelection) os << "All"; + else os << *m_fwdElectronSelection; } os << "\n"; os << "Photons\n"; os << " ContainerName: " << m_config->sgKeyPhotons() << "\n"; if (m_config->usePhotons()) { - os << " Selection: "; - if (!m_photonSelection) - os << "All"; - else - os << *m_photonSelection; + os << " Selection: "; + if (!m_photonSelection) os << "All"; + else os << *m_photonSelection; } os << "\n"; os << "Muons\n"; os << " ContainerName: " << m_config->sgKeyMuons() << "\n"; if (m_config->useMuons()) { - os << " Selection: "; - if (!m_muonSelection) - os << "All"; - else - os << *m_muonSelection; + os << " Selection: "; + if (!m_muonSelection) os << "All"; + else os << *m_muonSelection; + } + + os << "\n"; + os << "SoftMuons\n"; + os << " ContainerName: " << m_config->sgKeySoftMuons() << "\n"; + if (m_config->useSoftMuons()) { + os << " Selection: "; + if (!m_softmuonSelection) os << "All"; + else os << *m_softmuonSelection; } // // os << "\n"; @@ -665,23 +1242,30 @@ void TopObjectSelection::print(std::ostream& os) const { os << "Jets\n"; os << " ContainerName: " << m_config->sgKeyJets() << "\n"; if (m_config->useJets()) { - os << " Selection: "; - if (!m_jetSelection) - os << "All"; - else - os << *m_jetSelection; + os << " Selection: "; + if (!m_jetSelection) os << "All"; + else os << *m_jetSelection; } os << "\n"; os << "LargeJets\n"; os << " ContainerName: " << m_config->sgKeyLargeRJets() << "\n"; if (m_config->useLargeRJets()) { - os << " Selection: "; - if (!m_largeJetSelection) - os << "All"; - else - os << *m_largeJetSelection; + os << " Selection: "; + if (!m_largeJetSelection) os << "All"; + else os << *m_largeJetSelection; } + + os << "\n"; + os << "GhostTracks\n"; + os << " ContainerName: " << m_config->decoKeyJetGhostTrack() << "\n"; + if (m_config->useJetGhostTrack()) { + os << " Selection: "; + if (!m_jetGhostTrackSelection) os << "All"; +// else m_jetGhostTrackSelection->print(os); + else os << *m_jetGhostTrackSelection; + } + os << "\n"; os << "MET\n"; @@ -689,12 +1273,9 @@ void TopObjectSelection::print(std::ostream& os) const { os << "\n\n"; os << "OverlapRemoval after object selection: "; - if (!m_overlapRemovalToolPostSelection) - os << "None"; - else - os << *m_overlapRemovalToolPostSelection; + if (!m_overlapRemovalToolPostSelection) os << "None"; + else os << *m_overlapRemovalToolPostSelection; os << "\n\n"; -} - + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackJetMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackJetMC15.cxx index daad4eeaee7e..dc483cb11860 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackJetMC15.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackJetMC15.cxx @@ -1,38 +1,33 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/TrackJetMC15.h" -namespace top{ - - TrackJetMC15::TrackJetMC15(const double ptcut,const double etamax) : +namespace top { + TrackJetMC15::TrackJetMC15(const double ptcut, const double etamax) : m_ptcut(ptcut), m_etamax(etamax) { - } + } TrackJetMC15::~TrackJetMC15() { } bool TrackJetMC15::passSelection(const xAOD::Jet& jet) { - - if (jet.pt() < m_ptcut) - return false; + if (jet.pt() < m_ptcut) return false; - if (std::fabs(jet.eta()) > m_etamax) - return false; + if (std::fabs(jet.eta()) > m_etamax) return false; // See https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TrackJetSelectionRecAndGuide - if (jet.numConstituents() < 2) - return false; + if (jet.numConstituents() < 2) return false; return true; } void TrackJetMC15::print(std::ostream& os) const { os << "Track jet\n" - << " * pT > " << m_ptcut << "\n" - << " * |eta| < " << m_etamax << "\n" - << " * >= 2 tracks \n"; + << " * pT > " << m_ptcut << "\n" + << " * |eta| < " << m_etamax << "\n" + << " * >= 2 tracks \n"; } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackSelection.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackSelection.cxx new file mode 100644 index 000000000000..118f01a48f06 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackSelection.cxx @@ -0,0 +1,54 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopObjectSelectionTools/TrackSelection.h" +#include "InDetTrackSelectionTool/InDetTrackSelectionTool.h" + +#include "xAODTracking/TrackParticle.h" +#include "xAODTracking/Vertex.h" + +#include "TopEvent/EventTools.h" + +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +#include "TopObjectSelectionTools/MsgCategory.h" +using namespace TopObjectSelectionTools; + +namespace top { + + TrackSelection::TrackSelection(const double ptcut, const double etamax) : + m_ptcut(ptcut), + m_etamax(etamax), + m_trkseltool("TrkSelTool") + { + + top::check(m_trkseltool.retrieve(), "Failed to retrieve InDetTrackSelectionTool"); + + } + + TrackSelection::~TrackSelection() { + } + +// bool TrackSelection::passSelection(const xAOD::TrackParticle& track, const xAOD::Vertex& primaryVertex) { +// if (track.pt() < m_ptcut) return false; +// +// if (std::fabs(track.eta()) > m_etamax) return false; +// +// +// if (track.isAvailable<char>("passTruthFilter")) { +// if (!track.auxdecor<char>("passTruthFilter")) return false; +// } +// +// if ( !m_trkseltool->accept(track, &primaryVertex ) ) return false; +// +// return true; +// } + + void TrackSelection::print(std::ostream& os) const { + os << "Track \n" + << " * pT > " << m_ptcut << "\n" + << " * |eta| < " << m_etamax; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackSelectionBase.cxx new file mode 100644 index 000000000000..8cc82e9a543d --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TrackSelectionBase.cxx @@ -0,0 +1,18 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TopObjectSelectionTools/TrackSelectionBase.h" + +namespace top { + TrackSelectionBase::TrackSelectionBase() { + } + + TrackSelectionBase::~TrackSelectionBase() { + } + + std::ostream& operator << (std::ostream& os, const top::TrackSelectionBase& selection) { + selection.print(os); + return os; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TruthSelectionBase.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TruthSelectionBase.cxx index a1e93857ccb9..c6f87441355c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TruthSelectionBase.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TruthSelectionBase.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/TruthSelectionBase.h" @@ -10,13 +10,13 @@ #include <iostream> namespace top { - TruthSelectionBase::TruthSelectionBase() { } bool TruthSelectionBase::isBhadron(int pid) const { pid = (int) std::fabs(pid); - if ( (pid >= 511 && pid <= 545) || (pid >= 10511 && pid <= 10545) || (pid >= 20511 && pid <= 20545) || (pid >= 5112 && pid <= 5554)) { // check if it's a B-hadron + if ((pid >= 511 && pid <= 545) || (pid >= 10511 && pid <= 10545) || (pid >= 20511 && pid <= 20545) || + (pid >= 5112 && pid <= 5554)) { // check if it's a B-hadron return true; } return false; @@ -24,15 +24,15 @@ namespace top { bool TruthSelectionBase::isChadron(int pid) const { pid = (int) std::fabs(pid); - if ( (pid >= 400 && pid < 500 && pid != 443) || (pid >= 4000 && pid < 5000) || (pid >= 10411 && pid <= 10455) || (pid >= 20411 && pid <= 20445)) { // check if it's a C-hadron + if ((pid >= 400 && pid < 500 && pid != 443) || (pid >= 4000 && pid < 5000) || (pid >= 10411 && pid <= 10455) || + (pid >= 20411 && pid <= 20445)) { // check if it's a C-hadron return true; } return false; } - } -std::ostream& operator<<(std::ostream& os, const top::TruthSelectionBase& selection) { - selection.print(os); - return os; +std::ostream& operator << (std::ostream& os, const top::TruthSelectionBase& selection) { + selection.print(os); + return os; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TruthSelectionTtres.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TruthSelectionTtres.cxx index 94c94d7357ca..5caaba706a66 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TruthSelectionTtres.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/TruthSelectionTtres.cxx @@ -1,44 +1,46 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopObjectSelectionTools/TruthSelectionTtres.h" #include "TopEvent/EventTools.h" namespace top { - - TruthSelectionTtres::TruthSelectionTtres() - { + TruthSelectionTtres::TruthSelectionTtres() { } - bool TruthSelectionTtres::passSelection(const xAOD::TruthParticle& mc) const - { + bool TruthSelectionTtres::passSelection(const xAOD::TruthParticle& mc) const { int p = (int) std::fabs(mc.pdgId()); int s = mc.status(); int b = mc.barcode(); if (b > 100000) return false; + if (p == 11 || p == 13) { if (s != 1) // only final electrons and muons for e-in-jet and isolation performance eval. return false; + return true; } if (p == 6) { if (s != 3) // tops after radiation for mtt reconstruction return false; + return true; } if (isBhadron(p) || isChadron(p)) { if (s != 3) // b and c hadrons with status 3 to match with jets return false; + return true; } if (p == 12 || p == 14 || p == 16) { if (s != 1) // only final neutrinos for m_tt reconstruction return false; + return true; } @@ -47,12 +49,11 @@ namespace top { } void TruthSelectionTtres::print(std::ostream& os) const { - os << "TruthSelectionTtres\n" - << " * keep final electrons and muons\n" - << " * keep top quarks after radiation\n" - << " * keep b and c hadrons\n" - << " * keep final neutrinos\n" - ; + os << "TruthSelectionTtres\n" + << " * keep final electrons and muons\n" + << " * keep top quarks after radiation\n" + << " * keep b and c hadrons\n" + << " * keep final neutrinos\n" + ; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/AntiMuonMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/AntiMuonMC15.h index 359c0bcd48df..66c7dbec39e0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/AntiMuonMC15.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/AntiMuonMC15.h @@ -1,67 +1,63 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef ANTIMUONMC15_H_ -#define ANTIMUONMC15_H_ - -#include "TopObjectSelectionTools/MuonSelectionBase.h" -#include "TopObjectSelectionTools/IsolationTools.h" - -#include "AsgTools/ToolHandle.h" -#include "MuonAnalysisInterfaces/IMuonSelectionTool.h" - -namespace top { - -/** - * @brief Select muons based on some early MC15 suggestions. - */ -class AntiMuonMC15 : public MuonSelectionBase { -public: - /** - * @brief Construct the tool to select good muons. - * - * @param ptcut The minimum pT cut for good muons. - * @param isolation The isolation the user wants to apply. Don't want any - * isolation to be applied? Then leave this as a nullptr. - */ - AntiMuonMC15(const double ptcut, IsolationBase* isolation); - - ///Does nothing. - virtual ~AntiMuonMC15(){} - - /** - * @brief Implements the logic to select good muons. - * - * @param mu The muon that we want to check. - * @return True if the muon is good, false otherwise. - */ - virtual bool passSelection(const xAOD::Muon& mu) const override; - - /** - * @brief The loose selection needed by some background estimates. - * - * @param mu - * @return - */ - virtual bool passSelectionLoose(const xAOD::Muon& mu) const override; - - ///Print the cuts to the ostream. - virtual void print(std::ostream& os) const override; - - -protected: - ///Lower pT threshold to apply to object selection. - double m_ptcut; - - ///Proper tool to select muons. - ToolHandle<CP::IMuonSelectionTool> m_muonSelectionTool; -// ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolLoose; - - ///Isolation tool, can be nullptr meaning "no isolation requirement" -// std::unique_ptr<top::IsolationBase> m_isolation; -}; - -} - -#endif +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANTIMUONMC15_H_ +#define ANTIMUONMC15_H_ + +#include "TopObjectSelectionTools/MuonSelectionBase.h" +#include "TopObjectSelectionTools/IsolationTools.h" + +#include "AsgTools/ToolHandle.h" +#include "MuonAnalysisInterfaces/IMuonSelectionTool.h" + +namespace top { +/** + * @brief Select muons based on some early MC15 suggestions. + */ + class AntiMuonMC15: public MuonSelectionBase { + public: + /** + * @brief Construct the tool to select good muons. + * + * @param ptcut The minimum pT cut for good muons. + * @param isolation The isolation the user wants to apply. Don't want any + * isolation to be applied? Then leave this as a nullptr. + */ + AntiMuonMC15(const double ptcut, IsolationBase* isolation); + + ///Does nothing. + virtual ~AntiMuonMC15() {} + + /** + * @brief Implements the logic to select good muons. + * + * @param mu The muon that we want to check. + * @return True if the muon is good, false otherwise. + */ + virtual bool passSelection(const xAOD::Muon& mu) const override; + + /** + * @brief The loose selection needed by some background estimates. + * + * @param mu + * @return + */ + virtual bool passSelectionLoose(const xAOD::Muon& mu) const override; + + ///Print the cuts to the ostream. + virtual void print(std::ostream& os) const override; + protected: + ///Lower pT threshold to apply to object selection. + double m_ptcut; + + ///Proper tool to select muons. + ToolHandle<CP::IMuonSelectionTool> m_muonSelectionTool; +// ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolLoose; + + ///Isolation tool, can be nullptr meaning "no isolation requirement" +// std::unique_ptr<top::IsolationBase> m_isolation; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronCutBasedMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronCutBasedMC15.h index eb38ce5c10a3..41f8d0a56535 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronCutBasedMC15.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronCutBasedMC15.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ELECTRONCUTBASEDMC15_H_ #define ELECTRONCUTBASEDMC15_H_ @@ -11,12 +11,11 @@ #include <memory> namespace top { - /** * @brief Electron selection based on the cut-based thingy. */ -class ElectronCutBasedMC15 : public top::ElectronSelectionBase { -public: + class ElectronCutBasedMC15: public top::ElectronSelectionBase { + public: /** * @brief Class to help select cut-based good electrons. * @@ -28,8 +27,9 @@ public: * @param isolation nullptr for un-isolated, or a new "isolation object" to * apply isolation cuts */ - ElectronCutBasedMC15(double ptcut, bool vetoCrack, const std::string& quality, const std::string& qualityLoose, IsolationBase* isolation); - virtual ~ElectronCutBasedMC15(){} + ElectronCutBasedMC15(double ptcut, bool vetoCrack, const std::string& quality, const std::string& qualityLoose, + IsolationBase* isolation); + virtual ~ElectronCutBasedMC15() {} /** * @brief The cuts to select good electrons for your analysis should be * implemented in here. @@ -53,11 +53,10 @@ public: * * Usually this goes to the log file, so you know what you ran with. * - * @param Where the print-out should go, e.g. cout. + * @param Where the print-out should go, e.g. msg stream */ virtual void print(std::ostream&) const override; - -protected: + protected: /** * @brief Since both selections are fairly similar, we can perform * the un-isolated part in one function. @@ -85,8 +84,7 @@ protected: ///The isolation tool, or nullptr if we don't want isolation std::unique_ptr<top::IsolationBase> m_isolation; -}; - + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronLikelihoodMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronLikelihoodMC15.h index 81833bcf8864..67b5fc430f9d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronLikelihoodMC15.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronLikelihoodMC15.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ELECTRONLIKELIHOODMC15_H_ #define ELECTRONLIKELIHOODMC15_H_ @@ -11,112 +11,112 @@ #include <memory> namespace top { - /** - * @brief To select electrons based on the "likelihood" definition. - */ - class ElectronLikelihoodMC15 : public top::ElectronSelectionBase { - public: - /** - * @brief Cut on likelihood electrons - * - * @param ptcut The minimum pT electrons should have - * @param vetoCrack Do you want to veto 1.37 < |cluster_eta| < 1.52? - * @param operatingPoint Likelihood operating point for the main object - * definition - * @param operatingPointLoose Likelihood operating point for the loose - * objects (fakes estimates?) - * @param isolation The isolation tool the user wants to use. If you don't - * want any isolation cuts to be applied then leave this as a nullptr. - */ - ElectronLikelihoodMC15(const double ptcut, const bool vetoCrack, const std::string& operatingPoint, - const std::string& operatingPointLoose, StandardIsolation* isolation, const bool applyTTVACut=true); - // this constructor is kept for backward compatibility - isPrimaryxAOD is not needed anymore - ElectronLikelihoodMC15(const bool, - const double ptcut, const bool vetoCrack, const std::string& operatingPoint, - const std::string& operatingPointLoose, StandardIsolation* isolation, const bool applyTTVACut=true); - virtual ~ElectronLikelihoodMC15(){} - /** - * @brief Selection for the main analysis (i.e. tight object definitions). - * - * @param el The electron in question - * @return True if it passes the selection, false otherwise. - */ - virtual bool passSelection(const xAOD::Electron& el) const override; - - /** - * @brief Selection for the loose object definitions (e.g. in fakes - * estimates). - * - * @param el The electron in question - * @return True if it passes the selection, false otherwise. - */ - virtual bool passSelectionLoose(const xAOD::Electron& el) const override; - - /** - * @brief The BLayer cuts for the loose lepton LH WP. - * - * @param el - * @return True if passes, false otherwise - */ - virtual bool passBLayerCuts(const xAOD::Electron& el) const; - - - /** - * @brief The track-to-vertex association (TTVA) cuts. - * - * @param el - * @return True if passes, false otherwise - */ - virtual bool passTTVACuts(const xAOD::Electron& el) const; - - /** - * @brief The charge flip selector cut - * - * @param el - * @return True if passes, false otherwise - */ - virtual bool passChargeIDCut(const xAOD::Electron& el) const; - - /** - * @brief Why would you not want to know what you're running? - * - * @param os Print details of the cuts to the output stream. - */ - virtual void print(std::ostream& os) const override; - - protected: - /** - * @brief The loose and tight selections are the same, except they have different - * use isolation and a different likelihood tool. - * - * @param el The electron in question. - * @param likelihoodTool The tool to use (m_likelihood, or m_likelihoodLoose) - * @return True if it's good, False if it's not - */ - bool passSelectionNoIsolation(const xAOD::Electron& el, const std::string& operatingPoint_DF, const std::string& operatingPoint) const; - - ///Minimum pT that electrons should have - double m_ptcut; - - ///Veto the crack region? - bool m_vetoCrack; - - std::string m_operatingPoint; - std::string m_operatingPointLoose; - std::string m_operatingPoint_DF; - std::string m_operatingPointLoose_DF; - - ///The isolation tool, or nullptr if we don't want isolation - std::unique_ptr<top::StandardIsolation> m_isolation; - - /// decide if TTVA cut should be applied at all - bool m_applyTTVACut; - - /// decide to apply the charge ID selector tool - bool m_applyChargeIDCut; + * @brief To select electrons based on the "likelihood" definition. + */ + class ElectronLikelihoodMC15: public top::ElectronSelectionBase { + public: + /** + * @brief Cut on likelihood electrons + * + * @param ptcut The minimum pT electrons should have + * @param vetoCrack Do you want to veto 1.37 < |cluster_eta| < 1.52? + * @param operatingPoint Likelihood operating point for the main object + * definition + * @param operatingPointLoose Likelihood operating point for the loose + * objects (fakes estimates?) + * @param isolation The isolation tool the user wants to use. If you don't + * want any isolation cuts to be applied then leave this as a nullptr. + */ + ElectronLikelihoodMC15(const double ptcut, const bool vetoCrack, const std::string& operatingPoint, + const std::string& operatingPointLoose, StandardIsolation* isolation, + const bool applyTTVACut = true, const bool applyChargeIDCut = false); + // this constructor is kept for backward compatibility - isPrimaryxAOD is not needed anymore + ElectronLikelihoodMC15(const bool, + const double ptcut, const bool vetoCrack, const std::string& operatingPoint, + const std::string& operatingPointLoose, StandardIsolation* isolation, + const bool applyTTVACut = true, const bool applyChargeIDCut = false); + virtual ~ElectronLikelihoodMC15() {} + /** + * @brief Selection for the main analysis (i.e. tight object definitions). + * + * @param el The electron in question + * @return True if it passes the selection, false otherwise. + */ + virtual bool passSelection(const xAOD::Electron& el) const override; + + /** + * @brief Selection for the loose object definitions (e.g. in fakes + * estimates). + * + * @param el The electron in question + * @return True if it passes the selection, false otherwise. + */ + virtual bool passSelectionLoose(const xAOD::Electron& el) const override; + + /** + * @brief The BLayer cuts for the loose lepton LH WP. + * + * @param el + * @return True if passes, false otherwise + */ + virtual bool passBLayerCuts(const xAOD::Electron& el) const; + + + /** + * @brief The track-to-vertex association (TTVA) cuts. + * + * @param el + * @return True if passes, false otherwise + */ + virtual bool passTTVACuts(const xAOD::Electron& el) const; + + /** + * @brief The charge flip selector cut + * + * @param el + * @return True if passes, false otherwise + */ + virtual bool passChargeIDCut(const xAOD::Electron& el) const; + + /** + * @brief Why would you not want to know what you're running? + * + * @param os Print details of the cuts to the output stream. + */ + virtual void print(std::ostream& os) const override; + protected: + /** + * @brief The loose and tight selections are the same, except they have different + * use isolation and a different likelihood tool. + * + * @param el The electron in question. + * @param likelihoodTool The tool to use (m_likelihood, or m_likelihoodLoose) + * @return True if it's good, False if it's not + */ + bool passSelectionNoIsolation(const xAOD::Electron& el, const std::string& operatingPoint_DF, + const std::string& operatingPoint) const; + + ///Minimum pT that electrons should have + double m_ptcut; + + ///Veto the crack region? + bool m_vetoCrack; + + std::string m_operatingPoint; + std::string m_operatingPointLoose; + std::string m_operatingPoint_DF; + std::string m_operatingPointLoose_DF; + + ///The isolation tool, or nullptr if we don't want isolation + std::unique_ptr<top::StandardIsolation> m_isolation; + + /// decide if TTVA cut should be applied at all + bool m_applyTTVACut; + + /// decide to apply the charge ID selector tool + bool m_applyChargeIDCut; }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronSelectionBase.h index 970a06b104a2..0bf44b51d59c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronSelectionBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/ElectronSelectionBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ELECTRONSELECTIONBASE_H_ #define ELECTRONSELECTIONBASE_H_ @@ -10,7 +10,6 @@ #include <memory> namespace top { - /** * @brief Base class for implementing an electron selection. * @@ -20,8 +19,8 @@ namespace top { * passSelection for an Electron. I think it would be a less-clean solution if * we were to use the 'proper' CP tool style. */ -class ElectronSelectionBase { -public: + class ElectronSelectionBase { + public: ElectronSelectionBase(); virtual ~ElectronSelectionBase(); @@ -32,7 +31,7 @@ public: ElectronSelectionBase(ElectronSelectionBase&& rhs) = delete; ///No assignment - ElectronSelectionBase& operator=(const ElectronSelectionBase& rhs) = delete; + ElectronSelectionBase& operator = (const ElectronSelectionBase& rhs) = delete; ///For the main analysis object selection virtual bool passSelection(const xAOD::Electron&) const = 0; @@ -42,10 +41,9 @@ public: ///Because everybody likes to know what object definitions they ran with virtual void print(std::ostream&) const = 0; -}; + }; + std::ostream& operator << (std::ostream& os, const ElectronSelectionBase& selection); } -std::ostream& operator<<(std::ostream& os, const top::ElectronSelectionBase& selection); - #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/EventCleaningSelection.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/EventCleaningSelection.h index 9787fc024922..743aca7bdd2b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/EventCleaningSelection.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/EventCleaningSelection.h @@ -1,11 +1,14 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ -// $Id: EventCleaningSelection.h 797163 2017-02-14 16:31:05Z grancagn $ #ifndef ANALYSISTOP_TOPOBJECTSELECTIONTOOLS_EVENTCLEANINGSELECTION_H #define ANALYSISTOP_TOPOBJECTSELECTIONTOOLS_EVENTCLEANINGSELECTION_H +#include <string> +#include <unordered_set> +#include <vector> + // Framework include(s): #include "AsgTools/AsgTool.h" #include "AsgTools/ToolHandle.h" @@ -18,90 +21,101 @@ #include "TrigDecisionTool/TrigDecisionTool.h" #include "TriggerMatchingTool/IMatchingTool.h" #include "TrigTauMatching/ITrigTauMatching.h" +#include "TriggerAnalysisInterfaces/ITrigGlobalEfficiencyCorrectionTool.h" // Top include(s): #include "TopConfiguration/SelectionConfigurationData.h" -namespace top{ +namespace top { class TopConfig; - - class EventCleaningSelection final : public asg::AsgTool { - public: - explicit EventCleaningSelection( const std::string& name ); - virtual ~EventCleaningSelection(){} - - StatusCode initilize(); - - void setEventSelections( const std::vector<top::SelectionConfigurationData>& selections ); - bool applyGRL() const; - bool applyTrigger(); - bool applyGoodCalo() const; - bool applyPrimaryVertex() const; - - // Print trigger configuration - very verbose, but tells you which triggers are included for an event - void printTriggers() const; - - // helper to allow us to added trigger decisions to our output files - void addExtraBranches( std::vector<std::string>& extraBranchList ); - - // Delete Standard constructors - EventCleaningSelection(const EventCleaningSelection& rhs) = delete; - EventCleaningSelection(EventCleaningSelection&& rhs) = delete; - EventCleaningSelection& operator=(const EventCleaningSelection& rhs) = delete; - - private: - - ///Match offline electrons to the trigger - void matchElectrons(); - - ///Match offline muons to the trigger - void matchMuons(); - - ///Match offline taus to the trigger - void matchTaus(); - - /// Top config - std::shared_ptr<top::TopConfig> m_config; - - /// GoodRunsLists - ToolHandle<IGoodRunsListSelectionTool> m_grlTool; - - /// Trigger configuration tool - ToolHandle<TrigConf::ITrigConfigTool> m_trigConfTool; - - ///Trigger decision tool - ToolHandle<Trig::TrigDecisionTool> m_trigDecisionTool; - - // Trigger matching tool - ToolHandle<Trig::IMatchingTool> m_trigMatchTool; - - //Tau trigger matching - ToolHandle<Trig::ITrigTauMatchingTool> m_trigMatchTauTool; - - ///List of triggers to 'or' together for each event. If any one passes, the event passes - std::vector<std::string> m_allTriggers; - std::vector<std::string> m_electronTriggers; - std::vector<std::string> m_muonTriggers; - std::vector<std::string> m_tauTriggers; - - /// Apply a logical OR cut to all supplied triggers - /// If ANY selection does not request the trigger, this will not be set - /// In this case, the apply method will always return true - /// - /// If ALL selections request a trigger, then we can veto events - /// and not run the systematics, pre-OR cuts and the overlap removal - bool m_vetoEventsTrigger; - - /// If ALL selections request GRL, then we can veto events - /// and not run the systematics, pre-OR cuts and the overlap removal - bool m_vetoEventsGRL; - - /// If ALL selections request GOODCALO, then we can veto events - /// Data only - bool m_vetoEventsGoodCalo; - - /// If ALL selections request PRIVTX, then we can veto events - bool m_vetoEventsPriVtx; + + class EventCleaningSelection final: public asg::AsgTool { + public: + explicit EventCleaningSelection(const std::string& name); + virtual ~EventCleaningSelection() {} + + StatusCode initialize(); + + void setEventSelections(const std::vector<top::SelectionConfigurationData>& selections); + bool applyGRL() const; + bool applyTrigger(); + bool applyGoodCalo() const; + bool applyPrimaryVertex() const; + + // Print trigger configuration - very verbose, but tells you which triggers are included for an event + void printTriggers() const; + + // helper to allow us to added trigger decisions to our output files + void addExtraBranches(std::vector<std::string>& extraBranchList); + + // Delete Standard constructors + EventCleaningSelection(const EventCleaningSelection& rhs) = delete; + EventCleaningSelection(EventCleaningSelection&& rhs) = delete; + EventCleaningSelection& operator = (const EventCleaningSelection& rhs) = delete; + + bool isElectronTrigger(std::string const& trigger) const; + bool isMuonTrigger(std::string const& trigger) const; + static std::vector<std::string> getIndividualFromGlobalTriggers(std::vector<std::string> const& triggers); + private: + ///Match offline electrons to the trigger + void matchElectrons(); + + ///Match offline muons to the trigger + void matchMuons(); + + ///Match offline taus to the trigger + void matchTaus(); + + /// Top config + std::shared_ptr<top::TopConfig> m_config; + + /// GoodRunsLists + ToolHandle<IGoodRunsListSelectionTool> m_grlTool; + + /// Trigger configuration tool + ToolHandle<TrigConf::ITrigConfigTool> m_trigConfTool; + + ///Trigger decision tool + ToolHandle<Trig::TrigDecisionTool> m_trigDecisionTool; + + // Trigger matching tool + ToolHandle<Trig::IMatchingTool> m_trigMatchTool; + + //Tau trigger matching + ToolHandle<Trig::ITrigTauMatchingTool> m_trigMatchTauTool; + + //Global trigger efficiency tool + ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerSF; + ToolHandle<ITrigGlobalEfficiencyCorrectionTool> m_globalTriggerSFLoose; + + ///List of triggers to 'or' together for each event. If any one passes, the event passes + std::vector<std::string> m_allTriggers_Tight; + std::vector<std::string> m_electronTriggers_Tight; + std::vector<std::string> m_muonTriggers_Tight; + std::vector<std::string> m_tauTriggers_Tight; + std::vector<std::string> m_allTriggers_Loose; + std::vector<std::string> m_electronTriggers_Loose; + std::vector<std::string> m_muonTriggers_Loose; + std::vector<std::string> m_tauTriggers_Loose; + + /// Apply a logical OR cut to all supplied triggers + /// If ANY selection does not request the trigger, this will not be set + /// In this case, the apply method will always return true + /// + /// If ALL selections request a trigger, then we can veto events + /// and not run the systematics, pre-OR cuts and the overlap removal + bool m_vetoEventsTrigger; + + /// If ALL selections request GRL, then we can veto events + /// and not run the systematics, pre-OR cuts and the overlap removal + bool m_vetoEventsGRL; + + /// If ALL selections request GOODCALO, then we can veto events + /// Data only + bool m_vetoEventsGoodCalo; + + /// If ALL selections request PRIVTX, then we can veto events + bool m_vetoEventsPriVtx; }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/FwdElectronSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/FwdElectronSelectionBase.h new file mode 100644 index 000000000000..3ca141c52660 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/FwdElectronSelectionBase.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef FWDELECTRONSELECTIONBASE_H_ +#define FWDELECTRONSELECTIONBASE_H_ + +#include "xAODEgamma/Electron.h" + +#include <memory> + +namespace top { +/** + * @brief Base class for implementing an electron selection. + * + * If you want to build a new electron selection, you should inherit from this. + * Why didn't I use ASG tools as a base? I suspect it's a bit over-complicated + * for this simple task, and this way we can force people to implement + * passSelection for an Electron. I think it would be a less-clean solution if + * we were to use the 'proper' CP tool style. + */ + class FwdElectronSelectionBase { + public: + FwdElectronSelectionBase(); + virtual ~FwdElectronSelectionBase(); + + ///No copy construction + FwdElectronSelectionBase(const FwdElectronSelectionBase& rhs) = delete; + + ///No moving - really? Seems a bit strict. We'll see + FwdElectronSelectionBase(FwdElectronSelectionBase&& rhs) = delete; + + ///No assignment + FwdElectronSelectionBase& operator = (const FwdElectronSelectionBase& rhs) = delete; + + ///For the main analysis object selection + virtual bool passSelection(const xAOD::Electron&, int bcid, int runNumber) const = 0; + + ///For the loose (e.g. fakes) object selection + virtual bool passSelectionLoose(const xAOD::Electron&, int bcid, int runNumber) const = 0; + + ///Because everybody likes to know what object definitions they ran with + virtual void print(std::ostream&) const = 0; + }; + + std::ostream& operator << (std::ostream& os, const top::FwdElectronSelectionBase& selection); +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/IsolationTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/IsolationTools.h index 63dc09989ae1..f503b60d8f4b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/IsolationTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/IsolationTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ISOLATIONTOOLS_H_ #define ISOLATIONTOOLS_H_ @@ -9,13 +9,12 @@ #include "xAODPrimitives/IsolationType.h" namespace top { - /** * @brief A common base for implementing isolation cuts. Probably these * isolation tools should be in individual files? Time will tell. */ -class IsolationBase { -public: + class IsolationBase { + public: ///Create IsolationBase(); @@ -45,10 +44,10 @@ public: /** * @brief Because people like to know what isolation cuts they're applying. * - * @param os Where to print things to, e.g. cout. + * @param os Where to print things to, e.g. msg stream. */ virtual void print(std::ostream& os) const = 0; -}; + }; /** * @brief These should give you access to xAOD::Iso::topoetcone20, 30, 40 @@ -61,8 +60,8 @@ public: * fancy things, we should implement them. Don't you want to look at using * RelativePTVarCone instead though? */ -class AbsoluteIsolationDC14 : public IsolationBase { -public: + class AbsoluteIsolationDC14: public IsolationBase { + public: /** * @brief Absolute cut on topoetcone or ptcone. * @@ -83,21 +82,20 @@ public: virtual bool passSelection(const xAOD::IParticle& p) const override; virtual bool passSelectionLoose(const xAOD::IParticle& p) const override; virtual void print(std::ostream& os) const override; - -protected: + protected: ///What to cut on (topoetcone20, 30, 40 or ptcone20, 30, 40). xAOD::Iso::IsolationType m_type; ///The value, in MeV, to cut. double m_cutvalue; -}; + }; /** * @brief Yay DC14 now has isolation! This should allow you to cut on the * isolation (ptvarcone) as a fraction of the pt of the lepton. */ -class RelativePTVarCone : public IsolationBase { -public: + class RelativePTVarCone: public IsolationBase { + public: /** * @brief Cut on the mini-isolation (aka ptvarcone) as a fraction of the * pt of the lepton. @@ -129,8 +127,7 @@ public: ///Come on, you really need me to tell you what this does? virtual void print(std::ostream& os) const override; - -protected: + protected: ///The name of the variable to access, e.g. ptvarcone20 formed in the constructor. std::string m_size; @@ -142,7 +139,7 @@ protected: ///For the objects used in the looser object selection (e.g. matrix method fakes) double m_fractionLoose; -}; + }; /** * @brief Danilo's approximation of mini-isolation which has been calculated @@ -153,8 +150,8 @@ protected: * options will be better, and almost certainly faster if we don't need to load * all the tracks! */ -class ApproxPTVarCone : public IsolationBase { -public: + class ApproxPTVarCone: public IsolationBase { + public: /** * @brief An approximation of mini-isolation. * @@ -186,27 +183,26 @@ public: ///Come on, you really need me to tell you what this does? virtual void print(std::ostream& os) const override; - -protected: + protected: ///For the main analysis object selection double m_fraction; ///For the objects used in the looser object selection (e.g. matrix method fakes) double m_fractionLoose; -}; + }; /** * @brief Apply the cuts to etcone and ptcone like we used to in Run-I */ -class StandardIsolation : public IsolationBase { -public: + class StandardIsolation: public IsolationBase { + public: /** * @brief Applies the cuts to etcone and ptcone like we used to in Run-I * * This sets up the isolation tool and configures it with the cuts. */ - StandardIsolation(const std::string& tightLeptonIsolation = "Gradient" , - const std::string& looseLeptonIsolation = "None" ); + StandardIsolation(const std::string& tightLeptonIsolation = "Gradient", + const std::string& looseLeptonIsolation = "None"); /** * @brief Does this particle pass the isolation cuts for the main analysis @@ -231,16 +227,17 @@ public: ///Come on, you really need me to tell you what this does? virtual void print(std::ostream& os) const override; - -protected: + protected: std::string m_tightLeptonDecoration; std::string m_looseLeptonDecoration; std::string m_tightLeptonIsolation; std::string m_looseLeptonIsolation; bool m_doTightIsolation; bool m_doLooseIsolation; -}; - + bool m_doTightPromptLeptonIso; + bool m_doLoosePromptLeptonIso; + bool m_skipUnavailable; // skip unavailable working points (instead of aborting) + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetGhostTrackSelection.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetGhostTrackSelection.h new file mode 100644 index 000000000000..ec800ccde276 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetGhostTrackSelection.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef JETGHOSTTRACKSELECTION_H_ +#define JETGHOSTTRACKSELECTION_H_ + +#include "TopObjectSelectionTools/JetGhostTrackSelectionBase.h" +#include "InDetTrackSelectionTool/InDetTrackSelectionTool.h" + +#include "xAODTracking/VertexContainer.h" +#include "xAODTracking/Vertex.h" + + +namespace top { + class JetGhostTrackSelection: public JetGhostTrackSelectionBase { + public: + JetGhostTrackSelection(const double ptcut, const double etamax, const std::string vertexassociation, const double m_ptcut_jet, const double m_etamax_jet ); + ~JetGhostTrackSelection(); + virtual bool JetConsideredForGhostTrackSelection(double pt, double eta) const override; +// virtual bool passSelection(const xAOD::TrackParticle&, const xAOD::Vertex&) const override; + virtual void print(std::ostream& os) const override; + private: + //Include selection on pt and eta of the tracks + double m_ptcut; + double m_etamax; + + //Include selection on pt and eta of the jets + double m_ptcut_jet; + double m_etamax_jet; + + //Requirement on the vertex association + std::string m_vertexassociation; + double m_d0; + double m_z0sintheta; + + + ToolHandle<InDet::InDetTrackSelectionTool> m_trkseltool; + + }; +} +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetGhostTrackSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetGhostTrackSelectionBase.h new file mode 100644 index 000000000000..e2584a8071f6 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetGhostTrackSelectionBase.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef JETGHOSTTRACKSELECTIONBASE_H_ +#define JETGHOSTTRACKSELECTIONBASE_H_ + +#include "xAODTracking/TrackParticle.h" + +namespace top { + class JetGhostTrackSelectionBase { + public: + JetGhostTrackSelectionBase(); + virtual ~JetGhostTrackSelectionBase(); + + ///For the main analysis object selection +// virtual bool passSelection(const xAOD::TrackParticle&, const xAOD::Vertex&) const = 0; + ///To see if a jet hase the requirements to retrieve the corresponding tracks + virtual bool JetConsideredForGhostTrackSelection(double pt, double eta) const = 0; + ///Because everybody likes to know what object definitions they ran with + virtual void print(std::ostream&) const = 0; + + }; + +std::ostream& operator << (std::ostream& os, const top::JetGhostTrackSelectionBase& selection); + +} +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetMC15.h index 67c37327f20d..65ed5756eb2e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetMC15.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetMC15.h @@ -1,87 +1,92 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef JETMC15_H_ #define JETMC15_H_ #include "TopObjectSelectionTools/JetSelectionBase.h" -#include "JetJvtEfficiency/IJetJvtEfficiency.h" +#include "JetAnalysisInterfaces/IJetJvtEfficiency.h" #include "AsgTools/ToolHandle.h" # include <string> namespace top { - /** * @brief A class that performs object cuts on Jets (of any size!). At the * moment it includes a cut on pT, eta and JVT. */ -class JetMC15 : public JetSelectionBase { - public: - /** - * @brief A tool to select some jets for MC15 based on the pT and eta cuts. - * - * @param ptcut The minimum pT to accept good jets. - * @param etamax The maximum eta cut. - * @param doJVTCut To perform JVT cut - should be false for small-R jets - * @param fwdJetSel Scenario for treating forward jets. - */ - JetMC15(const double ptcut, const double etamax, const bool doJVTCut, const std::string fwdJetSel="default"); - - /** - * @brief A tool to select some jets for MC15 based on the pT and eta cuts. - * - * This version of the constructor always perform JVT cut - * - * @param ptcut The minimum pT to accept good jets. - * @param etamax The maximum eta cut. - * @param fwdJetSel Scenario for treating forward jets. - */ - JetMC15(const double ptcut, const double etamax, const std::string fwdJetSel="default"); - - /** - * @brief A tool to select some jets for MC15 based on the pT and eta cuts. - * - * DEPRECATED - only kept for backward compatibility - no need to specify any jvt cut, please use the above function instead. - * - * @param ptcut The minimum pT to accept good jets. - * @param etamax The maximum eta cut. - * @param jvtmin The minimum cut on the jet vertex fraction (no longer used) - */ - JetMC15(const double ptcut, const double etamax, const double); - - // Does nothing. - virtual ~JetMC15() {} - - /** - * @brief Implements the logic to select jets based on pT and eta. - * - * It cuts on pt, eta, jvt. - * - * @param jet The jet to check. - * @return True if the jet passes the cuts, false otherwise. - */ - virtual bool passSelection(const xAOD::Jet& jet) override; - - // Print the cuts to the ostream. - virtual void print(std::ostream& os) const override; - - protected: - // The lower pT cut threshold to apply to the object. - double m_ptcut; - - // The upper eta cut. - double m_etamax; - - // Scenario for treating forward jets - std::string m_fwdJetSel; - - // To do JVT cut - should be false for large-R jets - bool m_applyJVTCut; - - ToolHandle<CP::IJetJvtEfficiency> m_jvt_tool; -}; + class JetMC15: public JetSelectionBase { + public: + /** + * @brief A tool to select some jets for MC15 based on the pT and eta cuts. + * + * @param ptcut The minimum pT to accept good jets. + * @param etamax The maximum eta cut. + * @param doJVTCut To perform JVT cut - should be false for small-R jets + */ + JetMC15(const double ptcut, const double etamax, const bool doJVTCut); + + /** + * @brief A tool to select some jets for MC15 based on the pT and eta cuts. + * + * This version of the constructor always perform JVT cut + * + * @param ptcut The minimum pT to accept good jets. + * @param etamax The maximum eta cut. + */ + JetMC15(const double ptcut, const double etamax); + + /** + * @brief A tool to select some jets for MC15 based on the pT and eta cuts. + * + * DEPRECIATED - Only kept for backwards compatibility, to stop external extensions from crashing, please use above forms + * + * @param ptcut The minimum pT to accept good jets. + * @param etamax The maximum eta cut. + * @param fwdJetSel Scenario for treating forward jets. + */ + JetMC15(const double ptcut, const double etamax, const std::string); + + /** + * @brief A tool to select some jets for MC15 based on the pT and eta cuts. + * + * DEPRECATED - only kept for backward compatibility - no need to specify any jvt cut, please use the above function + *instead. + * + * @param ptcut The minimum pT to accept good jets. + * @param etamax The maximum eta cut. + * @param jvtmin The minimum cut on the jet vertex fraction (no longer used) + */ + JetMC15(const double ptcut, const double etamax, const double); + + // Does nothing. + virtual ~JetMC15() {} + + /** + * @brief Implements the logic to select jets based on pT and eta. + * + * It cuts on pt, eta, jvt. + * + * @param jet The jet to check. + * @return True if the jet passes the cuts, false otherwise. + */ + virtual bool passSelection(const xAOD::Jet& jet) override; + + // Print the cuts to the ostream. + virtual void print(std::ostream& os) const override; + protected: + // The lower pT cut threshold to apply to the object. + double m_ptcut; + + // The upper eta cut. + double m_etamax; + + // To do JVT cut - should be false for large-R jets + bool m_applyJVTCut; + + ToolHandle<CP::IJetJvtEfficiency> m_jvt_tool; + }; } // namespace top #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetSelectionBase.h index eeb33f65c694..9faf48646fab 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetSelectionBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/JetSelectionBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef JETSELECTIONBASE_H_ #define JETSELECTIONBASE_H_ @@ -8,9 +8,8 @@ #include "xAODJet/Jet.h" namespace top { - -class JetSelectionBase { -public: + class JetSelectionBase { + public: JetSelectionBase(); virtual ~JetSelectionBase(); @@ -18,10 +17,9 @@ public: virtual bool passSelection(const xAOD::Jet&) = 0; virtual void print(std::ostream&) const = 0; -}; + }; + std::ostream& operator << (std::ostream& os, const top::JetSelectionBase& selection); } -std::ostream& operator<<(std::ostream& os, const top::JetSelectionBase& selection); - #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MsgCategory.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MsgCategory.h new file mode 100644 index 000000000000..9bc3f50ed632 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MsgCategory.h @@ -0,0 +1,11 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#ifndef TOPOBJSELTOOLS_MSG_CATEGORY_H_ +#define TOPOBJSELTOOLS_MSG_CATEGORY_H_ + +#include <AsgMessaging/MessageCheck.h> + +ANA_MSG_HEADER(TopObjectSelectionTools) + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MuonMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MuonMC15.h index f0801c397a74..beaf3c9d60a2 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MuonMC15.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MuonMC15.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef MUONMC15_H_ #define MUONMC15_H_ @@ -12,68 +12,65 @@ #include "MuonAnalysisInterfaces/IMuonSelectionTool.h" namespace top { - /** * @brief Select muons based on some early MC15 suggestions. */ -class MuonMC15 : public MuonSelectionBase { - public: - /** - * @brief Construct the tool to select good muons. - * - * @param ptcut The minimum pT cut for good muons. - * @param isolation The isolation the user wants to apply. Don't want any - * isolation to be applied? Then leave this as a nullptr. - */ - MuonMC15(const double ptcut, - IsolationBase* isolation, - const bool applyTTVACut = true); - - // Does nothing. - virtual ~MuonMC15() {} - - /** - * @brief Implements the logic to select good muons. - * - * @param mu The muon that we want to check. - * @return True if the muon is good, false otherwise. - */ - virtual bool passSelection(const xAOD::Muon& mu) const override; - - /** - * @brief The loose selection needed by some background estimates. - * - * @param mu - * @return - */ - virtual bool passSelectionLoose(const xAOD::Muon& mu) const override; - - /** - * @brief The track-to-vertex association (TTVA) cuts. - * - * @param mu - * @return True if passes, false otherwise - */ - virtual bool passTTVACuts(const xAOD::Muon& mu) const; - - // Print the cuts to the ostream. - virtual void print(std::ostream& os) const override; - - - protected: - // Lower pT threshold to apply to object selection. - double m_ptcut; - - // Proper tool to select muons. - ToolHandle<CP::IMuonSelectionTool> m_muonSelectionTool; - ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolLoose; - - // Isolation tool, can be nullptr meaning "no isolation requirement" - std::unique_ptr<top::IsolationBase> m_isolation; - - // decide if TTVA cut should be applied at all - bool m_applyTTVACut; -}; + class MuonMC15: public MuonSelectionBase { + public: + /** + * @brief Construct the tool to select good muons. + * + * @param ptcut The minimum pT cut for good muons. + * @param isolation The isolation the user wants to apply. Don't want any + * isolation to be applied? Then leave this as a nullptr. + */ + MuonMC15(const double ptcut, + IsolationBase* isolation, + const bool applyTTVACut = true); + + // Does nothing. + virtual ~MuonMC15() {} + + /** + * @brief Implements the logic to select good muons. + * + * @param mu The muon that we want to check. + * @return True if the muon is good, false otherwise. + */ + virtual bool passSelection(const xAOD::Muon& mu) const override; + + /** + * @brief The loose selection needed by some background estimates. + * + * @param mu + * @return + */ + virtual bool passSelectionLoose(const xAOD::Muon& mu) const override; + + /** + * @brief The track-to-vertex association (TTVA) cuts. + * + * @param mu + * @return True if passes, false otherwise + */ + virtual bool passTTVACuts(const xAOD::Muon& mu) const; + + // Print the cuts to the ostream. + virtual void print(std::ostream& os) const override; + protected: + // Lower pT threshold to apply to object selection. + double m_ptcut; + + // Proper tool to select muons. + ToolHandle<CP::IMuonSelectionTool> m_muonSelectionTool; + ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolLoose; + + // Isolation tool, can be nullptr meaning "no isolation requirement" + std::unique_ptr<top::IsolationBase> m_isolation; + + // decide if TTVA cut should be applied at all + bool m_applyTTVACut; + }; } // namespace top #endif // MUONMC15_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MuonSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MuonSelectionBase.h index d0fe26fb0697..e8af99396ea4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MuonSelectionBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/MuonSelectionBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef MUONSELECTIONBASE_H_ #define MUONSELECTIONBASE_H_ @@ -8,12 +8,11 @@ #include "xAODMuon/Muon.h" namespace top { - -class MuonSelectionBase { -public: + class MuonSelectionBase { + public: MuonSelectionBase(); virtual ~MuonSelectionBase(); - + ///No copy construction MuonSelectionBase(const MuonSelectionBase& rhs) = delete; @@ -21,7 +20,7 @@ public: MuonSelectionBase(MuonSelectionBase&& rhs) = delete; ///No assignment - MuonSelectionBase& operator=(const MuonSelectionBase& rhs) = delete; + MuonSelectionBase& operator = (const MuonSelectionBase& rhs) = delete; ///For the main analysis object selection virtual bool passSelection(const xAOD::Muon&) const = 0; @@ -30,12 +29,10 @@ public: virtual bool passSelectionLoose(const xAOD::Muon&) const = 0; ///Because everybody likes to know what object definitions they ran with - virtual void print(std::ostream&) const = 0; - -}; + virtual void print(std::ostream&) const = 0; + }; + std::ostream& operator << (std::ostream& os, const top::MuonSelectionBase& selection); } -std::ostream& operator<<(std::ostream& os, const top::MuonSelectionBase& selection); - #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalASG.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalASG.h index 4806f7b19778..241919ac687b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalASG.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalASG.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: OverlapRemovalIndices.h 643484 2015-02-02 11:23:34Z simon $ #ifndef ANALYSISTOP_TOPOBJECTSELECTONTOOLS_OVERLAPREMOVALASG_H @@ -16,89 +16,84 @@ #include "AssociationUtils/IOverlapRemovalTool.h" namespace top { - /** * @brief The Harmonization Group recommended object overlap removal */ - class OverlapRemovalASG : public top::OverlapRemovalBase { - public: - /** - * @brief Sets up ASG Overlap Removal Tool - * - * @param dolargeJet Enables OR also with large-R jets - * This is false by default becaause large-R jets are a bit special. - * - */ - OverlapRemovalASG(bool dolargeJet = false); + class OverlapRemovalASG: public top::OverlapRemovalBase { + public: + /** + * @brief Sets up ASG Overlap Removal Tool + * + * @param dolargeJet Enables OR also with large-R jets + * This is false by default becaause large-R jets are a bit special. + * + */ + OverlapRemovalASG(bool dolargeJet = false); ///does nothing - virtual ~OverlapRemovalASG(); - - /** - * @brief Perform the "ASG standard" overlap removal. - * - * This runs for every event. - * - * @param photon All the photons in the event - * @param el All the electrons (even bad ones). Good ones are decorated - * with passPreORSelection = 1. - * @param mu All the muons in the event - * @param tau All the taus in the event - * @param jet All the jets in the event - * @param ljet All the large-R jets in the event - * - * @param goodPhotons The indices of the photons to keep - * @param goodElectrons The indices of the electrons to keep (e.g. the 0th, 2nd) - * @param goodMuons The indices of the muons to keep - * @param goodTaus The indices of the taus to keep - * @param goodJets The indices of the jets to keep - * @param goodLargeRJets The indices of the large-R jets to keep - * - */ - virtual void overlapremoval(const xAOD::PhotonContainer* photon , - const xAOD::ElectronContainer* el , - const xAOD::MuonContainer* mu , - const xAOD::TauJetContainer* tau , - const xAOD::JetContainer* jet , - const xAOD::JetContainer* ljet, - std::vector<unsigned int>& goodPhotons, - std::vector<unsigned int>& goodElectrons, - std::vector<unsigned int>& goodMuons, - std::vector<unsigned int>& goodTaus, - std::vector<unsigned int>& goodJets, - std::vector<unsigned int>& goodLargeRJets, - const bool isLooseEvent ); - - ///Print something useful to the screen - virtual void print(std::ostream&) const; - + virtual ~OverlapRemovalASG(); + + /** + * @brief Perform the "ASG standard" overlap removal. + * + * This runs for every event. + * + * @param photon All the photons in the event + * @param el All the electrons (even bad ones). Good ones are decorated + * with passPreORSelection = 1. + * @param mu All the muons in the event + * @param tau All the taus in the event + * @param jet All the jets in the event + * @param ljet All the large-R jets in the event + * + * @param goodPhotons The indices of the photons to keep + * @param goodElectrons The indices of the electrons to keep (e.g. the 0th, 2nd) + * @param goodMuons The indices of the muons to keep + * @param goodTaus The indices of the taus to keep + * @param goodJets The indices of the jets to keep + * @param goodLargeRJets The indices of the large-R jets to keep + * + */ + virtual void overlapremoval(const xAOD::PhotonContainer* photon, + const xAOD::ElectronContainer* el, + const xAOD::MuonContainer* mu, + const xAOD::TauJetContainer* tau, + const xAOD::JetContainer* jet, + const xAOD::JetContainer* ljet, + std::vector<unsigned int>& goodPhotons, + std::vector<unsigned int>& goodElectrons, + std::vector<unsigned int>& goodMuons, + std::vector<unsigned int>& goodTaus, + std::vector<unsigned int>& goodJets, + std::vector<unsigned int>& goodLargeRJets, + const bool isLooseEvent); + + ///Print something useful to the screen + virtual void print(std::ostream&) const; protected: - - /// For a generic container of type DataVector, fill a vector of - /// ints for objects we want to keep - virtual void removeObjectOverlap( const xAOD::IParticleContainer* xaod , - std::vector<unsigned int>& OUT_vec, - const std::string passTopCuts); + /// For a generic container of type DataVector, fill a vector of + /// ints for objects we want to keep + virtual void removeObjectOverlap(const xAOD::IParticleContainer* xaod, + std::vector<unsigned int>& OUT_vec, + const std::string passTopCuts); - /// For a generic container of type DataVector, fill a vector of - /// ints for objects we want to keep - /// This doesn't check for overlap removal (Large R jets) - virtual void removeObject( const xAOD::IParticleContainer* xaod , - std::vector<unsigned int>& OUT_vec, - const std::string passTopCuts); + /// For a generic container of type DataVector, fill a vector of + /// ints for objects we want to keep + /// This doesn't check for overlap removal (Large R jets) + virtual void removeObject(const xAOD::IParticleContainer* xaod, + std::vector<unsigned int>& OUT_vec, + const std::string passTopCuts); - // ASG overlap removal tool - asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool; - asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalToolLoose; + // ASG overlap removal tool + asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool; + asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalToolLoose; - const std::string m_passPreORSelection; - const std::string m_passPreORSelectionLoose; - const std::string m_overlaps; // true if object overlaps with another - - bool m_doLargeJet; + const std::string m_passPreORSelection; + const std::string m_passPreORSelectionLoose; + const std::string m_overlaps; // true if object overlaps with another + bool m_doLargeJet; }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalBase.h index a88009b7d1dd..305b1600dc00 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef OVERLAPREMOVALBASE_H_ #define OVERLAPREMOVALBASE_H_ @@ -12,38 +12,36 @@ #include "xAODTau/TauJetContainer.h" namespace top { - -class OverlapRemovalBase { -public: + class OverlapRemovalBase { + public: OverlapRemovalBase(); virtual ~OverlapRemovalBase(); OverlapRemovalBase(const OverlapRemovalBase& rhs) = delete; OverlapRemovalBase(OverlapRemovalBase&& rhs) = delete; - OverlapRemovalBase& operator=(const OverlapRemovalBase& rhs) = delete; - - virtual void overlapremoval(const xAOD::PhotonContainer* photon , - const xAOD::ElectronContainer* el , - const xAOD::MuonContainer* mu , - const xAOD::TauJetContainer* tau , - const xAOD::JetContainer* jet , - const xAOD::JetContainer* ljet, - std::vector<unsigned int>& goodPhotons, + OverlapRemovalBase& operator = (const OverlapRemovalBase& rhs) = delete; + + virtual void overlapremoval(const xAOD::PhotonContainer* photon, + const xAOD::ElectronContainer* el, + const xAOD::MuonContainer* mu, + const xAOD::TauJetContainer* tau, + const xAOD::JetContainer* jet, + const xAOD::JetContainer* ljet, + std::vector<unsigned int>& goodPhotons, std::vector<unsigned int>& goodElectrons, std::vector<unsigned int>& goodMuons, std::vector<unsigned int>& goodTaus, std::vector<unsigned int>& goodJets, std::vector<unsigned int>& goodLargeRJets, - const bool isLooseEvent ) = 0; - + const bool isLooseEvent) = 0; + virtual bool overlapsEl(std::vector<unsigned int>&) {return false;} virtual bool overlapsMu(std::vector<unsigned int>&) {return false;} virtual void print(std::ostream&) const = 0; -}; + }; + std::ostream& operator << (std::ostream& os, const top::OverlapRemovalBase& overlapremoval); } -std::ostream& operator<<(std::ostream& os, const top::OverlapRemovalBase& overlapremoval); - #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalIndices.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalIndices.h index ea92eab8ebc4..f35aa2048aba 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalIndices.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/OverlapRemovalIndices.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: OverlapRemovalIndices.h 661110 2015-04-17 00:03:39Z morrisj $ #ifndef ANALYSISTOP_TOPOBJECTSELECTONTOOLS_OVERLAPREMOVALINDICES_H #define ANALYSISTOP_TOPOBJECTSELECTONTOOLS_OVERLAPREMOVALINDICES_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief OverlapRemovalIndices - * Do overlap removal based on selected indices - * - * $Revision: 661110 $ - * $Date: 2015-04-17 02:03:39 +0200 (Fri, 17 Apr 2015) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief OverlapRemovalIndices + * Do overlap removal based on selected indices + * + * $Revision: 661110 $ + * $Date: 2015-04-17 01:03:39 +0100 (Fri, 17 Apr 2015) $ + * + **/ // system include(s): #include <memory> @@ -24,65 +24,63 @@ #include "TopObjectSelectionTools/OverlapRemovalBase.h" namespace top { - /** * @brief The "standard" overlap removal for the top group */ - class OverlapRemovalIndices : public top::OverlapRemovalBase { - public: - ///Doesn't do anything - OverlapRemovalIndices(); + class OverlapRemovalIndices: public top::OverlapRemovalBase { + public: + ///Doesn't do anything + OverlapRemovalIndices(); - ///Doesn't do anything - virtual ~OverlapRemovalIndices(); + ///Doesn't do anything + virtual ~OverlapRemovalIndices(); - /** - * @brief Perform our "standard" overlap removal. - * - * This runs for every event. - * - * The overlap removal consists of: - * - (1) remove muon within dR < 0.4 of any jet - * - (2) remove single jet closest to an electron (within dR < 0.2) - * - (3) remove electron with dR < 0.4 of jet - * - * @param el All the electrons (even bad ones). Good ones are decorated - * with passPreORSelection = 1. - * @param mu All the muons in the event - * @param jet All the jets in the event - * @param ljet All the large-R jets in the event - * @param OUT_el The indices of the electrons to keep (e.g. the 0th, 2nd) - * @param OUT_mu The indices of the muons to keep - * @param OUT_jet The indices of the jets to keep - * @param OUT_ljet The indices of the large-R jets to keep - */ - virtual void overlapremoval(const xAOD::ElectronContainer* el , - const xAOD::MuonContainer* mu , - const xAOD::JetContainer* jet , - const xAOD::JetContainer* ljet , - std::vector<unsigned int>& OUT_el , - std::vector<unsigned int>& OUT_mu , - std::vector<unsigned int>& OUT_jet , - std::vector<unsigned int>& OUT_ljet , - const bool isLooseEvent ); + /** + * @brief Perform our "standard" overlap removal. + * + * This runs for every event. + * + * The overlap removal consists of: + * - (1) remove muon within dR < 0.4 of any jet + * - (2) remove single jet closest to an electron (within dR < 0.2) + * - (3) remove electron with dR < 0.4 of jet + * + * @param el All the electrons (even bad ones). Good ones are decorated + * with passPreORSelection = 1. + * @param mu All the muons in the event + * @param jet All the jets in the event + * @param ljet All the large-R jets in the event + * @param OUT_el The indices of the electrons to keep (e.g. the 0th, 2nd) + * @param OUT_mu The indices of the muons to keep + * @param OUT_jet The indices of the jets to keep + * @param OUT_ljet The indices of the large-R jets to keep + */ + virtual void overlapremoval(const xAOD::ElectronContainer* el, + const xAOD::MuonContainer* mu, + const xAOD::JetContainer* jet, + const xAOD::JetContainer* ljet, + std::vector<unsigned int>& OUT_el, + std::vector<unsigned int>& OUT_mu, + std::vector<unsigned int>& OUT_jet, + std::vector<unsigned int>& OUT_ljet, + const bool isLooseEvent); - virtual void overlapremoval(const xAOD::PhotonContainer* photon , - const xAOD::ElectronContainer* el , - const xAOD::MuonContainer* mu , - const xAOD::TauJetContainer* tau , - const xAOD::JetContainer* jet , - const xAOD::JetContainer* ljet, - std::vector<unsigned int>& goodPhotons, - std::vector<unsigned int>& goodElectrons, - std::vector<unsigned int>& goodMuons, - std::vector<unsigned int>& goodTaus, - std::vector<unsigned int>& goodJets, - std::vector<unsigned int>& goodLargeRJets, - const bool isLooseEvent ); + virtual void overlapremoval(const xAOD::PhotonContainer* photon, + const xAOD::ElectronContainer* el, + const xAOD::MuonContainer* mu, + const xAOD::TauJetContainer* tau, + const xAOD::JetContainer* jet, + const xAOD::JetContainer* ljet, + std::vector<unsigned int>& goodPhotons, + std::vector<unsigned int>& goodElectrons, + std::vector<unsigned int>& goodMuons, + std::vector<unsigned int>& goodTaus, + std::vector<unsigned int>& goodJets, + std::vector<unsigned int>& goodLargeRJets, + const bool isLooseEvent); - ///Print something useful to the screen - virtual void print(std::ostream&) const; + ///Print something useful to the screen + virtual void print(std::ostream&) const; }; - } -#endif +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/PhotonMC16.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/PhotonMC16.h new file mode 100644 index 000000000000..9990990988a8 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/PhotonMC16.h @@ -0,0 +1,110 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TOPOBJECTSELECTIONTOOLS_PHOTONMC16_H_ +#define TOPOBJECTSELECTIONTOOLS_PHOTONMC16_H_ + +#include <memory> +#include <string> + +#include "TopObjectSelectionTools/PhotonSelectionBase.h" +#include "TopObjectSelectionTools/IsolationTools.h" + +#include "ElectronPhotonSelectorTools/AsgPhotonIsEMSelector.h" + +namespace top { +/** + * @brief Photon selection for top analyses. + * For Release 21 specific cleaning + */ + + class PhotonMC16: public top::PhotonSelectionBase { + public: + /** + * @brief Class to help select good photons. + * + * @param ptcut The minimum pT cut to apply to the photons. + * @param etamax The maximum eta cut + * @param isolation nullptr for un-isolated, or a new "isolation object" to + * @param usePhotonShowerShapeVariables to turn on/off the reading of shower shape variables + * apply isolation cuts + */ + PhotonMC16(double ptcut, double etamax, IsolationBase* isolation, bool usePhotonShowerShapeVariables); + + /** + * @brief Class to help select good photons. + * + * @param ptcut The minimum pT cut to apply to the photons. + * @param etamax The maximum eta cut + * @param tightID The ID level used to select tight photons. + * @param looseID The ID level used to select loose photons. + * @param isolation nullptr for un-isolated, or a new "isolation object" to + * @param usePhotonShowerShapeVariables to turn on/off the reading of shower shape variables + * apply isolation cuts + */ + PhotonMC16(double ptcut, double etamax, + const std::string& tightID, + const std::string& looseID, + IsolationBase* isolation, + bool usePhotonShowerShapeVariables); + + /** + * @brief The cuts to select good photons for your analysis should be + * implemented in here. + * + * @param ph The photon to cut on (all photons in the event are passed + * to the tool) + * @return True if this is a good photon, false otherwise. + */ + bool passSelection(const xAOD::Photon& ph) const override; + + /** + * @brief The loose selection. + * + * @param ph + * @return + */ + bool passSelectionLoose(const xAOD::Photon& ph) const override; + + /** + * @brief Print some useful information about the photon selection. + * + * Usually this goes to the log file, so you know what you ran with. + * + * @param Where the print-out should go, e.g. msg stream. + */ + void print(std::ostream&) const override; + private: + /** + * @brief Do all the cuts except for the isolation. + * + * @param ph The photon in question + * @return True if the photon passes + */ + bool passSelectionNoIsolation(const xAOD::Photon& ph, + const std::string& photon_selection) const; + + std::string getConfigFile(int operatingPoint); + + // minimum pT cut to apply + double m_ptcut; + + // max eta cut + double m_etamax; + + std::string m_photon_selection; + std::string m_loose_photon_selection; + + // Proper tool to select photons. + // ToolHandle<AsgPhotonIsEMSelector> m_photonTightIsEMSelector; + // ToolHandle<AsgPhotonIsEMSelector> m_photonMediumIsEMSelector; + // ToolHandle<AsgPhotonIsEMSelector> m_photonLooseIsEMSelector; + + // The isolation tool, or nullptr if we don't want isolation + std::unique_ptr<top::IsolationBase> m_isolation; + + mutable bool m_usePhotonShowerShapeVariables; + }; +} // namespace top +#endif // TOPOBJECTSELECTIONTOOLS_PHOTONMC16_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/PhotonSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/PhotonSelectionBase.h index bb1015d25c44..11c602044d46 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/PhotonSelectionBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/PhotonSelectionBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef PHOTONSELECTIONBASE_H_ #define PHOTONSELECTIONBASE_H_ @@ -10,7 +10,6 @@ #include <memory> namespace top { - /** * @brief Base class for implementing an Photon selection. * @@ -18,19 +17,19 @@ namespace top { * */ -class PhotonSelectionBase { -public: + class PhotonSelectionBase { + public: PhotonSelectionBase(); virtual ~PhotonSelectionBase(); ///No copy construction PhotonSelectionBase(const PhotonSelectionBase& rhs) = delete; - ///No moving + ///No moving PhotonSelectionBase(PhotonSelectionBase&& rhs) = delete; ///No assignment - PhotonSelectionBase& operator=(const PhotonSelectionBase& rhs) = delete; + PhotonSelectionBase& operator = (const PhotonSelectionBase& rhs) = delete; ///For the main analysis object selection virtual bool passSelection(const xAOD::Photon&) const = 0; @@ -40,10 +39,9 @@ public: ///Because everybody likes to know what object definitions they ran with virtual void print(std::ostream&) const = 0; -}; + }; + std::ostream& operator << (std::ostream& os, const top::PhotonSelectionBase& selection); } -std::ostream& operator<<(std::ostream& os, const top::PhotonSelectionBase& selection); - #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/SoftMuonMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/SoftMuonMC15.h new file mode 100644 index 000000000000..7aca4ee0de27 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/SoftMuonMC15.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef SOFTMUONMC15_H_ +#define SOFTMUONMC15_H_ + +#include "TopObjectSelectionTools/SoftMuonSelectionBase.h" +#include "TopObjectSelectionTools/IsolationTools.h" + +#include "AsgTools/ToolHandle.h" +#include "MuonAnalysisInterfaces/IMuonSelectionTool.h" + +namespace top { +/** + * @brief Select muons based on some early MC15 suggestions. + */ + class SoftMuonMC15: public SoftMuonSelectionBase { + public: + /** + * @brief Construct the tool to select good muons. + * + * @param ptcut The minimum pT cut for good muons. + * @param isolation The isolation the user wants to apply. Don't want any + * isolation to be applied? Then leave this as a nullptr. + */ + SoftMuonMC15(const double ptcut); + + // Does nothing. + virtual ~SoftMuonMC15() {} + + /** + * @brief Implements the logic to select good muons. + * + * @param mu The muon that we want to check. + * @return True if the muon is good, false otherwise. + */ + virtual bool passSelection(const xAOD::Muon& mu) const override; + + // Print the cuts to the ostream. + virtual void print(std::ostream& os) const override; + protected: + // Lower pT threshold to apply to object selection. + double m_ptcut; + + // Proper tool to select muons. + ToolHandle<CP::IMuonSelectionTool> m_softmuonSelectionTool; + }; +} // namespace top + +#endif // SOFTMUONMC15_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/SoftMuonSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/SoftMuonSelectionBase.h new file mode 100644 index 000000000000..c4e91235706e --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/SoftMuonSelectionBase.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef SOFTMUONSELECTIONBASE_H_ +#define SOFTMUONSELECTIONBASE_H_ + +#include "xAODMuon/Muon.h" + +namespace top { + class SoftMuonSelectionBase { + public: + SoftMuonSelectionBase(); + virtual ~SoftMuonSelectionBase(); + + ///No copy construction + SoftMuonSelectionBase(const SoftMuonSelectionBase& rhs) = delete; + + ///No moving - really? Seems a bit strict. We'll see + SoftMuonSelectionBase(SoftMuonSelectionBase&& rhs) = delete; + + ///No assignment + SoftMuonSelectionBase& operator = (const SoftMuonSelectionBase& rhs) = delete; + + ///For the main analysis object selection + virtual bool passSelection(const xAOD::Muon&) const = 0; + + ///Because everybody likes to know what object definitions they ran with + virtual void print(std::ostream&) const = 0; + }; + + std::ostream& operator << (std::ostream& os, const top::SoftMuonSelectionBase& selection); +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TauMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TauMC15.h index aa343e8e5d1d..455614d42889 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TauMC15.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TauMC15.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TOPOBJECTSELECTIONTOOLS_TAUMC15_H_ #define TOPOBJECTSELECTIONTOOLS_TAUMC15_H_ @@ -13,48 +13,44 @@ #include "TopEvent/EventTools.h" namespace top { - /** * @brief To select taus based on BoostedDecisionTree definition. */ -class TauMC15 : public top::TauSelectionBase { - public: - TauMC15(); - - virtual ~TauMC15() {} - /** - * @brief Selection for the main analysis (i.e. tight object definitions). - * - * @param tauJet The tau in question - * @return True if it passes the selection, false otherwise. - */ - bool passSelection(const xAOD::TauJet& tau) const override; - - /** - * @brief Selection for the "loose" object definitions (e.g. in fakes - * estimates). - * - * @param tauJet The tau in question - * @return True if it passes the selection, false otherwise. - */ - bool passSelectionLoose(const xAOD::TauJet& tau) const override; - - /** - * @brief Why would you not want to know what you're running? - * - * @param os Print details of the cuts to the output stream. - */ - void print(std::ostream& os) const override; - - - protected: - // The selection tool to use for the tight (main) analysis. - ToolHandle<TauAnalysisTools::TauSelectionTool> m_tauSelection; - - // The selection tool to use for the loose (e.g. fakes) object selection. - ToolHandle<TauAnalysisTools::TauSelectionTool> m_tauSelectionLoose; -}; - + class TauMC15: public top::TauSelectionBase { + public: + TauMC15(); + + virtual ~TauMC15() {} + /** + * @brief Selection for the main analysis (i.e. tight object definitions). + * + * @param tauJet The tau in question + * @return True if it passes the selection, false otherwise. + */ + bool passSelection(const xAOD::TauJet& tau) const override; + + /** + * @brief Selection for the "loose" object definitions (e.g. in fakes + * estimates). + * + * @param tauJet The tau in question + * @return True if it passes the selection, false otherwise. + */ + bool passSelectionLoose(const xAOD::TauJet& tau) const override; + + /** + * @brief Why would you not want to know what you're running? + * + * @param os Print details of the cuts to the output stream. + */ + void print(std::ostream& os) const override; + protected: + // The selection tool to use for the tight (main) analysis. + ToolHandle<TauAnalysisTools::TauSelectionTool> m_tauSelection; + + // The selection tool to use for the loose (e.g. fakes) object selection. + ToolHandle<TauAnalysisTools::TauSelectionTool> m_tauSelectionLoose; + }; } // namespace top #endif // TOPOBJECTSELECTIONTOOLS_TAUMC15_H_ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TauSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TauSelectionBase.h index 4a106f8b8280..702fb5749c7e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TauSelectionBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TauSelectionBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TAUSELECTIONBASE_H_ #define TAUSELECTIONBASE_H_ @@ -8,12 +8,11 @@ #include "xAODTau/TauJet.h" namespace top { - -class TauSelectionBase { -public: + class TauSelectionBase { + public: TauSelectionBase(); virtual ~TauSelectionBase(); - + ///No copy construction TauSelectionBase(const TauSelectionBase& rhs) = delete; @@ -21,7 +20,7 @@ public: TauSelectionBase(TauSelectionBase&& rhs) = delete; ///No assignment - TauSelectionBase& operator=(const TauSelectionBase& rhs) = delete; + TauSelectionBase& operator = (const TauSelectionBase& rhs) = delete; ///For the main analysis object selection virtual bool passSelection(const xAOD::TauJet&) const = 0; @@ -30,11 +29,10 @@ public: virtual bool passSelectionLoose(const xAOD::TauJet&) const = 0; ///Because everybody likes to know what object definitions they ran with - virtual void print(std::ostream&) const = 0; -}; - + virtual void print(std::ostream&) const = 0; + }; } -std::ostream& operator<<(std::ostream& os, const top::TauSelectionBase& selection); +std::ostream& operator << (std::ostream& os, const top::TauSelectionBase& selection); #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TopObjectSelection.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TopObjectSelection.h index 31b0b8d8af0e..02ab3e54891f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TopObjectSelection.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TopObjectSelection.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ -// $Id: TopObjectSelection.h 802995 2017-04-17 01:23:28Z tpelzer $ +// $Id: TopObjectSelection.h 810745 2017-09-29 14:03:01Z iconnell $ #ifndef ANALYSISTOP_TOPOBJECTSELECTONTOOLS_TOPOBJECTSELECTION_H #define ANALYSISTOP_TOPOBJECTSELECTONTOOLS_TOPOBJECTSELECTION_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief TopObjectSelection - * Selects top objects according to the ObjectLoaderBase type - * - * $Revision: 802995 $ - * $Date: 2017-04-17 03:23:28 +0200 (Mon, 17 Apr 2017) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief TopObjectSelection + * Selects top objects according to the ObjectLoaderBase type + * + * $Revision: 810745 $ + * $Date: 2017-09-29 15:03:01 +0100 (Fri, 29 Sep 2017) $ + * + **/ // system include(s): #include <memory> @@ -23,35 +23,51 @@ // Framework include(s): #include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" +#include "AsgTools/ToolHandleArray.h" +#include "AsgTools/AnaToolHandle.h" +#include "AssociationUtils/IOverlapRemovalTool.h" // Top include(s): #include "TopObjectSelectionTools/ElectronSelectionBase.h" +#include "TopObjectSelectionTools/FwdElectronSelectionBase.h" #include "TopObjectSelectionTools/MuonSelectionBase.h" +#include "TopObjectSelectionTools/SoftMuonSelectionBase.h" #include "TopObjectSelectionTools/JetSelectionBase.h" +#include "TopObjectSelectionTools/JetGhostTrackSelectionBase.h" #include "TopObjectSelectionTools/TauSelectionBase.h" #include "TopObjectSelectionTools/PhotonSelectionBase.h" +#include "TopObjectSelectionTools/TrackSelectionBase.h" #include "TopObjectSelectionTools/OverlapRemovalBase.h" - #include "TopSystematicObjectMaker/ElectronInJetSubtractionCollectionMaker.h" -#include "xAODBTaggingEfficiency/BTaggingSelectionTool.h" +// boosted-tagging includes +//#include "BoostedJetTaggers/SmoothedTopTagger.h" +//#include "BoostedJetTaggers/SmoothedWZTagger.h" +//#include "BoostedJetTaggers/JSSWTopTaggerDNN.h" + +// b-tagging +#include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h" #include "TopEvent/Event.h" +#include "xAODMuon/MuonContainer.h" +#include "xAODJet/JetContainer.h" + // forward declare -namespace xAOD{ +namespace xAOD { class SystematicEvent; } namespace top { -class TopConfig; + class TopConfig; /** * @brief Configure the object selection used in the analysis. The user should * be able to configure this, or if they really really want to, then overload it * with a class based on TopObjectSelection and load that at run time. Crazy. */ -class TopObjectSelection : public asg::AsgTool { -public: + class TopObjectSelection: public asg::AsgTool { + public: /** * @brief Setup the object selection at the start of the run. * @@ -59,16 +75,16 @@ public: * of information about what the user wants (which containers to load for * example). Note that it's not a smart pointer (yet) because of root5 * restrictions on dynamic class loading. - * + * */ - explicit TopObjectSelection( const std::string& name ); - virtual ~TopObjectSelection(){} + explicit TopObjectSelection(const std::string& name); + virtual ~TopObjectSelection() {} // Delete Standard constructors TopObjectSelection(const TopObjectSelection& rhs) = delete; TopObjectSelection(TopObjectSelection&& rhs) = delete; - TopObjectSelection& operator=(const TopObjectSelection& rhs) = delete; - + TopObjectSelection& operator = (const TopObjectSelection& rhs) = delete; + StatusCode initialize(); /** @@ -77,7 +93,7 @@ public: * * @param topEvt The top event containing all the systematic variations. */ - StatusCode execute(); + StatusCode execute(bool); /** * @brief Set the code used to select electrons. @@ -90,6 +106,18 @@ public: */ void electronSelection(ElectronSelectionBase* ptr); + + /** + * @brief Set the code used to select forward electrons. + * + * Note that nullptr means that no selection will be applied (so all + * electrons will be accepted). + * + * @param ptr The code used to perform the forward electron selection (see + * TopObjectSelectionTools). + */ + void fwdElectronSelection(FwdElectronSelectionBase* ptr); + /** * @brief Set the code used to select muons. * @@ -100,17 +128,28 @@ public: * TopObjectSelectionTools). */ void muonSelection(MuonSelectionBase* ptr); - - /** - * @brief Set the code used to select taus. + + /** + * @brief Set the code used to select soft muons. * * Note that nullptr means that no selection will be applied (so all * muons will be accepted). * - * @param ptr The code used to perform the muon selection (see + * @param ptr The code used to perform the soft muon selection (see + * TopObjectSelectionTools). + */ + void softmuonSelection(SoftMuonSelectionBase* ptr); + + /** + * @brief Set the code used to select taus. + * + * Note that nullptr means that no selection will be applied (so all + * taus will be accepted). + * + * @param ptr The code used to perform the taus selection (see * TopObjectSelectionTools). */ - void tauSelection(TauSelectionBase* ptr); + void tauSelection(TauSelectionBase* ptr); /** * @brief Set the code used to select jets. @@ -133,7 +172,7 @@ public: * TopObjectSelectionTools). */ void photonSelection(PhotonSelectionBase* ptr); - + /** * @brief Set the code used to select large jets. @@ -145,7 +184,7 @@ public: * TopObjectSelectionTools). */ void largeJetSelection(JetSelectionBase* ptr); - + /** * @brief Set the code used to select track jets. * @@ -155,7 +194,30 @@ public: * @param ptr The code used to perform the track jets selection (see * TopObjectSelectionTools). */ - void trackJetSelection(JetSelectionBase* ptr); + void trackJetSelection(JetSelectionBase* ptr); + + /** + * @brief Set the code used to select tracks ghost associated to small-R jets. + * + * Note that nullptr means that no selection will be applied (so all + * tracks associated to jets will be accepted) a part from the one during the thinning. + * + * @param ptr The code used to perform the ghost track selection (see + * TopObjectSelectionTools). + */ + void jetGhostTrackSelection(JetGhostTrackSelectionBase* ptr); + + /** + * @brief Set the code used to select tracks. + * + * Note that nullptr means that no selection will be applied (so all + * tracks will be accepted). + * + * @param ptr The code used to perform the track selection (see + * TopObjectSelectionTools). + **/ + void trackSelection(TrackSelectionBase* ptr); + /** * @brief Set the code used to perform the overlap removal. At the moment @@ -171,37 +233,44 @@ public: * @brief Print details of this object selection to wherever the user asks * for. Useful for checking cuts in the log files I hope! * - * @param os Where you would like the output printing to, presumably std::cout? + * @param os Where you would like the output printing to, e.g. msg stream. */ virtual void print(std::ostream& os) const; - + /** * @brief or prehaps you'd like the AsgTool print function */ virtual void print() const; - -private: + private: void applySelectionPreOverlapRemoval(); void applySelectionPreOverlapRemovalPhotons(); void applySelectionPreOverlapRemovalElectrons(); + void applySelectionPreOverlapRemovalFwdElectrons(); void applySelectionPreOverlapRemovalMuons(); + void applySelectionPreOverlapRemovalSoftMuons(); void applySelectionPreOverlapRemovalTaus(); void applySelectionPreOverlapRemovalJets(); void applySelectionPreOverlapRemovalLargeRJets(); void applySelectionPreOverlapRemovalTrackJets(); - - virtual StatusCode applyOverlapRemoval(); - virtual StatusCode applyOverlapRemoval(const bool isLoose,const std::string& sgKey); + void applySelectionPreOverlapRemovalJetGhostTracks(); + void applySelectionPreOverlapRemovalTracks(); + + virtual StatusCode applyOverlapRemoval(); + virtual StatusCode applyOverlapRemoval(const bool isLoose, const std::string& sgKey); virtual StatusCode applyOverlapRemoval(xAOD::SystematicEvent* currentSystematic); - - void applyTightSelectionPostOverlapRemoval( const xAOD::IParticleContainer* xaod , std::vector<unsigned int>& indices ); - void trackJetOverlapRemoval(const xAOD::IParticleContainer* xaod_el, - const xAOD::IParticleContainer* xaod_mu, - const xAOD::IParticleContainer* xaod_tjet, + + void applyTightSelectionPostOverlapRemoval(const xAOD::IParticleContainer* xaod, + std::vector<unsigned int>& indices); + void trackJetOverlapRemoval(const xAOD::IParticleContainer* xaod_el, + const xAOD::IParticleContainer* xaod_mu, + const xAOD::IParticleContainer* xaod_tjet, std::vector<unsigned int>& goodElectrons, std::vector<unsigned int>& goodMuons, - std::vector<unsigned int>& goodTrackJets); - + std::vector<unsigned int>& goodTrackJets); + + void decorateSoftMuonsPostOverlapRemoval(const xAOD::MuonContainer* xaod_softmu, + std::vector<unsigned int>& goodMuons); + /** * @brief Pointer to the configuration object so we can check which objects * were requested in the config file. @@ -211,44 +280,67 @@ private: ///Electron selection code - can load user defined classes std::unique_ptr<top::ElectronSelectionBase> m_electronSelection; + ///Fwd Electron selection code - can load user defined classes + std::unique_ptr<top::FwdElectronSelectionBase> m_fwdElectronSelection; + ///Muon selection code - can load user defined classes std::unique_ptr<top::MuonSelectionBase> m_muonSelection; + ///Soft Muon selection code - can load user defined classes + std::unique_ptr<top::SoftMuonSelectionBase> m_softmuonSelection; + ///Tau selection code - can load user defined classes std::unique_ptr<top::TauSelectionBase> m_tauSelection; ///Jet selection code - can load user defined classes std::unique_ptr<top::JetSelectionBase> m_jetSelection; - ///Photon selection code - can load user defined classes + ///Photon selection code - can load user defined classes std::unique_ptr<top::PhotonSelectionBase> m_photonSelection; ///Large-R jet selection code - can load user defined classes std::unique_ptr<top::JetSelectionBase> m_largeJetSelection; - + ///Track jet selection code - can load user defined classes - std::unique_ptr<top::JetSelectionBase> m_trackJetSelection; + std::unique_ptr<top::JetSelectionBase> m_trackJetSelection; + + ///Ghost Track associated to small-R jets selection code - can load user defined classes + std::unique_ptr<top::JetGhostTrackSelectionBase> m_jetGhostTrackSelection; + + ///Track selection code - can load user defined classes + std::unique_ptr<top::TrackSelectionBase> m_trackSelection; ///Overlap removal that runs after all object selection std::unique_ptr<top::OverlapRemovalBase> m_overlapRemovalToolPostSelection; - + //Electron In Jet Subtraction std::unique_ptr<top::ElectronInJetSubtractionCollectionMaker> m_electronInJetSubtractor; - + // Pass selection strings const std::string m_passPreORSelection; const std::string m_passPreORSelectionLoose; - // the following two are used to give failing JVT jets a lower priority in the OR + // the following two are used to give failing JVT and failing fJVT jets a lower priority in the OR const std::string m_ORToolDecoration; const std::string m_ORToolDecorationLoose; - + // Do we need to request loose lepton selection bool m_doLooseCuts; - + // do decorate the jets with the b-tagging flags - std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool>> m_btagSelTools; - std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool>> m_trkjet_btagSelTools; -}; + std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool> > m_btagSelTools; + std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool> > m_trkjet_btagSelTools; + + // Boolean to handle only running selection on nominal/systematics + bool m_executeNominal; + + //helper OR tool for soft muons + asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool_softMuons_PFjets; + asg::AnaToolHandle<ORUtils::IOverlapRemovalTool> m_overlapRemovalTool_softMuons_Alljets; + + // Function to decorate event info + void decorateEventInfoPostOverlapRemoval(int, bool); + float calculateMinDRMuonJet(const xAOD::Muon& mu, const xAOD::JetContainer* xaod_jet, std::vector<unsigned int>& goodJets, bool useRapidity=false); + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackJetMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackJetMC15.h index b36b72ba12c2..08c3e78514b9 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackJetMC15.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackJetMC15.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TRACKJETMC15_H_ #define TRACKJETMC15_H_ @@ -8,17 +8,15 @@ #include "TopObjectSelectionTools/JetSelectionBase.h" namespace top { - class TrackJetMC15 : public top::JetSelectionBase { - public: - TrackJetMC15(const double ptcut,const double etamax); - ~TrackJetMC15(); - virtual bool passSelection(const xAOD::Jet& jet) override; - virtual void print(std::ostream& os) const override; - private: - double m_ptcut; - double m_etamax; - - + class TrackJetMC15: public top::JetSelectionBase { + public: + TrackJetMC15(const double ptcut, const double etamax); + ~TrackJetMC15(); + virtual bool passSelection(const xAOD::Jet& jet) override; + virtual void print(std::ostream& os) const override; + private: + double m_ptcut; + double m_etamax; }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackSelection.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackSelection.h new file mode 100644 index 000000000000..044cc995b741 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackSelection.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TRACKSELECTION_H_ +#define TRACKSELECTION_H_ + +#include "TopObjectSelectionTools/TrackSelectionBase.h" +#include "InDetTrackSelectionTool/InDetTrackSelectionTool.h" + +#include "xAODTracking/VertexContainer.h" +#include "xAODTracking/Vertex.h" + + +namespace top { + class TrackSelection: public TrackSelectionBase { + public: + TrackSelection(const double ptcut, const double etamax); + virtual ~TrackSelection(); +// virtual bool passSelection(const xAOD::TrackParticle&, const xAOD::Vertex&) override; + virtual void print(std::ostream& os) const override; + private: + double m_ptcut; + double m_etamax; + + ToolHandle<InDet::IInDetTrackSelectionTool> m_trkseltool; + + }; +} +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackSelectionBase.h new file mode 100644 index 000000000000..ca63c80c8d3f --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TrackSelectionBase.h @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TRACKSELECTIONBASE_H_ +#define TRACKSELECTIONBASE_H_ + +#include "xAODTracking/TrackParticle.h" + +namespace top { + class TrackSelectionBase { + public: + TrackSelectionBase(); + virtual ~TrackSelectionBase(); + + ///For the main analysis object selection +// virtual bool passSelection(const xAOD::TrackParticle&, const xAOD::Vertex&) = 0; + ///Because everybody likes to know what object definitions they ran with + virtual void print(std::ostream&) const = 0; + }; +} + +std::ostream& operator << (std::ostream& os, const top::TrackSelectionBase& selection); + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TruthSelectionBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TruthSelectionBase.h index b875e44d189b..2a6fade11224 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TruthSelectionBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TruthSelectionBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TRUTHSELECTIONBASE_H_ #define TRUTHSELECTIONBASE_H_ @@ -9,34 +9,32 @@ #include <memory> - /** - * @brief Base class for implementing a truth selection. - * - * If you want to build a new truth selection, you should inherit from this. - */ - -namespace top { +/** + * @brief Base class for implementing a truth selection. + * + * If you want to build a new truth selection, you should inherit from this. + */ +namespace top { class TruthSelectionBase { - public: - TruthSelectionBase(); + public: + TruthSelectionBase(); - virtual ~TruthSelectionBase(){} + virtual ~TruthSelectionBase() {} - virtual bool passSelection(const xAOD::TruthParticle&) const = 0; + virtual bool passSelection(const xAOD::TruthParticle&) const = 0; - virtual void print(std::ostream&) const = 0; - - protected: - bool isBhadron(int pid) const; - bool isChadron(int pid) const; + virtual void print(std::ostream&) const = 0; + protected: + bool isBhadron(int pid) const; + bool isChadron(int pid) const; - TruthSelectionBase(const TruthSelectionBase& rhs); - TruthSelectionBase(const TruthSelectionBase&& rhs); - void operator=(const TruthSelectionBase& rhs); + TruthSelectionBase(const TruthSelectionBase& rhs); + TruthSelectionBase(const TruthSelectionBase&& rhs); + void operator = (const TruthSelectionBase& rhs); }; } -std::ostream& operator<<(std::ostream& os, const top::TruthSelectionBase& selection); +std::ostream& operator << (std::ostream& os, const top::TruthSelectionBase& selection); #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TruthSelectionTtres.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TruthSelectionTtres.h index 462c0462bf6f..63c22cb745b5 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TruthSelectionTtres.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/TruthSelectionTtres.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef TRUTHSELECTIONTTRES_H_ #define TRUTHSELECTIONTTRES_H_ @@ -8,42 +8,38 @@ #include "TopObjectSelectionTools/TruthSelectionBase.h" - /** - * @brief An example class implementing a truth selection for tt resonances. - * - */ +/** + * @brief An example class implementing a truth selection for tt resonances. + * + */ namespace top { - - class TruthSelectionTtres : public top::TruthSelectionBase { - public: - - TruthSelectionTtres(); - /** - * @brief Doesn't do anything itself. - */ - virtual ~TruthSelectionTtres(){} - - /** - * @brief The cuts (per object) are implemented in here. - * - * Not that I've marked this as final, to stop people going crazy with - * inheritance. Why not just inherit from TruthSelectionBase instead? - * - * @param mc The particle to cut on. - * @return True if you want to keep this particle, false otherwise. - */ - bool passSelection(const xAOD::TruthParticle& mc) const override final; - - ///Print the cuts to the ostream. - void print(std::ostream& os) const override final; - - private: - TruthSelectionTtres(const TruthSelectionTtres& rhs); - TruthSelectionTtres(const TruthSelectionTtres&& rhs); - void operator=(const TruthSelectionTtres& rhs); + class TruthSelectionTtres: public top::TruthSelectionBase { + public: + TruthSelectionTtres(); + /** + * @brief Doesn't do anything itself. + */ + virtual ~TruthSelectionTtres() {} + + /** + * @brief The cuts (per object) are implemented in here. + * + * Not that I've marked this as final, to stop people going crazy with + * inheritance. Why not just inherit from TruthSelectionBase instead? + * + * @param mc The particle to cut on. + * @return True if you want to keep this particle, false otherwise. + */ + bool passSelection(const xAOD::TruthParticle& mc) const override final; + + ///Print the cuts to the ostream. + void print(std::ostream& os) const override final; + private: + TruthSelectionTtres(const TruthSelectionTtres& rhs); + TruthSelectionTtres(const TruthSelectionTtres&& rhs); + void operator = (const TruthSelectionTtres& rhs); }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/CMakeLists.txt index 9cc50fae456d..1462dd37605a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/CMakeLists.txt @@ -5,19 +5,31 @@ atlas_subdir( TopParticleLevel None ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC + xAODBase xAODTruth xAODJet xAODMissingET xAODCore xAODRootAccess + FourMomUtils TopEvent TopConfiguration - TruthUtils - MCTruthClassifier ) + TopDataPreparation + TruthUtils + MCTruthClassifier + JetReclustering + JetSubStructureUtils + AsgTools + + ) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) +# Need fast jet for the RC jet substructure code +find_package( FastJet COMPONENTS fastjetplugins fastjettools ) +find_package( FastJetContrib COMPONENTS EnergyCorrelator Nsubjettiness ) + # Custom definitions needed for this package: add_definitions( -g ) @@ -26,15 +38,24 @@ atlas_add_library( TopParticleLevel Root/*.cxx Root/*.h Root/*.icc TopParticleLevel/*.h TopParticleLevel/*.icc TopParticleLevel/*/*.h TopParticleLevel/*/*.icc PUBLIC_HEADERS TopParticleLevel - LINK_LIBRARIES xAODTruth + LINK_LIBRARIES + xAODBase + xAODTruth xAODJet xAODMissingET xAODCore xAODRootAccess + FourMomUtils TopEvent TopConfiguration + TopDataPreparation MCTruthClassifierLib - TruthUtils - ${ROOT_LIBRARIES} + TruthUtils + JetReclusteringLib + JetSubStructureUtils + AsgTools + ${ROOT_LIBRARIES} + ${FASTJET_LIBRARIES} + ${FASTJETCONTRIB_LIBRARIES} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/MsgCategory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/MsgCategory.cxx new file mode 100644 index 000000000000..902b85113fc0 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/MsgCategory.cxx @@ -0,0 +1,6 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#include "TopParticleLevel/MsgCategory.h" + +ANA_MSG_SOURCE(TopParticleLevel, "TopParticleLevel") diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelElectronObjectSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelElectronObjectSelector.cxx index 4c4f713403de..f8efd7900b2a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelElectronObjectSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelElectronObjectSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelElectronObjectSelector.cxx // Description: @@ -13,61 +13,63 @@ #include "TopParticleLevel/TruthTools.h" namespace top { + ParticleLevelElectronObjectSelector::ParticleLevelElectronObjectSelector(Options opt /* = Options() */) + : m_opt(opt) { /* Deliberately Empty */} - ParticleLevelElectronObjectSelector::ParticleLevelElectronObjectSelector( Options opt /* = Options() */ ) - : m_opt( opt ){ /* Deliberately Empty */ } + /* virtual */ bool + ParticleLevelElectronObjectSelector::apply(const xAOD::TruthParticle& truthParticle) { + // Obtain the particle type and particle origin from the decoration + // created by the MCTruthClassifier. For legacy reasons, try both + // decoration names. + unsigned int type; - /* virtual */ bool - ParticleLevelElectronObjectSelector::apply( const xAOD::TruthParticle & truthParticle ) { - - // Obtain the particle type and particle origin from the decoration - // created by the MCTruthClassifier. For legacy reasons, try both - // decoration names. - unsigned int type; - if ( truthParticle.isAvailable<unsigned int>( "particleType" ) ){ - type = truthParticle.auxdata<unsigned int>( "particleType" ); - } else if ( truthParticle.isAvailable<unsigned int>( "classifierParticleType" ) ){ - type = truthParticle.auxdata<unsigned int>( "classifierParticleType" ); - } else { - std::cerr << "Could not obtain MCTruthClassifier result decoration." << std::endl; - std::exit( 1 ); - } - - // -------------------------------------------------- - // Accept electrons iff they do not come from a hadron - using namespace MCTruthPartClassifier; - if ( m_opt.not_from_hadron && - type != ParticleType::IsoElectron ){ - return false; - } - - // If it is requested that tauons are hadrons, perform a check of the - // ancestry: It shall not contain a single tauon. - if ( m_opt.tau_is_hadron ){ - auto truthProxy = truthParticle.auxdata<ElementLink<xAOD::TruthParticleContainer> >( "originalTruthParticle" ); - if ( not truthProxy.isValid() ){ - std::cerr << "Could not obtain 'originalTruthParticle' reference." << std::endl; - std::exit( 1 ); - } - if ( truth::isLeptonFromTau( * truthProxy ) ){ - return false; - } - } + if (truthParticle.isAvailable<unsigned int>("particleType")) { + type = truthParticle.auxdata<unsigned int>("particleType"); + } else if (truthParticle.isAvailable<unsigned int>("classifierParticleType")) { + type = truthParticle.auxdata<unsigned int>("classifierParticleType"); + } else { + throw std::runtime_error("ParticleLevelElectronObjectSelector::apply: " + "Could not obtain MCTruthClassifier result decoration."); + } - // -------------------------------------------------- - // Apply kinematic cut on the dressed pT: - // must exceed 25 GeV - if ( truthParticle.auxdata<float>( "pt_dressed" ) < m_opt.pt_min ){ return false; } + // -------------------------------------------------- + // Accept electrons iff they do not come from a hadron + using namespace MCTruthPartClassifier; + if (m_opt.not_from_hadron && + type != ParticleType::IsoElectron) { + return false; + } - // -------------------------------------------------- - // Apply kinematic cut on the dressed eta: - // must be less than or equal to 2.5 - if ( std::abs( truthParticle.auxdata<float>( "eta_dressed" ) ) > m_opt.eta_max ){ return false; } + // If it is requested that tauons are hadrons, perform a check of the + // ancestry: It shall not contain a single tauon. + if (m_opt.tau_is_hadron) { + auto truthProxy = truthParticle.auxdata<ElementLink<xAOD::TruthParticleContainer> >("originalTruthParticle"); + if (not truthProxy.isValid()) { + throw std::runtime_error("ParticleLevelElectronObjectSelector::apply: " + "Could not obtain 'originalTruthParticle' reference."); + } + if (truth::isLeptonFromTau(*truthProxy)) { + return false; + } + } + // -------------------------------------------------- + // Apply kinematic cut on the dressed pT: + // must exceed 25 GeV + if (truthParticle.auxdata<float>("pt_dressed") < m_opt.pt_min) { + return false; + } - // -------------------------------------------------- - // Everything that reaches this point has passed the selection - return true; + // -------------------------------------------------- + // Apply kinematic cut on the dressed eta: + // must be less than or equal to 2.5 + if (std::abs(truthParticle.auxdata<float>("eta_dressed")) > m_opt.eta_max) { + return false; } + + // -------------------------------------------------- + // Everything that reaches this point has passed the selection + return true; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelEvent.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelEvent.cxx new file mode 100644 index 000000000000..62f9d7a2bb0e --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelEvent.cxx @@ -0,0 +1,94 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopParticleLevel/ParticleLevelEvent.h" + +std::ostream & operator << (std::ostream& os, const top::ParticleLevelEvent& plEvent) { + if (plEvent.m_electrons) { + os << "Number of electrons: " << plEvent.m_electrons->size() << "\n"; + for (const auto& elPtr : *plEvent.m_electrons) { + if (elPtr) { + os << " " << *elPtr << "\n"; + } + } + } else { + os << "ParticleLevelEvent: Cannot find electron truth collection. Did you set the truth collection correctly?\n"; + } + + if (plEvent.m_muons) { + os << "Number of muons: " << plEvent.m_muons->size() << "\n"; + for (const auto& muPtr : *plEvent.m_muons) { + if (muPtr) { + os << " " << *muPtr << "\n"; + } + } + } else { + os << "ParticleLevelEvent: Cannot find muon truth collection. Did you set the truth collection correctly?\n"; + } + + if (plEvent.m_softmuons) { + os << "Number of soft muons: " << plEvent.m_softmuons->size() << "\n"; + for (const auto& muPtr : *plEvent.m_softmuons) { + if (muPtr) { + os << " " << *muPtr << "\n"; + } + } + } else { + os << "ParticleLevelEvent: Cannot find muon truth collection. Did you set the truth collection correctly?\n"; + } + + if (plEvent.m_jets) { + os << "Number of jets: " << plEvent.m_jets->size() << "\n"; + for (const auto& jetPtr : *plEvent.m_jets) { + if (jetPtr) { + os << " " << *jetPtr << "\n"; + } + } + } else { + os << "ParticleLevelEvent: Cannot find jet truth collection. Did you set the truth collection correctly?\n"; + } + + if (plEvent.m_largeRJets) { + os << "Number of large R jets: " << plEvent.m_largeRJets->size() << "\n"; + for (const auto& largeRjetPtr : *plEvent.m_largeRJets) { + if (largeRjetPtr) { + os << " " << *largeRjetPtr << "\n"; + } + } + } else { + os << + "ParticleLevelEvent: Cannot find large R jets truth collection. Did you set the truth collection correctly?\n"; + } + + if (plEvent.m_taus) { + os << "Number of taus: " << plEvent.m_taus->size() << "\n"; + for (const auto& tauPtr : *plEvent.m_taus) { + if (tauPtr) { + os << " " << *tauPtr << "\n"; + } + } + } else { + os << "ParticleLevelEvent: Cannot find tau truth collection. Did you set the truth collection correctly?\n"; + } + + if (plEvent.m_photons) { + os << "Number of photons: " << plEvent.m_photons->size() << "\n"; + for (const auto& phPtr : *plEvent.m_photons) { + if (phPtr) { + os << " " << *phPtr << "\n"; + } + } + } else { + os << "ParticleLevelEvent: Cannot find photon truth collection. Did you set the truth collection correctly?\n"; + } + + if (plEvent.m_met) { + os << *plEvent.m_met; + } else { + os << + "ParticleLevelEvent: Cannot find MET (neutrino) truth collection. Did you set the truth collection correctly?\n"; + } + + return os; +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelJetObjectSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelJetObjectSelector.cxx index a01bbfd9dfb8..5c55332030b0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelJetObjectSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelJetObjectSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelJetObjectSelector.cxx // Description: @@ -10,25 +10,27 @@ #include "TopParticleLevel/ParticleLevelJetObjectSelector.h" namespace top { + ParticleLevelJetObjectSelector::ParticleLevelJetObjectSelector(Options opt /* = Options() */) + : m_opt(opt) { /* Deliberately Empty */} + + /* virtual */ bool + ParticleLevelJetObjectSelector::apply(const xAOD::Jet& jet) { + // -------------------------------------------------- + // Apply kinematic cut on the pT: + // must exceed 25 GeV + if (jet.pt() < m_opt.pt_min) { + return false; + } - ParticleLevelJetObjectSelector::ParticleLevelJetObjectSelector( Options opt /* = Options() */) - : m_opt( opt ){ /* Deliberately Empty */ } - - /* virtual */ bool - ParticleLevelJetObjectSelector::apply( const xAOD::Jet & jet ) { - // -------------------------------------------------- - // Apply kinematic cut on the pT: - // must exceed 25 GeV - if ( jet.pt() < m_opt.pt_min ){ return false; } - - // -------------------------------------------------- - // Apply kinematic cut on the eta: - // must be less than or equal to 2.5 - if ( std::abs( jet.eta() ) > m_opt.eta_max ){ return false; } - - // -------------------------------------------------- - // Everything that reaches this point has passed the selection - return true; + // -------------------------------------------------- + // Apply kinematic cut on the eta: + // must be less than or equal to 2.5 + if (std::abs(jet.eta()) > m_opt.eta_max) { + return false; } + // -------------------------------------------------- + // Everything that reaches this point has passed the selection + return true; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelLoader.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelLoader.cxx index 7b39d65f5dbf..066c08ec7354 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelLoader.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelLoader.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelLoader.cxx // Description: @@ -8,6 +8,7 @@ // Created: Sun Feb 22 13:24:02 2015 #include "TopParticleLevel/ParticleLevelLoader.h" +#include "TopParticleLevel/TruthTools.h" #include <list> #include <cassert> @@ -21,543 +22,834 @@ #include "TopParticleLevel/ParticleLevelMuonObjectSelector.h" #include "TopParticleLevel/ParticleLevelPhotonObjectSelector.h" #include "TopParticleLevel/ParticleLevelJetObjectSelector.h" +#include "TopParticleLevel/ParticleLevelTauObjectSelector.h" #include "TopConfiguration/TopConfig.h" +#include "FourMomUtils/xAODP4Helpers.h" + +#include <boost/algorithm/string.hpp> // #define TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL 1 namespace top { + ParticleLevelLoader::ParticleLevelLoader(const std::shared_ptr<top::TopConfig>& cfg) + : asg::AsgTool("ParticleLevelLoader"), + m_config(cfg), + // Don't create them here because construction is a bit long-ish + m_objectSelector_Electron(nullptr), + m_objectSelector_Muon(nullptr), + m_objectSelector_Photon(nullptr), + m_objectSelector_Jet(nullptr), + m_objectSelector_LargeRJet(nullptr), + m_objectSelector_Tau(nullptr), + // Tool is inactive on non-MC data and whenever particle level is not requested + m_active(m_config->doTopParticleLevel() && + m_config->isMC() && + (m_config->useTruthElectrons() || + m_config->useTruthMuons() || + m_config->useTruthPhotons() || + m_config->useTruthJets() || + m_config->useTruthLargeRJets() || + m_config->useTruthTaus() || + m_config->useTruthMET())) { + // Configure and create electron object selector + auto optEl = ParticleLevelElectronObjectSelector::Options { + m_config->truth_electron_PtCut(), + m_config->truth_electron_EtaCut(), + m_config->truth_electron_NotFromHadron(), + m_config->truth_electron_TauIsHadron() + }; + + m_objectSelector_Electron.reset(new ParticleLevelElectronObjectSelector(optEl)); + + // Configure and create muon object selector + auto optMu = ParticleLevelMuonObjectSelector::Options { + m_config->truth_muon_PtCut(), + m_config->truth_muon_EtaCut(), + m_config->truth_muon_NotFromHadron(), + m_config->truth_muon_TauIsHadron() + }; + + m_objectSelector_Muon.reset(new ParticleLevelMuonObjectSelector(optMu)); + + // Configure and create photon object selector + auto optPhoton = ParticleLevelPhotonObjectSelector::Options { + m_config->truth_photon_PtCut(), + m_config->truth_photon_EtaCut(), + m_config->truth_photon_Origin(), + m_config->truth_photon_Isolation() + }; + + m_objectSelector_Photon.reset(new ParticleLevelPhotonObjectSelector(optPhoton)); + + + // Configure and create jet object selector + auto optJet = ParticleLevelJetObjectSelector::Options { + m_config->truth_jet_PtCut(), + m_config->truth_jet_EtaCut() + }; + + m_objectSelector_Jet.reset(new ParticleLevelJetObjectSelector(optJet)); + + // Configure and create jet object selector + auto optLargeRJet = ParticleLevelJetObjectSelector::Options { + m_config->truth_jet_largeR_PtCut(), + m_config->truth_jet_largeR_EtaCut() + }; + + m_objectSelector_LargeRJet.reset(new ParticleLevelJetObjectSelector(optLargeRJet)); + + // Configure and create muon object selector + auto optTau = ParticleLevelTauObjectSelector::Options { + m_config->truth_tau_PtCut(), + m_config->truth_tau_EtaCut() + }; + + m_objectSelector_Tau.reset(new ParticleLevelTauObjectSelector(optTau)); + + + std::ostream &msgInfo = msg(MSG::Level::INFO); + if (m_active) { + msgInfo << "Particle level reconstruction is enabled; telling you how I am configured:" << '\n'; + msgInfo << " " << std::setw(20) << "UseElectrons? " << std::setw(5) << std::boolalpha << + m_config->useTruthElectrons(); + if (m_config->useTruthElectrons()) { + msgInfo << " [" << m_config->sgKeyTruthElectrons() << "]" << '\n' + << " --- Pt > " << m_config->truth_electron_PtCut() << '\n' + << " --- |eta| < " << m_config->truth_electron_EtaCut() << '\n' + << " --- notFromHadron? " << std::boolalpha << m_config->truth_electron_NotFromHadron() << '\n' + << " --- tauIsHadron? " << std::boolalpha << m_config->truth_electron_TauIsHadron() << '\n'; + } else { + msgInfo << '\n'; + } + msgInfo << " " << std::setw(20) << "UseMuons? " << std::setw(5) << std::boolalpha << + m_config->useTruthMuons(); + if (m_config->useTruthMuons()) { + msgInfo << " [" << m_config->sgKeyTruthMuons() << "]" << '\n' + << " --- Pt > " << m_config->truth_muon_PtCut() << '\n' + << " --- |eta| < " << m_config->truth_muon_EtaCut() << '\n' + << " --- notFromHadron? " << std::boolalpha << m_config->truth_muon_NotFromHadron() << '\n' + << " --- tauIsHadron? " << std::boolalpha << m_config->truth_muon_TauIsHadron() << '\n'; + } else { + msgInfo << '\n'; + } + msgInfo << " " << std::setw(20) << "UsePhotons? " << std::setw(5) << std::boolalpha << + m_config->useTruthPhotons(); + if (m_config->useTruthPhotons()) { + msgInfo << " [" << m_config->sgKeyTruthPhotons() << "]" << '\n' + << " --- Pt > " << m_config->truth_photon_PtCut() << '\n' + << " --- |eta| < " << m_config->truth_photon_EtaCut() << '\n' + << " --- Origin = " << m_config->truth_photon_Origin() << '\n' + << " --- Isolation = " << m_config->truth_photon_Isolation() << '\n'; + } else { + msgInfo << '\n'; + } + msgInfo << " " << std::setw(20) << "UseJets? " << std::setw(5) << std::boolalpha << m_config->useTruthJets(); + if (m_config->useTruthJets()) { + msgInfo << " [" << m_config->sgKeyTruthJets() << "]" << '\n' + << " --- Pt > " << m_config->truth_jet_PtCut() << '\n' + << " --- |eta| < " << m_config->truth_jet_EtaCut() << '\n'; + } else { + msgInfo << '\n'; + } + msgInfo << " " << std::setw(20) << "UseLargeRJets? " << std::setw(5) << std::boolalpha << + m_config->useTruthLargeRJets(); + if (m_config->useTruthJets()) { + msgInfo << " [" << m_config->sgKeyTruthLargeRJets() << "]" << '\n' + << " --- Pt > " << m_config->truth_jet_largeR_PtCut() << '\n' + << " --- |eta| < " << m_config->truth_jet_largeR_EtaCut() << '\n'; + } else { + msgInfo << '\n'; + } + msgInfo << " " << std::setw(20) << "UseTaus? " << std::setw(5) << std::boolalpha << m_config->useTruthTaus(); + if (m_config->useTruthTaus()) { + msgInfo << " [" << m_config->sgKeyTruthTaus() << "]" << '\n' + << " --- Pt > " << m_config->truth_tau_PtCut() << '\n' + << " --- |eta| < " << m_config->truth_tau_EtaCut() << '\n'; + } else { + msgInfo << '\n'; + } + msgInfo << " " << std::setw(20) << "UseMET? " << std::setw(5) << std::boolalpha << m_config->useTruthMET(); + if (m_config->useTruthMET()) { + msgInfo << " [" << m_config->sgKeyTruthMET() << "]" << '\n'; + } else { + msgInfo << '\n'; + } + msgInfo << " " << std::setw(20) << "DoOverlapRemoval Mu-Jet? " << std::setw(5) << std::boolalpha << + m_config->doParticleLevelOverlapRemovalMuJet() << '\n'; + msgInfo << " " << std::setw(20) << "DoOverlapRemoval El-Jet? " << std::setw(5) << std::boolalpha << + m_config->doParticleLevelOverlapRemovalElJet() << '\n'; + msgInfo << " " << std::setw(20) << "DoOverlapRemoval Jet-Photon? " << std::setw(5) << std::boolalpha << + m_config->doParticleLevelOverlapRemovalJetPhoton() << '\n'; + + + if (m_config->useRCJets()) { + m_particleLevelRCJetObjectLoader = std::unique_ptr<ParticleLevelRCJetObjectLoader> (new ParticleLevelRCJetObjectLoader( + m_config)); + top::check(m_particleLevelRCJetObjectLoader->initialize(), + "Failed to initialize ParticleLevelRCJetObjectLoader"); + } + + if (m_config->useVarRCJets() == true) { + boost::split(m_VarRCJetRho, m_config->VarRCJetRho(), boost::is_any_of(",")); + boost::split(m_VarRCJetMassScale, m_config->VarRCJetMassScale(), boost::is_any_of(",")); + + for (auto& rho : m_VarRCJetRho) { + for (auto& mass_scale : m_VarRCJetMassScale) { + std::replace(rho.begin(), rho.end(), '.', '_'); + std::string name = rho + mass_scale; + m_particleLevelVarRCJetObjectLoader[name] = std::unique_ptr<ParticleLevelRCJetObjectLoader> (new ParticleLevelRCJetObjectLoader( + m_config)); + top::check(m_particleLevelVarRCJetObjectLoader[name]->setProperty("VarRCjets", + true), + "Failed to set VarRCjets property of VarRCJetMC15"); + top::check(m_particleLevelVarRCJetObjectLoader[name]->setProperty("VarRCjets_rho", + rho), + "Failed to set VarRCjets rho property of VarRCJetMC15"); + top::check(m_particleLevelVarRCJetObjectLoader[name]->setProperty("VarRCjets_mass_scale", + mass_scale), + "Failed to set VarRCjets mass scale property of VarRCJetMC15"); + top::check(m_particleLevelVarRCJetObjectLoader[name]->initialize(), "Failed to initialize VarRCJetMC15"); + } // end loop over mass scale parameters (e.g., top mass, w mass, etc.) + } // end loop over mass scale multiplies (e.g., 1.,2.,etc.) + } + } else { + msgInfo << "Particle level reconstruction is disabled." << '\n'; + } + } - ParticleLevelLoader::ParticleLevelLoader( const std::shared_ptr<top::TopConfig> & cfg ) - : asg::AsgTool( "ParticleLevelLoader" ), - m_config( cfg ), - // Don't create them here because construction is a bit long-ish - m_objectSelector_Electron( nullptr ), - m_objectSelector_Muon( nullptr ), - m_objectSelector_Photon( nullptr ), - m_objectSelector_Jet( nullptr ), - m_objectSelector_LargeRJet( nullptr ), - // Tool is inactive on non-MC data and whenever particle level is not requested - m_active( m_config->doTopParticleLevel() && - m_config->isMC() && - ( m_config->useTruthElectrons() || - m_config->useTruthMuons() || - m_config->useTruthPhotons() || - m_config->useTruthJets() || - m_config->useTruthLargeRJets() || - m_config->useTruthMET() ) ) { - - // Configure and create electron object selector - auto optEl = ParticleLevelElectronObjectSelector::Options{ - m_config->truth_electron_PtCut(), - m_config->truth_electron_EtaCut(), - m_config->truth_electron_NotFromHadron(), - m_config->truth_electron_TauIsHadron() - }; - - m_objectSelector_Electron.reset( new ParticleLevelElectronObjectSelector( optEl ) ); - - // Configure and create muon object selector - auto optMu = ParticleLevelMuonObjectSelector::Options{ - m_config->truth_muon_PtCut(), - m_config->truth_muon_EtaCut(), - m_config->truth_muon_NotFromHadron(), - m_config->truth_muon_TauIsHadron() - }; - - m_objectSelector_Muon.reset( new ParticleLevelMuonObjectSelector( optMu ) ); - - // Configure and create photon object selector - auto optPhoton = ParticleLevelPhotonObjectSelector::Options{ - m_config->truth_photon_PtCut(), - m_config->truth_photon_EtaCut(), - m_config->truth_photon_Origin(), - m_config->truth_photon_Isolation() - }; - - m_objectSelector_Photon.reset( new ParticleLevelPhotonObjectSelector( optPhoton ) ); - - - // Configure and create jet object selector - auto optJet = ParticleLevelJetObjectSelector::Options{ - m_config->truth_jet_PtCut(), - m_config->truth_jet_EtaCut() - }; - - m_objectSelector_Jet.reset( new ParticleLevelJetObjectSelector( optJet ) ); - - // Configure and create jet object selector - auto optLargeRJet = ParticleLevelJetObjectSelector::Options{ - m_config->truth_jet_largeR_PtCut(), - m_config->truth_jet_largeR_EtaCut() - }; - - m_objectSelector_LargeRJet.reset( new ParticleLevelJetObjectSelector( optLargeRJet ) ); - - - if ( m_active ){ - std::cout << "Particle level reconstruction is enabled; telling you how I am configured:" << '\n'; - std::cout << " " << std::setw( 20 ) << "UseElectrons? " << std::setw( 5 ) << std::boolalpha << m_config->useTruthElectrons(); - if ( m_config->useTruthElectrons() ){ - std::cout << " [" << m_config->sgKeyTruthElectrons() << "]" << '\n' - << " --- Pt > " << m_config->truth_electron_PtCut() << '\n' - << " --- |eta| < " << m_config->truth_electron_EtaCut() << '\n' - << " --- notFromHadron? " << std::boolalpha << m_config->truth_electron_NotFromHadron() << '\n' - << " --- tauIsHadron? " << std::boolalpha << m_config->truth_electron_TauIsHadron() << '\n'; - } else { - std::cout << '\n'; - } - std::cout << " " << std::setw( 20 ) << "UseMuons? " << std::setw( 5 ) << std::boolalpha << m_config->useTruthMuons(); - if ( m_config->useTruthMuons() ){ - std::cout << " [" << m_config->sgKeyTruthMuons() << "]" << '\n' - << " --- Pt > " << m_config->truth_muon_PtCut() << '\n' - << " --- |eta| < " << m_config->truth_muon_EtaCut() << '\n' - << " --- notFromHadron? " << std::boolalpha << m_config->truth_muon_NotFromHadron() << '\n' - << " --- tauIsHadron? " << std::boolalpha << m_config->truth_muon_TauIsHadron() << '\n'; - } else { - std::cout << '\n'; - } - std::cout << " " << std::setw( 20 ) << "UsePhotons? " << std::setw( 5 ) << std::boolalpha << m_config->useTruthPhotons(); - if ( m_config->useTruthPhotons() ){ - std::cout << " [" << m_config->sgKeyTruthPhotons() << "]" << '\n' - << " --- Pt > " << m_config->truth_photon_PtCut() << '\n' - << " --- |eta| < " << m_config->truth_photon_EtaCut() << '\n' - << " --- Origin = " << m_config->truth_photon_Origin() << '\n' - << " --- Isolation = " << m_config->truth_photon_Isolation() << '\n'; - } else { - std::cout << '\n'; - } - std::cout << " " << std::setw( 20 ) << "UseJets? " << std::setw( 5 ) << std::boolalpha << m_config->useTruthJets(); - if ( m_config->useTruthJets() ){ - std::cout << " [" << m_config->sgKeyTruthJets() << "]" << '\n' - << " --- Pt > " << m_config->truth_jet_PtCut() << '\n' - << " --- |eta| < " << m_config->truth_jet_EtaCut() << '\n'; - } else { - std::cout << '\n'; - } - std::cout << " " << std::setw( 20 ) << "UseLargeRJets? " << std::setw( 5 ) << std::boolalpha << m_config->useTruthLargeRJets(); - if ( m_config->useTruthJets() ){ - std::cout << " [" << m_config->sgKeyTruthLargeRJets() << "]" << '\n' - << " --- Pt > " << m_config->truth_jet_largeR_PtCut() << '\n' - << " --- |eta| < " << m_config->truth_jet_largeR_EtaCut() << '\n'; - } else { - std::cout << '\n'; - } - std::cout << " " << std::setw( 20 ) << "UseMET? " << std::setw( 5 ) << std::boolalpha << m_config->useTruthMET(); - if ( m_config->useTruthMET() ){ - std::cout << " [" << m_config->sgKeyTruthMET() << "]" << '\n'; - } else { - std::cout << '\n'; - } - std::cout << " " << std::setw( 20 ) << "DoOverlapRemoval Mu-Jet? " << std::setw( 5 ) << std::boolalpha << m_config->doParticleLevelOverlapRemovalMuJet() << '\n'; - std::cout << " " << std::setw( 20 ) << "DoOverlapRemoval El-Jet? " << std::setw( 5 ) << std::boolalpha << m_config->doParticleLevelOverlapRemovalElJet() << '\n'; - std::cout << " " << std::setw( 20 ) << "DoOverlapRemoval Jet-Photon? " << std::setw( 5 ) << std::boolalpha << m_config->doParticleLevelOverlapRemovalJetPhoton() << '\n'; + ParticleLevelLoader::~ParticleLevelLoader() { /* Deliberately Empty */} - } else { - std::cout << "Particle level reconstruction is disabled." << '\n'; - } + ParticleLevelEvent ParticleLevelLoader::load() { + // If the ParticleLevelLoader is not active, return an empty object + if (!m_active) { + return {}; } - ParticleLevelLoader::~ParticleLevelLoader(){ /* Deliberately Empty */ } + // Create the result object. + ParticleLevelEvent plEvent; + + // Load event info object directly into the plEvent + top::check(evtStore()->retrieve(plEvent.m_info, m_config->sgKeyEventInfo()), + "xAOD::TEvent::retrieve failed for EventInfo"); + + // Load the info for electrons, muons, jets, and MET into local objects: + // They need to be selected / modified / etc + const xAOD::TruthParticleContainer* electrons { + nullptr + }; + const xAOD::TruthParticleContainer* muons { + nullptr + }; + const xAOD::TruthParticleContainer* photons { + nullptr + }; + const xAOD::JetContainer* jets { + nullptr + }; + const xAOD::JetContainer* largeRJets { + nullptr + }; + const xAOD::TruthParticleContainer* taus { + nullptr + }; + const xAOD::MissingETContainer* mets { + nullptr + }; + + if (m_config->useTruthElectrons()) { + top::check(evtStore()->retrieve(electrons, m_config->sgKeyTruthElectrons()), + "xAOD::TEvent::retrieve failed for Truth Electrons"); + } - ParticleLevelEvent ParticleLevelLoader::load() { + if (m_config->useTruthMuons()) { + top::check(evtStore()->retrieve(muons, m_config->sgKeyTruthMuons()), + "xAOD::TEvent::retrieve failed for Truth Muons"); + } - // If the ParticleLevelLoader is not active, return an empty object - if ( ! m_active ){ return {}; } + if (m_config->useTruthPhotons()) { + top::check(evtStore()->retrieve(photons, m_config->sgKeyTruthPhotons()), + "xAOD::TEvent::retrieve failed for Truth Photons"); + } - // Create the result object. - ParticleLevelEvent plEvent; + if (m_config->useTruthJets()) { + top::check(evtStore()->retrieve(jets, m_config->sgKeyTruthJets()), + "xAOD::TEvent::retrieve failed for Truth Jets"); + } - // Load event info object directly into the plEvent - top::check( evtStore()->retrieve( plEvent.m_info, m_config->sgKeyEventInfo() ), - "xAOD::TEvent::retrieve failed for EventInfo" ); + if (m_config->useTruthLargeRJets()) { + top::check(evtStore()->retrieve(largeRJets, m_config->sgKeyTruthLargeRJets()), + "xAOD::TEvent::retrieve failed for Truth Jets Large R"); + } - // Load the info for electrons, muons, jets, and MET into local objects: - // They need to be selected / modified / etc - const xAOD::TruthParticleContainer * electrons{ nullptr }; - const xAOD::TruthParticleContainer * muons{ nullptr }; - const xAOD::TruthParticleContainer * photons{ nullptr }; - const xAOD::JetContainer * jets{ nullptr }; - const xAOD::JetContainer * largeRJets{ nullptr }; - const xAOD::MissingETContainer * mets{ nullptr }; + if (m_config->useTruthTaus()) { + top::check(evtStore()->retrieve(taus, m_config->sgKeyTruthTaus()), + "xAOD::TEvent::retrieve failed for Truth Taus"); + } - if ( m_config->useTruthElectrons() ){ - top::check( evtStore()->retrieve( electrons, m_config->sgKeyTruthElectrons() ), - "xAOD::TEvent::retrieve failed for Truth Electrons" ); - } + if (m_config->useTruthMET()) { + top::check(evtStore()->retrieve(mets, m_config->sgKeyTruthMET()), + "xAOD::TEvent::retrieve failed for Truth Missing ET"); + } - if ( m_config->useTruthMuons() ){ - top::check( evtStore()->retrieve( muons, m_config->sgKeyTruthMuons() ), - "xAOD::TEvent::retrieve failed for Truth Muons" ); - } + // ====================================================================== + // DRESSING + // We want to put the dressed leptons into the Event container, however, + // after reading from the TOPQ file, their dressed kinematics are stored + // as decorations. Lets (1) create a shallow copied container now, (2) + // set the kinematics for the shallow copies to the dressed values, (3) + // create decorations for the bare (non-dressed) kinematics, and (4) + // deep-copy the selection electrons from that container later. + + // ELECTRONS + if (m_config->useTruthElectrons()) { + top::check(loadDressedLeptons(*electrons, + m_electronsDressed, + m_electronsDressedAux), + "Failure to load dressed electrons."); + } - if ( m_config->useTruthPhotons() ){ - top::check( evtStore()->retrieve( photons, m_config->sgKeyTruthPhotons() ), - "xAOD::TEvent::retrieve failed for Truth Photons" ); - } + // MUONS + if (m_config->useTruthMuons()) { + top::check(loadDressedLeptons(*muons, + m_muonsDressed, + m_muonsDressedAux), + "Failure to load dressed muons."); + } - if ( m_config->useTruthJets() ){ - top::check( evtStore()->retrieve( jets, m_config->sgKeyTruthJets() ), - "xAOD::TEvent::retrieve failed for Truth Jets" ); + // ====================================================================== + // OBJECT SELECTION + // This yields index collections, one for each + // { electrons, muons, photons, jets, largeRJets }. + std::list<std::size_t> idx_electrons; // -> relative to `electrons` + std::list<std::size_t> idx_muons; // -> relative to `muons` + std::list<std::size_t> idx_photons; // -> relative to `photons` + std::list<std::size_t> idx_jets; // -> relative to `jets` + std::list<std::size_t> idx_largeRJets; // -> relative to `largeRJets` + std::list<std::size_t> idx_taus; // -> relative to `taus` + + // Electrons + if (m_config->useTruthElectrons()) { + for (std::size_t i = 0; i < electrons->size(); ++i) { + const auto* electron = electrons->at(i); + + // Allow use of mixed-particle input container. + if (electron->absPdgId() != 11) { + continue; } - if ( m_config->useTruthLargeRJets() ){ - top::check( evtStore()->retrieve( largeRJets, m_config->sgKeyTruthLargeRJets() ), - "xAOD::TEvent::retrieve failed for Truth Jets Large R" ); + // FIXME: Is this still needed? + if (electron->barcode() >= 2e5) { + continue; } - if ( m_config->useTruthMET() ){ - top::check( evtStore()->retrieve( mets, m_config->sgKeyTruthMET() ), - "xAOD::TEvent::retrieve failed for Truth Missing ET" ); + if (m_objectSelector_Electron->apply(*electron)) { + idx_electrons.push_back(i); } + } + } - // ====================================================================== - // DRESSING - // We want to put the dressed leptons into the Event container, however, - // after reading from the TOPQ file, their dressed kinematics are stored - // as decorations. Lets (1) create a shallow copied container now, (2) - // set the kinematics for the shallow copies to the dressed values, (3) - // create decorations for the bare (non-dressed) kinematics, and (4) - // deep-copy the selection electrons from that container later. - - // ELECTRONS - if ( m_config->useTruthElectrons() ) { - top::check(loadDressedLeptons(* electrons, - m_electronsDressed, - m_electronsDressedAux), - "Failure to load dressed electrons."); + // Muons + if (m_config->useTruthMuons()) { + for (std::size_t i = 0; i < muons->size(); ++i) { + const auto* muon = muons->at(i); + + // Allow use of mixed-particle input container. + if (muon->absPdgId() != 13) { + continue; } - // MUONS - if ( m_config->useTruthMuons() ){ - top::check(loadDressedLeptons(* muons, - m_muonsDressed, - m_muonsDressedAux), - "Failure to load dressed muons."); + // FIXME: Is this still needed? + if (muon->barcode() >= 2e5) { + continue; } - // ====================================================================== - // OBJECT SELECTION - // This yields index collections, one for each - // { electrons, muons, photons, jets, largeRJets }. - std::list<std::size_t> idx_electrons; // -> relative to `electrons` - std::list<std::size_t> idx_muons; // -> relative to `muons` - std::list<std::size_t> idx_photons; // -> relative to `photons` - std::list<std::size_t> idx_jets; // -> relative to `jets` - std::list<std::size_t> idx_largeRJets; // -> relative to `largeRJets` - - // Electrons - if ( m_config->useTruthElectrons() ) { - for ( std::size_t i = 0; i < electrons->size(); ++i ){ - const auto * electron = electrons->at(i); - - // Allow use of mixed-particle input container. - if ( electron->absPdgId() != 11 ){ continue; } - - // FIXME: Is this still needed? - if ( electron->barcode() >= 2e5 ){ continue; } - - if ( m_objectSelector_Electron->apply(* electron) ){ - idx_electrons.push_back( i ); - } - } + if (m_objectSelector_Muon->apply(*muon)) { + idx_muons.push_back(i); } + } + } - // Muons - if ( m_config->useTruthMuons() ){ - for ( std::size_t i = 0; i < muons->size(); ++i ){ - const auto * muon = muons->at(i); + // Photons + if (m_config->useTruthPhotons()) { + for (std::size_t i = 0; i < photons->size(); ++i) { + const auto* photon = photons->at(i); - // Allow use of mixed-particle input container. - if ( muon->absPdgId() != 13 ){ continue; } + // Allow use of mixed-particle input container. + if (photon->absPdgId() != 22) { + continue; + } - // FIXME: Is this still needed? - if ( muon->barcode() >= 2e5 ){ continue; } + // FIXME: Is this still needed? + if (photon->barcode() >= 2e5) { + continue; + } - if ( m_objectSelector_Muon->apply(* muon) ){ - idx_muons.push_back( i ); - } - } + if (not m_objectSelector_Photon->apply(*photon)) { + continue; } - // Photons - if ( m_config->useTruthPhotons() ){ - for ( std::size_t i = 0; i < photons->size(); ++i ){ - const auto * photon = photons->at(i); - - // Allow use of mixed-particle input container. - if ( photon->absPdgId() != 22 ){ continue; } - - // FIXME: Is this still needed? - if ( photon->barcode() >= 2e5 ){ continue; } - - if ( not m_objectSelector_Photon->apply(* photon) ){ - continue; - } - - // Reject photons used for electron dressing. - if (m_config->useTruthElectrons()){ - if (isDressingPhoton(* photon, * electrons)){ - continue; - } - } - - // Reject photons used for muon dressing. - if (m_config->useTruthMuons()){ - if (isDressingPhoton(* photon, * muons)){ - continue; - } - } - idx_photons.push_back( i ); - } + // Reject photons used for electron dressing. + if (m_config->useTruthElectrons()) { + if (isDressingPhoton(*photon, *electrons)) { + continue; + } } - // Jets - if ( m_config->useTruthJets() ){ - for ( std::size_t i = 0; i < jets->size(); ++i ){ - if ( m_objectSelector_Jet->apply( * jets->at( i ) ) ){ - idx_jets.push_back( i ); - } - } + // Reject photons used for muon dressing. + if (m_config->useTruthMuons()) { + if (isDressingPhoton(*photon, *muons)) { + continue; + } } + idx_photons.push_back(i); + } + } - // Large-R-Jets - if ( m_config->useTruthLargeRJets() ){ - for ( std::size_t i = 0; i < largeRJets->size(); ++i ){ - if ( m_objectSelector_LargeRJet->apply( * largeRJets->at( i ) ) ){ - idx_largeRJets.push_back( i ); - } - } + // Jets + if (m_config->useTruthJets()) { + for (std::size_t i = 0; i < jets->size(); ++i) { + if (m_objectSelector_Jet->apply(*jets->at(i))) { + idx_jets.push_back(i); } + } + } - // ====================================================================== - // OVERLAP REMOVAL - // Removal Steps: - // 1. Jets & Muons: - // Remove Muons with dR < 0.4 - // 2. Jets & Electrons: - // Remove Electrons with dR < 0.4 - // 3. Photons & Jets: - // Remove Jets with dR < 0.4 + // Large-R-Jets + if (m_config->useTruthLargeRJets()) { + for (std::size_t i = 0; i < largeRJets->size(); ++i) { + if (m_objectSelector_LargeRJet->apply(*largeRJets->at(i))) { + idx_largeRJets.push_back(i); + } + } + } - // Jets and Muons: Remove Muon with dR < 0.4 - if ( m_config->useTruthMuons() && m_config->useTruthJets() && m_config->doParticleLevelOverlapRemovalMuJet() ) { + // Taus + if (m_config->useTruthTaus()) { + for (std::size_t i = 0; i < taus->size(); ++i) { + if (m_objectSelector_Tau->apply(*taus->at(i))) { + idx_taus.push_back(i); + } + } + } + // ====================================================================== + // OVERLAP REMOVAL + // Removal Steps: + // 1. Jets & Muons: + // Remove Muons with dR < 0.4 + // 2. Jets & Electrons: + // Remove Electrons with dR < 0.4 + // 3. Photons & Jets: + // Remove Jets with dR < 0.4 + + // Jets and Muons: Remove Muon with dR < 0.4 + if (m_config->useTruthMuons() && m_config->useTruthJets() && m_config->doParticleLevelOverlapRemovalMuJet()) { #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL - const std::size_t nMuonsPreOR{idx_muons.size()}; + const std::size_t nMuonsPreOR { + idx_muons.size() + }; #endif - idx_muons.remove_if([& idx_jets, & jets, this](std::size_t m){ - for( auto j : idx_jets ){ - if ( jets->at( j )->p4().DeltaR( m_muonsDressed->at( m )->p4() ) < 0.4 ){ - return true; - } - } - return false; - }); + idx_muons.remove_if([&idx_jets, &jets, this](std::size_t m) { + for (auto j : idx_jets) { + if (jets->at(j)->p4().DeltaR(m_muonsDressed->at(m)->p4()) < 0.4) { + return true; + } + } + return false; + }); #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL - std::cout << "[top::ParticleLevelLoader] Muon-In-Jet OR: " - << nMuonsPreOR << " -> " << idx_muons.size() << std::endl; + ATH_MSG_INFO("[top::ParticleLevelLoader] Muon-In-Jet OR: " + << nMuonsPreOR << " -> " << idx_muons.size()); #endif - } - - // Jets and Electrons: Remove Electron with dR < 0.4 - if ( m_config->useTruthElectrons() && m_config->useTruthJets() && m_config->doParticleLevelOverlapRemovalElJet() ) { + } + // Jets and Electrons: Remove Electron with dR < 0.4 + if (m_config->useTruthElectrons() && m_config->useTruthJets() && m_config->doParticleLevelOverlapRemovalElJet()) { #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL - const std::size_t nElectronsPreOR{idx_electrons.size()}; + const std::size_t nElectronsPreOR { + idx_electrons.size() + }; #endif - idx_electrons.remove_if([& idx_jets, & jets, this](std::size_t e){ - for( auto j : idx_jets ){ - if ( jets->at( j )->p4().DeltaR( m_electronsDressed->at( e )->p4() ) < 0.4 ){ - return true; - } - } - return false; - }); + idx_electrons.remove_if([&idx_jets, &jets, this](std::size_t e) { + for (auto j : idx_jets) { + if (jets->at(j)->p4().DeltaR(m_electronsDressed->at(e)->p4()) < 0.4) { + return true; + } + } + return false; + }); #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL - std::cout << "[top::ParticleLevelLoader] Electron-In-Jet OR: " - << nElectronsPreOR << " -> " << idx_electrons.size() << std::endl; + ATH_MSG_INFO("[top::ParticleLevelLoader] Electron-In-Jet OR: " + << nElectronsPreOR << " -> " << idx_electrons.size()); #endif - } - - // Photons and Jets: Remove Jet with dR < 0.4 - if ( m_config->useTruthPhotons() && m_config->useTruthJets() && m_config->doParticleLevelOverlapRemovalJetPhoton() ) { + } + // Photons and Jets: Remove Jet with dR < 0.4 + if (m_config->useTruthPhotons() && m_config->useTruthJets() && m_config->doParticleLevelOverlapRemovalJetPhoton()) { #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL - const std::size_t nJetPreOR{idx_jets.size()}; + const std::size_t nJetPreOR { + idx_jets.size() + }; #endif - idx_jets.remove_if([& idx_photons, & photons, & jets](std::size_t j){ - for( auto ph : idx_photons ){ - if ( photons->at( ph )->p4().DeltaR( jets->at( j )->p4() ) < 0.4 ){ - return true; - } - } - return false; - }); + idx_jets.remove_if([&idx_photons, &photons, &jets](std::size_t j) { + for (auto ph : idx_photons) { + if (photons->at(ph)->p4().DeltaR(jets->at(j)->p4()) < 0.4) { + return true; + } + } + return false; + }); #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL - std::cout << "[top::ParticleLevelLoader] Jet-In-Photon OR: " - << nJetsPreOR << " -> " << idx_jets.size() << std::endl; + ATH_MSG_INFO("[top::ParticleLevelLoader] Jet-In-Photon OR: " + << nJetsPreOR << " -> " << idx_jets.size()); #endif - } + } - // ====================================================================== - // WRITE TO LOADER - // 1. Loop index lists for electrons / muons / photons / jets - // 2. Create a deep copy of the item and insert it into the - // appropriate container - // 3. Create a shallow copy of the containers and apply corrections - // if needed (dressing, etc.) - - // Create New Containers holding the "Good" Electrons / Muons / Jets - // and the MET - if ( m_config->useTruthElectrons() ) { - xAOD::TruthParticleContainer * goodElectrons = new xAOD::TruthParticleContainer(); - xAOD::TruthParticleAuxContainer * goodElectronsAux = new xAOD::TruthParticleAuxContainer(); - goodElectrons->setStore( goodElectronsAux ); //< Connect the two - - m_goodElectrons.reset( goodElectrons ); - m_goodElectronsAux.reset( goodElectronsAux ); - - for ( auto e : idx_electrons ){ - const auto & elPtr = m_electronsDressed->at( e ); - xAOD::TruthParticle * electron = new xAOD::TruthParticle(); - electron->makePrivateStore( * elPtr ); - m_goodElectrons->push_back( electron ); - } - } + // ====================================================================== + // WRITE TO LOADER + // 1. Loop index lists for electrons / muons / photons / jets + // 2. Create a deep copy of the item and insert it into the + // appropriate container + // 3. Create a shallow copy of the containers and apply corrections + // if needed (dressing, etc.) + + // Create New Containers holding the "Good" Electrons / Muons / Jets + // and the MET + if (m_config->useTruthElectrons()) { + xAOD::TruthParticleContainer* goodElectrons = new xAOD::TruthParticleContainer(); + xAOD::TruthParticleAuxContainer* goodElectronsAux = new xAOD::TruthParticleAuxContainer(); + goodElectrons->setStore(goodElectronsAux); //< Connect the two + + m_goodElectrons.reset(goodElectrons); + m_goodElectronsAux.reset(goodElectronsAux); + + for (auto e : idx_electrons) { + const auto& elPtr = m_electronsDressed->at(e); + xAOD::TruthParticle* electron = new xAOD::TruthParticle(); + electron->makePrivateStore(*elPtr); + m_goodElectrons->push_back(electron); + } + + // sort electrons based on dressed pT -- otherwise they remain sorted according to bare pT + std::sort(m_goodElectrons->begin(), m_goodElectrons->end(), top::descendingPtSorter); + } - if ( m_config->useTruthMuons() ){ - xAOD::TruthParticleContainer * goodMuons = new xAOD::TruthParticleContainer(); - xAOD::TruthParticleAuxContainer * goodMuonsAux = new xAOD::TruthParticleAuxContainer(); - goodMuons->setStore( goodMuonsAux ); //< Connect the two + if (m_config->useTruthMuons()) { + xAOD::TruthParticleContainer* goodMuons = new xAOD::TruthParticleContainer(); + xAOD::TruthParticleAuxContainer* goodMuonsAux = new xAOD::TruthParticleAuxContainer(); + goodMuons->setStore(goodMuonsAux); //< Connect the two - m_goodMuons.reset( goodMuons ); - m_goodMuonsAux.reset( goodMuonsAux ); + m_goodMuons.reset(goodMuons); + m_goodMuonsAux.reset(goodMuonsAux); - for ( auto m : idx_muons ){ - const auto & muPtr = m_muonsDressed->at( m ); - xAOD::TruthParticle * muon = new xAOD::TruthParticle(); - muon->makePrivateStore( * muPtr ); - m_goodMuons->push_back( muon ); - } - } + for (auto m : idx_muons) { + const auto& muPtr = m_muonsDressed->at(m); + xAOD::TruthParticle* muon = new xAOD::TruthParticle(); + muon->makePrivateStore(*muPtr); + m_goodMuons->push_back(muon); + } - if ( m_config->useTruthPhotons() ){ - xAOD::TruthParticleContainer * goodPhotons = new xAOD::TruthParticleContainer(); - xAOD::TruthParticleAuxContainer * goodPhotonsAux = new xAOD::TruthParticleAuxContainer(); - goodPhotons->setStore( goodPhotonsAux ); //< Connect the two + // sort muons based on dressed pT -- otherwise they remain sorted according to bare pT + std::sort(m_goodMuons->begin(), m_goodMuons->end(), top::descendingPtSorter); + } - m_goodPhotons.reset( goodPhotons ); - m_goodPhotonsAux.reset( goodPhotonsAux ); + if (m_config->useTruthPhotons()) { + xAOD::TruthParticleContainer* goodPhotons = new xAOD::TruthParticleContainer(); + xAOD::TruthParticleAuxContainer* goodPhotonsAux = new xAOD::TruthParticleAuxContainer(); + goodPhotons->setStore(goodPhotonsAux); //< Connect the two - for ( auto ph : idx_photons ){ - const auto & phPtr = photons->at( ph ); - xAOD::TruthParticle * photon = new xAOD::TruthParticle(); - photon->makePrivateStore( * phPtr ); - m_goodPhotons->push_back( photon ); - } - } + m_goodPhotons.reset(goodPhotons); + m_goodPhotonsAux.reset(goodPhotonsAux); - if ( m_config->useTruthJets() ){ - xAOD::JetContainer * goodJets = new xAOD::JetContainer(); - xAOD::JetAuxContainer * goodJetsAux = new xAOD::JetAuxContainer(); - goodJets->setStore( goodJetsAux ); //< Connect the two + for (auto ph : idx_photons) { + const auto& phPtr = photons->at(ph); + xAOD::TruthParticle* photon = new xAOD::TruthParticle(); + photon->makePrivateStore(*phPtr); + m_goodPhotons->push_back(photon); + } + } - m_goodJets.reset( goodJets ); - m_goodJetsAux.reset( goodJetsAux ); + if (m_config->useTruthJets()) { + xAOD::JetContainer* goodJets = new xAOD::JetContainer(); + xAOD::JetAuxContainer* goodJetsAux = new xAOD::JetAuxContainer(); + goodJets->setStore(goodJetsAux); //< Connect the two - for ( auto j : idx_jets ){ - const auto & jetPtr = jets->at( j ); - xAOD::Jet * jet = new xAOD::Jet(); - jet->makePrivateStore( * jetPtr ); - m_goodJets->push_back( jet ); - } - } + m_goodJets.reset(goodJets); + m_goodJetsAux.reset(goodJetsAux); - if ( m_config->useTruthLargeRJets() ){ - xAOD::JetContainer * goodLargeRJets = new xAOD::JetContainer(); - xAOD::JetAuxContainer * goodLargeRJetsAux = new xAOD::JetAuxContainer(); - goodLargeRJets->setStore( goodLargeRJetsAux ); //< Connect the two + for (auto j : idx_jets) { + const auto& jetPtr = jets->at(j); + xAOD::Jet* jet = new xAOD::Jet(); + jet->makePrivateStore(*jetPtr); + m_goodJets->push_back(jet); + } + } - m_goodLargeRJets.reset( goodLargeRJets ); - m_goodLargeRJetsAux.reset( goodLargeRJetsAux ); + if (m_config->useTruthLargeRJets()) { + xAOD::JetContainer* goodLargeRJets = new xAOD::JetContainer(); + xAOD::JetAuxContainer* goodLargeRJetsAux = new xAOD::JetAuxContainer(); + goodLargeRJets->setStore(goodLargeRJetsAux); //< Connect the two - for ( auto j : idx_largeRJets ){ - const auto & jetPtr = largeRJets->at( j ); - xAOD::Jet * jet = new xAOD::Jet(); - jet->makePrivateStore( * jetPtr ); - m_goodLargeRJets->push_back( jet ); - } - } + m_goodLargeRJets.reset(goodLargeRJets); + m_goodLargeRJetsAux.reset(goodLargeRJetsAux); - // ====================================================================== - // INSERTION INTO STORAGE - // Put everything into storage, i.e. into the ParticleLevel.event object - plEvent.m_electrons = m_config->useTruthElectrons() ? m_goodElectrons.get() : nullptr; - plEvent.m_muons = m_config->useTruthMuons() ? m_goodMuons.get() : nullptr; - plEvent.m_photons = m_config->useTruthPhotons() ? m_goodPhotons.get() : nullptr; - plEvent.m_jets = m_config->useTruthJets() ? m_goodJets.get() : nullptr; - plEvent.m_largeRJets = m_config->useTruthLargeRJets() ? m_goodLargeRJets.get() : nullptr; - plEvent.m_met = m_config->useTruthMET() ? (* mets)[ "NonInt" ] : nullptr; - - return plEvent; + for (auto j : idx_largeRJets) { + const auto& jetPtr = largeRJets->at(j); + xAOD::Jet* jet = new xAOD::Jet(); + jet->makePrivateStore(*jetPtr); + m_goodLargeRJets->push_back(jet); + } } - bool ParticleLevelLoader::loadDressedLeptons(const xAOD::TruthParticleContainer & input, - std::unique_ptr<xAOD::TruthParticleContainer> & store, - std::unique_ptr<xAOD::ShallowAuxContainer> & storeAux) const { - auto dressed = xAOD::shallowCopyContainer(input); - store.reset(dressed.first); - storeAux.reset(dressed.second); - - for (auto pl : * store.get()){ - TLorentzVector fvDressed; - fvDressed.SetPtEtaPhiE(pl->auxdata<float>("pt_dressed"), - pl->auxdata<float>("eta_dressed"), - pl->auxdata<float>("phi_dressed"), - pl->auxdata<float>("e_dressed")); - - // Store original kinematics as decoration - // m->auxdata<int>( "nPhotons_dressed" ) = m->auxdata<int>( "nPhotons_dressed" ); - - pl->auxdata<float>( "pt_bare" ) = pl->pt(); - pl->auxdata<float>( "eta_bare" ) = pl->eta(); - pl->auxdata<float>( "phi_bare" ) = pl->phi(); - pl->auxdata<float>( "e_bare" ) = pl->e(); - - pl->setPx( fvDressed.Px() ); - pl->setPy( fvDressed.Py() ); - pl->setPz( fvDressed.Pz() ); - pl->setE( fvDressed.E() ); + if (m_config->useTruthTaus()) { + xAOD::TruthParticleContainer* goodTaus = new xAOD::TruthParticleContainer(); + xAOD::TruthParticleAuxContainer* goodTausAux = new xAOD::TruthParticleAuxContainer(); + goodTaus->setStore(goodTausAux); //< Connect the two + + m_goodTaus.reset(goodTaus); + m_goodTausAux.reset(goodTausAux); + + for (auto t : idx_taus) { + const auto& tauPtr = taus->at(t); + xAOD::TruthParticle* tau = new xAOD::TruthParticle(); + tau->makePrivateStore(*tauPtr); + m_goodTaus->push_back(tau); + } + } + + if (m_config->useTruthMuons() && m_config->useSoftMuons() ) { + xAOD::TruthParticleContainer* goodSoftMuons = new xAOD::TruthParticleContainer(); + xAOD::TruthParticleAuxContainer* goodSoftMuonsAux = new xAOD::TruthParticleAuxContainer(); + goodSoftMuons->setStore(goodSoftMuonsAux); //< Connect the two + + m_goodSoftMuons.reset(goodSoftMuons); + m_goodSoftMuonsAux.reset(goodSoftMuonsAux); + + //if we want the soft muon truth history, the parent navigation for the TruthMuons collection is unfortunately working only in DAOD_PHYS, in other derivations + //we need a workaround, i.e. we need to use the muon from the TruthParticles container instead of the one from the TruthMuon container + std::vector<const xAOD::TruthParticle*> truth_particles_vec; //this is an helper vector to speed up looking for the right muon... + const xAOD::TruthParticleContainer* truth_particles = nullptr; + if (m_config->useTruthParticles() && m_config->softmuonAdditionalTruthInfo()) { + top::check(evtStore()->retrieve(truth_particles, m_config->sgKeyMCParticle()), + "xAOD::TEvent::retrieve failed for Truth Particles"); + if(truth_particles) + { + for(const xAOD::TruthParticle* p : *truth_particles) + { + if(p->isMuon() && p->status()==1) truth_particles_vec.push_back(p); + } + } + } + + for (std::size_t i = 0; i < muons->size(); ++i) { //note we don't use dressed muons in this case + if(std::find(idx_muons.begin(), idx_muons.end(), i)!=idx_muons.end()) continue; //we don't want to store muons both as standard muons and as soft muons + const auto& muPtr = muons->at(i); + + //here we apply the selection for soft muons + if(muPtr->absPdgId()!=13) continue; + if(muPtr->pt()<m_config->truth_softmuon_PtCut()) continue; + if(fabs(muPtr->eta())>m_config->truth_softmuon_EtaCut()) continue; + //now the association with the jets + + if(m_config->useTruthJets()) + { + bool isInJet=false; + for(xAOD::Jet* jetPtr : *m_goodJets) + { + float dR = xAOD::P4Helpers::deltaR(*muPtr,*jetPtr,m_config->softmuonDRJetcutUseRapidity()); + if(dR<m_config->softmuonDRJetcut()) + { + isInJet=true; + break; + } + } + if(!isInJet) continue; } + //end of selection + + if(m_config->softmuonAdditionalTruthInfo() && (!muPtr->isAvailable<bool>("hasTruthMuonHistoryInfo") || !muPtr->auxdecor<bool>("hasTruthMuonHistoryInfo"))) //if "hasTruthMuonPartonHistoryInfo" exists and is true, we already filled these info for this muon (since muon history filling can be done in several parts of the code for good reasons) + { + bool doPartonHistory=m_config->softmuonAdditionalTruthInfoCheckPartonOrigin(); + top::truth::initTruthMuonHistoryInfo(muPtr,doPartonHistory); + + //in DAOD_PHYS we can just navigate directly from the muon from TruthMuons + if (m_config->getDerivationStream() == "PHYS") + { + top::truth::getTruthMuonHistory(muPtr,doPartonHistory,m_config->getShoweringAlgorithm(),m_config->softmuonAdditionalTruthInfoDoVerbose()); + } + else //apparently in older derivation formats we have to navigate using the muon from the TruthParticles container, this is annoying + { + //first we find the associated truth muon from truth_particles + const xAOD::TruthParticle* assMuon = 0; + for(const xAOD::TruthParticle* p : truth_particles_vec) + { + if(!p) continue; + if(p->barcode() == muPtr->barcode()) + { + assMuon = p; + break; + } + } + if(assMuon) //then we use it + { + //if we don't have the info correctly filled already, let's initialize it to default values + if(!assMuon->isAvailable<bool>("hasTruthMuonHistoryInfo") || ! assMuon->auxdecor<bool>("hasTruthMuonHistoryInfo")) top::truth::initTruthMuonHistoryInfo(assMuon,doPartonHistory); + //we have to use the associated muon from the TruthParticles container in this case + top::truth::getTruthMuonHistory(assMuon,doPartonHistory,m_config->getShoweringAlgorithm(),m_config->softmuonAdditionalTruthInfoDoVerbose()); + //then we copy the info to our muon + top::truth::copyTruthMuonHistoryInfo(assMuon,muPtr); + + } + } + }//end of additional soft muon filling + + xAOD::TruthParticle* muon = new xAOD::TruthParticle(); + muon->makePrivateStore(*muPtr); + + m_goodSoftMuons->push_back(muon); + + } + + // sort muons based on dressed pT -- otherwise they remain sorted according to bare pT + std::sort(m_goodSoftMuons->begin(), m_goodSoftMuons->end(), top::descendingPtSorter); + } - return true; + + // ====================================================================== + // INSERTION INTO STORAGE + // Put everything into storage, i.e. into the ParticleLevel.event object + plEvent.m_electrons = m_config->useTruthElectrons() ? m_goodElectrons.get() : nullptr; + plEvent.m_muons = m_config->useTruthMuons() ? m_goodMuons.get() : nullptr; + plEvent.m_softmuons = (m_config->useTruthMuons() && m_config->useSoftMuons()) ? m_goodSoftMuons.get() : nullptr; + plEvent.m_photons = m_config->useTruthPhotons() ? m_goodPhotons.get() : nullptr; + plEvent.m_jets = m_config->useTruthJets() ? m_goodJets.get() : nullptr; + plEvent.m_largeRJets = m_config->useTruthLargeRJets() ? m_goodLargeRJets.get() : nullptr; + plEvent.m_taus = m_config->useTruthTaus() ? m_goodTaus.get() : nullptr; + plEvent.m_met = m_config->useTruthMET() ? (*mets)[ "NonInt" ] : nullptr; + + // Reclustered jets + if (m_config->useRCJets()) { + top::check(m_particleLevelRCJetObjectLoader->execute( + plEvent), "Failed to execute ParticleLevelRCJetObjectLoader container"); + // Get the name of the container of re-clustered jets + std::string RCJetContainerNane = m_particleLevelRCJetObjectLoader->rcjetContainerName(); + + // -- Retrieve the re-clustered jets from TStore & save good re-clustered jets -- // + const xAOD::JetContainer* rc_jets(nullptr); + top::check(evtStore()->retrieve(rc_jets, RCJetContainerNane), "Failed to retrieve particle RC JetContainer"); + + for (auto rcjet : *rc_jets) { + top::check(rcjet->isAvailable<bool>( + "PassedSelection"), + " Can't find reclustered jet decoration \"PassedSelection\" - we need it to decide if we should keep the reclustered jet in the top::Event instance or not!"); + if (rcjet->auxdataConst<bool>("PassedSelection")) plEvent.m_RCJets.push_back((xAOD::Jet*) rcjet); + } + } + // Variable-R reclustered jets + if (m_config->useVarRCJets()) { + for (auto& rho : m_VarRCJetRho) { + for (auto& mass_scale : m_VarRCJetMassScale) { + std::replace(rho.begin(), rho.end(), '.', '_'); + std::string name = rho + mass_scale; + top::check(m_particleLevelVarRCJetObjectLoader[name]->execute( + plEvent), "Failed to execute RCJetMC15 container"); + + // Get the name of the container of re-clustered jets in TStore + std::string varRCJetContainerName = m_particleLevelVarRCJetObjectLoader[name]->rcjetContainerName(); + + // -- Retrieve the re-clustered jets from TStore & save good re-clustered jets -- // + const xAOD::JetContainer* vrc_jets(nullptr); + top::check(evtStore()->retrieve(vrc_jets, varRCJetContainerName), "Failed to retrieve RC JetContainer"); + + plEvent.m_VarRCJets[name] = std::make_shared<xAOD::JetContainer>(SG::VIEW_ELEMENTS); + for (auto vrcjet : *vrc_jets) { + top::check(vrcjet->isAvailable<bool>( + "PassedSelection"), + " Can't find jet decoration \"PassedSelection\" - we need it to decide if we should keep the variable-R reclustered jet in the top::Event instance or not!"); + if (vrcjet->auxdataConst<bool>("PassedSelection")) plEvent.m_VarRCJets[name]->push_back((xAOD::Jet*) vrcjet); + + } + } + } } - bool ParticleLevelLoader::isDressingPhoton(const xAOD::TruthParticle & photon, - const xAOD::TruthParticleContainer & dressedParticles, - const float dressingCone /* = 0.1 */) const { - // We do not check whether the original truth particle decoration exists - // and / or is valid because at this point we assume that it was already - // used by the lepton loading function. - static const std::string decoName{"originalTruthParticle"}; - for (const auto & particle : dressedParticles){ - auto truthProxy = particle->auxdata<ElementLink<xAOD::TruthParticleContainer> >("originalTruthParticle"); - if ((* truthProxy)->p4().DeltaR(photon.p4()) <= dressingCone){ - return true; - } + return plEvent; + } - } + bool ParticleLevelLoader::loadDressedLeptons(const xAOD::TruthParticleContainer& input, + std::unique_ptr<xAOD::TruthParticleContainer>& store, + std::unique_ptr<xAOD::ShallowAuxContainer>& storeAux) const { + auto dressed = xAOD::shallowCopyContainer(input); - return false; + store.reset(dressed.first); + storeAux.reset(dressed.second); + + for (auto pl : *store.get()) { + TLorentzVector fvDressed; + fvDressed.SetPtEtaPhiE(pl->auxdata<float>("pt_dressed"), + pl->auxdata<float>("eta_dressed"), + pl->auxdata<float>("phi_dressed"), + pl->auxdata<float>("e_dressed")); + + // Store original kinematics as decoration + // m->auxdata<int>( "nPhotons_dressed" ) = m->auxdata<int>( "nPhotons_dressed" ); + + pl->auxdata<float>("pt_bare") = pl->pt(); + pl->auxdata<float>("eta_bare") = pl->eta(); + pl->auxdata<float>("phi_bare") = pl->phi(); + pl->auxdata<float>("e_bare") = pl->e(); + + pl->setPx(fvDressed.Px()); + pl->setPy(fvDressed.Py()); + pl->setPz(fvDressed.Pz()); + pl->setE(fvDressed.E()); } + + return true; + } + + bool ParticleLevelLoader::isDressingPhoton(const xAOD::TruthParticle& photon, + const xAOD::TruthParticleContainer& dressedParticles, + const float dressingCone /* = 0.1 */) const { + // We do not check whether the original truth particle decoration exists + // and / or is valid because at this point we assume that it was already + // used by the lepton loading function. + static const std::string decoName { + "originalTruthParticle" + }; + + for (const auto& particle : dressedParticles) { + bool tp_isValid = false; + ElementLink<xAOD::TruthParticleContainer> truthProxy; + try { + truthProxy = particle->auxdata<ElementLink<xAOD::TruthParticleContainer> >("originalTruthParticle"); + tp_isValid = truthProxy.isValid(); + } catch (const SG::ExcBadAuxVar&) { + // ExcBadAuxVar can be thrown before checking if proxy is valid + tp_isValid = false; + } + + if (not tp_isValid) { + if (particle->p4().DeltaR(photon.p4()) <= dressingCone) { + return true; + } + } else { + if ((*truthProxy)->p4().DeltaR(photon.p4()) <= dressingCone) { + return true; + } + } + } + + return false; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelMuonObjectSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelMuonObjectSelector.cxx index ce976792e0f7..c650dfef2787 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelMuonObjectSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelMuonObjectSelector.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelMuonObjectSelector.cxx // Description: @@ -13,62 +13,64 @@ #include "TopParticleLevel/TruthTools.h" namespace top { + ParticleLevelMuonObjectSelector::ParticleLevelMuonObjectSelector(Options opt /* = Options() */) + : m_opt(opt) { /* Deliberately Empty */} - ParticleLevelMuonObjectSelector::ParticleLevelMuonObjectSelector( Options opt /* = Options() */ ) - : m_opt( opt ){ /* Deliberately Empty */ } + /* virtual */ bool + ParticleLevelMuonObjectSelector::apply(const xAOD::TruthParticle& truthParticle) { + // Obtain the particle type and particle origin from the decoration + // created by the MCTruthClassifier. For legacy reasons, try both + // decoration names. + unsigned int type; - /* virtual */ bool - ParticleLevelMuonObjectSelector::apply( const xAOD::TruthParticle & truthParticle ) { - - // Obtain the particle type and particle origin from the decoration - // created by the MCTruthClassifier. For legacy reasons, try both - // decoration names. - unsigned int type; - if ( truthParticle.isAvailable<unsigned int>( "particleType" ) ){ - type = truthParticle.auxdata<unsigned int>( "particleType" ); - } else if ( truthParticle.isAvailable<unsigned int>( "classifierParticleType" ) ){ - type = truthParticle.auxdata<unsigned int>( "classifierParticleType" ); - } else { - std::cerr << "Could not obtain MCTruthClassifier result decoration." << std::endl; - std::exit( 1 ); - } - - // -------------------------------------------------- - // Accept muons iff they do not come from a hadron - using namespace MCTruthPartClassifier; - if ( m_opt.not_from_hadron && - type != ParticleType::IsoMuon ){ - return false; - } - - // If it is requested that tauons are hadrons, perform a check of the - // ancestry: It shall not contain a single tauon. - if ( m_opt.tau_is_hadron ){ - auto truthProxy = truthParticle.auxdata<ElementLink<xAOD::TruthParticleContainer> >( "originalTruthParticle" ); - if ( not truthProxy.isValid() ){ - std::cerr << "Could not obtain 'originalTruthParticle' reference." << std::endl; - std::exit( 1 ); - } - if ( truth::isLeptonFromTau( * truthProxy ) ){ - return false; - } - } + if (truthParticle.isAvailable<unsigned int>("particleType")) { + type = truthParticle.auxdata<unsigned int>("particleType"); + } else if (truthParticle.isAvailable<unsigned int>("classifierParticleType")) { + type = truthParticle.auxdata<unsigned int>("classifierParticleType"); + } else { + throw std::runtime_error("ParticleLevelMuonObjectSelector::apply: " + "Could not obtain MCTruthClassifier result decoration."); + } + // -------------------------------------------------- + // Accept muons iff they do not come from a hadron + using namespace MCTruthPartClassifier; + if (m_opt.not_from_hadron && + type != ParticleType::IsoMuon) { + return false; + } - // -------------------------------------------------- - // Apply kinematic cut on the dressed pT: - // must exceed 25 GeV - if ( truthParticle.auxdata<float>( "pt_dressed" ) < m_opt.pt_min ){ return false; } + // If it is requested that tauons are hadrons, perform a check of the + // ancestry: It shall not contain a single tauon. + if (m_opt.tau_is_hadron) { + auto truthProxy = truthParticle.auxdata<ElementLink<xAOD::TruthParticleContainer> >("originalTruthParticle"); + if (not truthProxy.isValid()) { + throw std::runtime_error("ParticleLevelMuonObjectSelector::apply: " + "Could not obtain 'originalTruthParticle' reference."); + } + if (truth::isLeptonFromTau(*truthProxy)) { + return false; + } + } - // -------------------------------------------------- - // Apply kinematic cut on the dressed eta: - // must be less than or equal to 2.5 - if ( std::abs( truthParticle.auxdata<float>( "eta_dressed" ) ) > m_opt.eta_max ){ return false; } + // -------------------------------------------------- + // Apply kinematic cut on the dressed pT: + // must exceed 25 GeV + if (truthParticle.auxdata<float>("pt_dressed") < m_opt.pt_min) { + return false; + } - // -------------------------------------------------- - // Everything that reaches this point has passed the selection - return true; + // -------------------------------------------------- + // Apply kinematic cut on the dressed eta: + // must be less than or equal to 2.5 + if (std::abs(truthParticle.auxdata<float>("eta_dressed")) > m_opt.eta_max) { + return false; } + + // -------------------------------------------------- + // Everything that reaches this point has passed the selection + return true; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelPhotonObjectSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelPhotonObjectSelector.cxx index 964255de328e..39e4e51a7c17 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelPhotonObjectSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelPhotonObjectSelector.cxx @@ -1,134 +1,122 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Filename: ParticleLevelPhotonObjectSelector.cxx -// Description: -// Author: Fabian Wilk -// Created: Wed Oct 12 11:41:36 2016 -// -// (c) by The ATLAS Collaboration -// by Fabian Wilk <mail@fabianwilk.de> -// -// This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 -// International License. -// -// You should have received a copy of the license along with this work. -// If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopParticleLevel/ParticleLevelPhotonObjectSelector.h" #include "TopConfiguration/Tokenize.h" namespace top { - ParticleLevelPhotonObjectSelector::ParticleLevelPhotonObjectSelector(Options opt /* = Options() */) - : m_opt(opt){ /* Deliberately Empty */ } - - ParticleLevelPhotonObjectSelector::Options::Options(double ptMin /* = 25.e3 */, - double etaMax /* = 2.5 */, - const std::string & Origin /* = "" */, - const std::string & Isolation /* = "" */) : - pt_min(ptMin), - eta_max(etaMax), - origin(), - isolationVar(""), - isolationCut(){ - - // ========================================================= - // Parse the TruthOrigin Configuration Parameter. - if (Origin == "" || Origin == " "|| Origin == "False" || Origin == "None"){ - // Deliberately Empty - } else { - // This allows us to convert from string name to enum value. - MCTruthPartClassifier::ParticleDef def; - - // Tokenize at comma. - std::vector<std::string> tokens; - tokenize(Origin, tokens, ","); - - while (tokens.size()){ - const auto & token = tokens.back(); - - auto it = std::find(def.sParticleOrigin.begin(), - def.sParticleOrigin.end(), - token); - - top::check(it != def.sParticleOrigin.end(), - "[ParticleLevelPhotonObjectSelector] Invalid particle origin '" + token + "'"); - - origin.push_back( - static_cast<MCTruthPartClassifier::ParticleOrigin>( - std::distance(def.sParticleOrigin.begin(), - it))); - - tokens.pop_back(); - } - } - - // ========================================================= - // Parse the TruthIsolation Configuration Parameter - if (Isolation == "" || Isolation == " " || Isolation == "False" || Isolation == "None"){ - isolationVar = ""; - } else { - // Split at space, should be exactly 2 tokens. - std::vector<std::string> tokens; - tokenize(Isolation, tokens, " "); - top::check(tokens.size() == 2, - "[ParticleLevelPhotonObjectSelector] Invalid input for isolation parameter (expected 2 tokens)."); - - isolationVar = tokens.at(0); - isolationCut = std::stof(tokens.at(1)); - } - } - - - /* virtual */ bool ParticleLevelPhotonObjectSelector::apply(const xAOD::TruthParticle & truthParticle){ - // -------------------------------------------------- - // Require that the photon is status=1 (stable) - // TODO: Should we include other statuses? - if (truthParticle.status() != 1){ - return false; - } - - // -------------------------------------------------- - // Apply kinematic cut on the pT: - // must exceed 25 GeV - if ( truthParticle.pt() < m_opt.pt_min ){ return false; } - - // -------------------------------------------------- - // Apply kinematic cut on the eta: - // must be less than or equal to 2.5 - if ( std::abs( truthParticle.eta() ) > m_opt.eta_max ){ return false; } - - // -------------------------------------------------- - // Apply particle origin cut. - if (m_opt.origin.size()){ - unsigned int origin; - if ( truthParticle.isAvailable<unsigned int>( "particleOrigin" ) ){ - origin = truthParticle.auxdata<unsigned int>( "particleOrigin" ); - } else if ( truthParticle.isAvailable<unsigned int>( "classifierParticleOrigin" ) ){ - origin = truthParticle.auxdata<unsigned int>( "classifierParticleOrigin" ); - } else { - top::check(false, "Could not obtain MCTruthClassifier result decoration."); - } - - if (std::find(m_opt.origin.begin(), m_opt.origin.end(), origin) == m_opt.origin.end()){ - return false; - } - } - - // -------------------------------------------------- - // Apply isolation cut - if (m_opt.isolationVar.size()){ - top::check(truthParticle.isAvailable<float>(m_opt.isolationVar), - "[ParticleLevelPhotonObjectSelector] Selected isolation variable not available!"); - if (m_opt.isolationCut <= truthParticle.auxdata<float>(m_opt.isolationVar) / truthParticle.pt()){ - return false; - } - } - - // -------------------------------------------------- - // Everything that reaches this point has passed the selection - return true; + ParticleLevelPhotonObjectSelector::ParticleLevelPhotonObjectSelector(Options opt /* = Options() */) + : m_opt(opt) { /* Deliberately Empty */} + + ParticleLevelPhotonObjectSelector::Options::Options(double ptMin /* = 25.e3 */, + double etaMax /* = 2.5 */, + const std::string& Origin /* = "" */, + const std::string& Isolation /* = "" */) : + pt_min(ptMin), + eta_max(etaMax), + origin(), + isolationVar(""), + isolationCut() { + // ========================================================= + // Parse the TruthOrigin Configuration Parameter. + if (Origin == "" || Origin == " " || Origin == "False" || Origin == "None") { + // Deliberately Empty + } else { + // This allows us to convert from string name to enum value. + MCTruthPartClassifier::ParticleDef def; + + // Tokenize at comma. + std::vector<std::string> tokens; + tokenize(Origin, tokens, ","); + + while (tokens.size()) { + const auto& token = tokens.back(); + + auto it = std::find(def.sParticleOrigin.begin(), + def.sParticleOrigin.end(), + token); + + top::check(it != def.sParticleOrigin.end(), + "[ParticleLevelPhotonObjectSelector] Invalid particle origin '" + token + "'"); + + origin.push_back( + static_cast<MCTruthPartClassifier::ParticleOrigin>( + std::distance(def.sParticleOrigin.begin(), + it))); + + tokens.pop_back(); + } } + + // ========================================================= + // Parse the TruthIsolation Configuration Parameter + if (Isolation == "" || Isolation == " " || Isolation == "False" || Isolation == "None") { + isolationVar = ""; + } else { + // Split at space, should be exactly 2 tokens. + std::vector<std::string> tokens; + tokenize(Isolation, tokens, " "); + top::check(tokens.size() == 2, + "[ParticleLevelPhotonObjectSelector] Invalid input for isolation parameter (expected 2 tokens)."); + + isolationVar = tokens.at(0); + isolationCut = std::stof(tokens.at(1)); + } + } + + /* virtual */ bool ParticleLevelPhotonObjectSelector::apply(const xAOD::TruthParticle& truthParticle) { + // -------------------------------------------------- + // Require that the photon is status=1 (stable) + // TODO: Should we include other statuses? + if (truthParticle.status() != 1) { + return false; + } + + // -------------------------------------------------- + // Apply kinematic cut on the pT: + // must exceed 25 GeV + if (truthParticle.pt() < m_opt.pt_min) { + return false; + } + + // -------------------------------------------------- + // Apply kinematic cut on the eta: + // must be less than or equal to 2.5 + if (std::abs(truthParticle.eta()) > m_opt.eta_max) { + return false; + } + + // -------------------------------------------------- + // Apply particle origin cut. + if (m_opt.origin.size()) { + unsigned int origin; + if (truthParticle.isAvailable<unsigned int>("particleOrigin")) { + origin = truthParticle.auxdata<unsigned int>("particleOrigin"); + } else if (truthParticle.isAvailable<unsigned int>("classifierParticleOrigin")) { + origin = truthParticle.auxdata<unsigned int>("classifierParticleOrigin"); + } else { + top::check(false, "Could not obtain MCTruthClassifier result decoration."); + } + + if (std::find(m_opt.origin.begin(), m_opt.origin.end(), origin) == m_opt.origin.end()) { + return false; + } + } + + // -------------------------------------------------- + // Apply isolation cut + if (m_opt.isolationVar.size()) { + top::check(truthParticle.isAvailable<float>(m_opt.isolationVar), + "[ParticleLevelPhotonObjectSelector] Selected isolation variable not available!"); + if (m_opt.isolationCut <= truthParticle.auxdata<float>(m_opt.isolationVar) / truthParticle.pt()) { + return false; + } + } + + // -------------------------------------------------- + // Everything that reaches this point has passed the selection + return true; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelRCJetObjectLoader.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelRCJetObjectLoader.cxx new file mode 100644 index 000000000000..ac513b2d29a5 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelRCJetObjectLoader.cxx @@ -0,0 +1,406 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "xAODJet/JetContainer.h" +#include "xAODJet/JetAuxContainer.h" +#include "xAODEventInfo/EventInfo.h" +#include "xAODCore/ShallowCopy.h" +#include "xAODBase/IParticleHelpers.h" +#include "AthContainers/ConstDataVector.h" + + +#include "TopParticleLevel/ParticleLevelRCJetObjectLoader.h" +#include "TopEvent/EventTools.h" +#include "TopParticleLevel/ParticleLevelEvent.h" +#include "TopConfiguration/TopConfig.h" + +#include "fastjet/ClusterSequence.hh" +#include <fastjet/contrib/Nsubjettiness.hh> +#include <fastjet/contrib/EnergyCorrelator.hh> +#include "JetSubStructureUtils/Qw.h" +#include "JetSubStructureUtils/KtSplittingScale.h" +#include "JetSubStructureUtils/EnergyCorrelatorGeneralized.h" +#include "JetSubStructureUtils/EnergyCorrelator.h" + +ParticleLevelRCJetObjectLoader::ParticleLevelRCJetObjectLoader(const std::shared_ptr<top::TopConfig>& cfg) : asg:: + AsgTool("ParticleLevelRCJetObjectLoader"), m_config(cfg) { + m_ptcut = 0.; + m_etamax = 0.; + m_inputJetPtMin = 0.; + m_inputJetEtaMax = 999.; + m_trim = 0.; + m_radius = 0.; + m_treeName = "particleLevel"; + m_InJetContainerBase = "AntiKt4TruthWZJets_RC"; + m_OutJetContainerBase = "AntiKt10RCTrim"; + m_InputJetContainer = "AntiKt4TruthWZJets_RC"; + m_OutputJetContainer = "AntiKt10RCTrim"; + m_name = ""; + m_useJSS = false; + m_useAdditionalJSS = false; + m_jet_def_rebuild = nullptr; + m_nSub1_beta1 = nullptr; + m_nSub2_beta1 = nullptr; + m_nSub3_beta1 = nullptr; + m_ECF1 = nullptr; + m_ECF2 = nullptr; + m_ECF3 = nullptr; + m_split12 = nullptr; + m_split23 = nullptr; + m_qw = nullptr; + m_gECF332 = nullptr; + m_gECF461 = nullptr; + m_gECF322 = nullptr; + m_gECF331 = nullptr; + m_gECF422 = nullptr; + m_gECF441 = nullptr; + m_gECF212 = nullptr; + m_gECF321 = nullptr; + m_gECF311 = nullptr; + + + declareProperty("VarRCjets", m_VarRCjets = false); + declareProperty("VarRCjets_rho", m_VarRCjets_rho = ""); + declareProperty("VarRCjets_mass_scale", m_VarRCjets_mass_scale = ""); +} + +ParticleLevelRCJetObjectLoader::~ParticleLevelRCJetObjectLoader() {} + + +StatusCode ParticleLevelRCJetObjectLoader::initialize() { + /* Initialize the re-clustered jets */ + ATH_MSG_INFO(" Initializing particle level Re-clustered jets "); + + m_name = m_VarRCjets_rho + m_VarRCjets_mass_scale; + + + if (m_VarRCjets) { + m_ptcut = m_config->VarRCJetPtcut(); // 100 GeV + m_etamax = m_config->VarRCJetEtacut(); // 2.5 + m_trim = m_config->VarRCJetTrimcut(); // 0.05 (5% jet pT) + m_radius = m_config->VarRCJetMaxRadius(); // 1.2 (min=0.4) + m_minradius = 0.4; // 0.4 default (until we have smaller jets!) + std::string original_rho(m_VarRCjets_rho); + std::replace(original_rho.begin(), original_rho.end(), '_', '.'); + float rho = std::stof(original_rho); + float m_scale = mass_scales.at(m_VarRCjets_mass_scale); + m_massscale = rho * m_scale * 1e-3; + + m_useJSS = m_config->useVarRCJetSubstructure(); + m_useAdditionalJSS = m_config->useVarRCJetAdditionalSubstructure(); + } else { + m_ptcut = m_config->RCJetPtcut(); // for initialize [GeV] & passSelection + m_etamax = m_config->RCJetEtacut(); // for passSelection + m_trim = m_config->RCJetTrimcut(); // for initialize + m_radius = m_config->RCJetRadius(); // for initialize + m_minradius = -1.0; + m_massscale = -1.0; + + m_useJSS = m_config->useRCJetSubstructure(); + m_useAdditionalJSS = m_config->useRCJetAdditionalSubstructure(); + } + + m_inputJetPtMin = m_config->RCInputJetPtMin(); + m_inputJetEtaMax = m_config->RCInputJetEtaMax(); + + + + m_InputJetContainer = m_InJetContainerBase; + m_OutputJetContainer = m_OutJetContainerBase + m_name; + + // build a jet re-clustering tool for each case + m_jetReclusteringTool = std::make_shared<JetReclusteringTool>(m_treeName + m_name); + top::check(m_jetReclusteringTool->setProperty("InputJetContainer", + m_InputJetContainer), + "Failed inputjetcontainer initialize reclustering tool"); + top::check(m_jetReclusteringTool->setProperty("OutputJetContainer", + m_OutputJetContainer), + "Failed outputjetcontainer initialize reclustering tool"); + top::check(m_jetReclusteringTool->setProperty("ReclusterRadius", + m_radius), "Failed re-clustering radius initialize reclustering tool"); + top::check(m_jetReclusteringTool->setProperty("RCJetPtMin", + m_ptcut * 1e-3), "Failed ptmin [GeV] initialize reclustering tool"); + top::check(m_jetReclusteringTool->setProperty("InputJetPtMin", m_inputJetPtMin * 1e-3), "Failed InputJetPtMin [GeV] initialize reclustering tool"); + top::check(m_jetReclusteringTool->setProperty("TrimPtFrac", + m_trim), "Failed pT fraction initialize reclustering tool"); + top::check(m_jetReclusteringTool->setProperty("VariableRMinRadius", + m_minradius), "Failed VarRC min radius initialize reclustering tool"); + top::check(m_jetReclusteringTool->setProperty("VariableRMassScale", + m_massscale), "Failed VarRC mass scale initialize reclustering tool"); + top::check(m_jetReclusteringTool->initialize(), "Failed to initialize reclustering tool"); + + if (m_useJSS || m_useAdditionalJSS) { + ATH_MSG_INFO("Calculating RCJet Substructure"); + + // Setup a bunch of FastJet stuff + //define the type of jets you will build (http://fastjet.fr/repo/doxygen-3.0.3/classfastjet_1_1JetDefinition.html) + m_jet_def_rebuild = std::make_shared<fastjet::JetDefinition>(fastjet::antikt_algorithm, 1.0, fastjet::E_scheme, + fastjet::Best); + } + if (m_useJSS) { + //Substructure tool definitions + m_nSub1_beta1 = std::make_shared<fastjet::contrib::Nsubjettiness>(1, + fastjet::contrib::OnePass_WTA_KT_Axes(), + fastjet::contrib::UnnormalizedMeasure(1.0)); + m_nSub2_beta1 = std::make_shared<fastjet::contrib::Nsubjettiness>(2, + fastjet::contrib::OnePass_WTA_KT_Axes(), + fastjet::contrib::UnnormalizedMeasure(1.0)); + m_nSub3_beta1 = std::make_shared<fastjet::contrib::Nsubjettiness>(3, + fastjet::contrib::OnePass_WTA_KT_Axes(), + fastjet::contrib::UnnormalizedMeasure(1.0)); + + + m_split12 = std::make_shared<JetSubStructureUtils::KtSplittingScale>(1); + m_split23 = std::make_shared<JetSubStructureUtils::KtSplittingScale>(2); + + m_qw = std::make_shared<JetSubStructureUtils::Qw>(); + + m_ECF1 = std::make_shared<fastjet::contrib::EnergyCorrelator>(1, 1.0, fastjet::contrib::EnergyCorrelator::pt_R); + m_ECF2 = std::make_shared<fastjet::contrib::EnergyCorrelator>(2, 1.0, fastjet::contrib::EnergyCorrelator::pt_R); + m_ECF3 = std::make_shared<fastjet::contrib::EnergyCorrelator>(3, 1.0, fastjet::contrib::EnergyCorrelator::pt_R); + } + if (m_useAdditionalJSS) { + + m_gECF332 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(3, 3, 2, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF461 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(6, 4, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF322 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(2, 3, 2, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF331 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(3, 3, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF422 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(2, 4, 2, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF441 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(4, 4, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF212 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(1, 2, 2, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF321 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(2, 3, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + m_gECF311 = std::make_shared<JetSubStructureUtils::EnergyCorrelatorGeneralized>(1, 3, 1, + JetSubStructureUtils::EnergyCorrelator::pt_R); + } + ATH_MSG_INFO(" Re-clustered jets initialized "); + + return StatusCode::SUCCESS; +} // end initialize() + +StatusCode ParticleLevelRCJetObjectLoader::execute(const top::ParticleLevelEvent& plEvent) { + /* + Make the jet container (if necessary) and execute the re-clustering tool + https://svnweb.cern.ch/trac/atlasoff/browser/PhysicsAnalysis/TopPhys/xAOD/TopEvent/trunk/Root/TopEventMaker.cxx#L31 + */ + + // -- Save the jet container to the TStore (only if it doesn't already exist!) + // -- Then, we can access it with the re-clustering tool further down + if (!evtStore()->contains<xAOD::JetContainer>(m_InputJetContainer)) { + auto rcJetInputs = std::make_unique< ConstDataVector< xAOD::JetContainer > >(SG::VIEW_ELEMENTS); + for(const xAOD::Jet* jet : *plEvent.m_jets) { + if(jet->pt() < m_inputJetPtMin || std::abs(jet->eta()) > m_inputJetEtaMax) continue; + rcJetInputs->push_back(jet); + } + top::check(evtStore()->tds()->record(std::move(rcJetInputs), m_InputJetContainer), + "Failed to put jets in TStore for re-clustering"); + } // end if jet container exists + + + + + + // --- EXECUTE --- // + // only execute if the jet container doesn't exist + // (do not re-make the 'nominal' jet container over & over again!) + if (!evtStore()->contains<xAOD::JetContainer>(m_OutputJetContainer)) { + m_jetReclusteringTool->execute(); + + const xAOD::JetContainer* myJets(nullptr); + top::check(evtStore()->retrieve(myJets, m_OutputJetContainer), "Failed to retrieve particle RC JetContainer"); + + for (auto rcjet : *myJets) { + rcjet->auxdecor<bool>("PassedSelection") = passSelection(*rcjet); + } + + if (m_useJSS || m_useAdditionalJSS) { + static const SG::AuxElement::ConstAccessor<bool> passedSelection("PassedSelection"); + + for (auto rcjet : *myJets) { + if (!passedSelection(*rcjet)) continue; // Calculate JSS only if passed object selection + + + std::vector<fastjet::PseudoJet> clusters; + clusters.clear(); + + for (auto subjet : rcjet->getConstituents()) { + const xAOD::Jet* subjet_raw = static_cast<const xAOD::Jet*>(subjet->rawConstituent()); + + + for (auto clus_itr : subjet_raw->getConstituents()) { + + TLorentzVector temp_p4; + temp_p4.SetPtEtaPhiM(clus_itr->pt(), clus_itr->eta(), clus_itr->phi(), clus_itr->m()); + + + // Only in case AntiKt4EMPFlowJets are used include in the substructure only the charged component of the + // substructure + if (m_config->sgKeyJetsTDS(m_config->nominalHashValue(), + false).find("AntiKt4EMPFlowJets") != std::string::npos) { + + const xAOD::TruthParticle* tp = dynamic_cast<const xAOD::TruthParticle*>(clus_itr->rawConstituent()); + + if( tp == nullptr) + continue; + + // Do not use charged particles + if (tp->charge() == 0) continue; + + //Apply same track selection used at reco-level + if ((clus_itr->pt() < m_config->ghostTrackspT()) || ( std::abs(clus_itr->eta()) > 2.5 ) ) continue; + } + + clusters.push_back(fastjet::PseudoJet(temp_p4.Px(), temp_p4.Py(), temp_p4.Pz(), temp_p4.E())); + } + } + + if (clusters.size() != 0) { + fastjet::ClusterSequence clust_seq_rebuild = fastjet::ClusterSequence(clusters, *m_jet_def_rebuild); + std::vector<fastjet::PseudoJet> my_pjets = fastjet::sorted_by_pt(clust_seq_rebuild.inclusive_jets(0.0)); + + fastjet::PseudoJet correctedJet; + correctedJet = my_pjets[0]; + //Sometimes fastjet splits the jet into two, so need to correct for that!! + if (my_pjets.size() > 1) correctedJet += my_pjets[1]; + + if (m_useJSS) { + // Now finally we can calculate some substructure! + double tau32 = -1, tau21 = -1; + + double tau1 = m_nSub1_beta1->result(correctedJet); + double tau2 = m_nSub2_beta1->result(correctedJet); + double tau3 = m_nSub3_beta1->result(correctedJet); + + if (std::abs(tau1) > 1e-8) tau21 = tau2 / tau1; + else tau21 = -999.0; + if (std::abs(tau2) > 1e-8) tau32 = tau3 / tau2; + else tau32 = -999.0; + + + + double split12 = m_split12->result(correctedJet); + double split23 = m_split23->result(correctedJet); + double qw = m_qw->result(correctedJet); + + double D2 = -1; + + double vECF1 = m_ECF1->result(correctedJet); + double vECF2 = m_ECF2->result(correctedJet); + double vECF3 = m_ECF3->result(correctedJet); + if (std::abs(vECF2) > 1e-8) D2 = vECF3 * vECF1* vECF1* vECF1 / (vECF2 * vECF2 * vECF2); + else D2 = -999.0; + + // now attach the results to the original jet + rcjet->auxdecor<float>("Tau32_clstr") = tau32; + rcjet->auxdecor<float>("Tau21_clstr") = tau21; + + // lets also write out the components so we can play with them later + rcjet->auxdecor<float>("Tau3_clstr") = tau3; + rcjet->auxdecor<float>("Tau2_clstr") = tau2; + rcjet->auxdecor<float>("Tau1_clstr") = tau1; + + rcjet->auxdecor<float>("d12_clstr") = split12; + rcjet->auxdecor<float>("d23_clstr") = split23; + rcjet->auxdecor<float>("Qw_clstr") = qw; + + + rcjet->auxdecor<float>("nconstituent_clstr") = clusters.size(); + + rcjet->auxdecor<float>("ECF1_clstr") = vECF1; + rcjet->auxdecor<float>("ECF2_clstr") = vECF2; + rcjet->auxdecor<float>("ECF3_clstr") = vECF3; + rcjet->auxdecor<float>("D2_clstr") = D2; + } // end of if useJSS + + if (m_useAdditionalJSS) { + + // MlB's t/H discriminators + // E = (a*n) / (b*m) + // for an ECFG_X_Y_Z, a=Y, n=Z -> dimenionless variable + double gECF332 = m_gECF332->result(correctedJet); + double gECF461 = m_gECF461->result(correctedJet); + double gECF322 = m_gECF322->result(correctedJet); + double gECF331 = m_gECF331->result(correctedJet); + double gECF422 = m_gECF422->result(correctedJet); + double gECF441 = m_gECF441->result(correctedJet); + double gECF212 = m_gECF212->result(correctedJet); + double gECF321 = m_gECF321->result(correctedJet); + double gECF311 = m_gECF311->result(correctedJet); + + double L1 = -999.0, L2 = -999.0, L3 = -999.0, L4 = -999.0, L5 = -999.0; + if (std::abs(gECF212) > 1e-12) { + L1 = gECF321 / gECF212; + L2 = gECF331 / sqrt(gECF212*gECF212*gECF212); + } + if (std::abs(gECF331) > 1e-12) { + L3 = gECF311 / pow(gECF331,1./3.); + L4 = gECF322 / pow(gECF331,4./3.); + } + if (std::abs(gECF441) > 1e-12) { + L5 = gECF422/gECF441; + } + + rcjet->auxdecor<float>("gECF332_clstr") = gECF332; + rcjet->auxdecor<float>("gECF461_clstr") = gECF461; + rcjet->auxdecor<float>("gECF322_clstr") = gECF322; + rcjet->auxdecor<float>("gECF331_clstr") = gECF331; + rcjet->auxdecor<float>("gECF422_clstr") = gECF422; + rcjet->auxdecor<float>("gECF441_clstr") = gECF441; + rcjet->auxdecor<float>("gECF212_clstr") = gECF212; + rcjet->auxdecor<float>("gECF321_clstr") = gECF321; + rcjet->auxdecor<float>("gECF311_clstr") = gECF311; + rcjet->auxdecor<float>("L1_clstr") = L1; + rcjet->auxdecor<float>("L2_clstr") = L2; + rcjet->auxdecor<float>("L3_clstr") = L3; + rcjet->auxdecor<float>("L4_clstr") = L4; + rcjet->auxdecor<float>("L5_clstr") = L5; + } + + // lets also store the rebuilt jet in case we need it later + if (m_useJSS || m_useAdditionalJSS) { + rcjet->auxdecor<float>("RRCJet_pt") = correctedJet.pt(); + rcjet->auxdecor<float>("RRCJet_eta") = correctedJet.eta(); + rcjet->auxdecor<float>("RRCJet_phi") = correctedJet.phi(); + rcjet->auxdecor<float>("RRCJet_e") = correctedJet.e(); + }// end of if useAdditional JSS + }//end of check on cluster size + } // end rcjet loop + } // //m_useJSS || m_useAdditionalJSS + } //if (!evtStore()->contains<xAOD::JetContainer>(m_OutputJetContainer)) + + + // // } + + return StatusCode::SUCCESS; +} // end execute() + +StatusCode ParticleLevelRCJetObjectLoader::finalize() { + return StatusCode::SUCCESS; +} + +bool ParticleLevelRCJetObjectLoader::passSelection(const xAOD::Jet& jet) const { + /* + Check if the re-clustered jet passes selection. + Right now, this only does something for |eta| because + pT is taken care of in the re-clustering tool. When + small-r jet mass is available (calibrated+uncertainties), + we can cut on that. + */ + // [pT] calibrated to >~ 22 GeV (23 Jan 2016) + if (jet.pt() < m_ptcut) return false; + + // [|eta|] calibrated < 2.5 + if (std::abs(jet.eta()) > m_etamax) return false; + + // small-r jet mass not calibrated and no uncertainties + + return true; +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelTauObjectSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelTauObjectSelector.cxx new file mode 100644 index 000000000000..e312a2e4dc90 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/ParticleLevelTauObjectSelector.cxx @@ -0,0 +1,55 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopParticleLevel/ParticleLevelTauObjectSelector.h" + +#include "MCTruthClassifier/MCTruthClassifierDefs.h" +#include "TopParticleLevel/TruthTools.h" + +namespace top { + ParticleLevelTauObjectSelector::ParticleLevelTauObjectSelector(Options opt /* = Options() */) + : m_opt(opt) { /* Deliberately Empty */} + + bool ParticleLevelTauObjectSelector::apply(const xAOD::TruthParticle& truthParticle) { + // Obtain the particle type and particle origin from the decoration + // created by the MCTruthClassifier. For legacy reasons, try both + // decoration names. + unsigned int type; + + if (truthParticle.isAvailable<unsigned int>("particleType")) { + type = truthParticle.auxdata<unsigned int>("particleType"); + } else if (truthParticle.isAvailable<unsigned int>("classifierParticleType")) { + type = truthParticle.auxdata<unsigned int>("classifierParticleType"); + } else { + throw std::runtime_error { + "Could not obtain MCTruthClassifier result decoration." + }; + } + + // -------------------------------------------------- + // Accept muons iff they do not come from a hadron + using namespace MCTruthPartClassifier; + if (type != ParticleType::IsoTau) { + return false; + } + + // -------------------------------------------------- + // Apply kinematic cut on the dressed pT: + // must exceed 25 GeV + if (truthParticle.pt() < m_opt.pt_min) { + return false; + } + + // -------------------------------------------------- + // Apply kinematic cut on the dressed eta: + // must be less than or equal to 2.5 + if (std::fabs(truthParticle.eta()) > m_opt.eta_max) { + return false; + } + + // -------------------------------------------------- + // Everything that reaches this point has passed the selection + return true; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/TruthTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/TruthTools.cxx index b10ea4e16386..823acab9e818 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/TruthTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/Root/TruthTools.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // Filename: TruthTools.cxx // Description: @@ -8,8 +8,12 @@ // Created: Wed Feb 4 11:05:43 2015 #include "TopParticleLevel/TruthTools.h" +#include "TopEvent/EventTools.h" #include "xAODTruth/TruthVertex.h" +#include "AthContainers/AuxElement.h" +#include "xAODTruth/xAODTruthHelpers.h" +#include "xAODTruth/TruthParticleContainer.h" #include "TruthUtils/PIDHelpers.h" @@ -17,311 +21,1119 @@ #include <string> #include <sstream> #include <functional> +#include <iostream> + +#include "TopParticleLevel/MsgCategory.h" + +using namespace TopParticleLevel; + namespace top { - namespace truth { - - void printDecayChain( const xAOD::TruthParticle * truthPart, - std::ostream & os /* = std::cout */, - const std::string & prefix /* = "" */ ){ - // Protect against a faulty production vertex reference. - if ( not truthPart->prodVtx() ){ - os << prefix << "[" << truthPart->pdgId() << " <- NULL]" << '\n'; - return; - } - - const xAOD::TruthParticle * parent{ truthPart->prodVtx()->incomingParticle( 0 ) }; - os << prefix << "[" << truthPart->pdgId(); - while ( parent ){ - os << " <- " << parent->pdgId(); - if ( parent->prodVtx() ){ - parent = parent->prodVtx()->incomingParticle( 0 ); - } - else { - break; - } - } - os << "]" << '\n'; - } - - - bool isFrom( const xAOD::TruthParticle * truthParticle, - const std::vector<int> & parentPDGIds, - bool bOnlyDirect /* = false */ ){ - // If the input does not have aproper production vertex reference or - // there are no incoming particle to the production vertex, directly - // return false - if ( ! truthParticle->hasProdVtx() || - ! truthParticle->prodVtx() || - truthParticle->prodVtx()->nIncomingParticles() == 0 ) { - return false; - } - - // The current production vertex - const xAOD::TruthVertex * prodVtx = truthParticle->prodVtx(); - // The previous production vertex (initialised to the current - // production vertex) - const xAOD::TruthVertex * prevProdVtx = prodVtx; - - auto numIncoming = prodVtx->nIncomingParticles(); - for ( std::size_t motherIndex = 0; - motherIndex < numIncoming; - ++motherIndex ){ - - const xAOD::TruthParticle * mother= nullptr; - int motherPdgId = truthParticle->pdgId(); - - // Ascend through the decay chain until we find the "actual" - // decay, i.e. a change in the PDG ID. This skips all the - // non-decay truth table entries which come from "particle - // evolution" rather than physical decay - while ( truthParticle->pdgId() == motherPdgId ) { - mother = prodVtx->incomingParticle( motherIndex ); - if ( mother ) { - motherPdgId = mother->pdgId(); - } - else { break; } - - if ( truthParticle->pdgId() != motherPdgId ) { break; } - - // Include protection against cyclic or broken reference - // chains which can occur in SHERPA samples - if( ! mother->hasProdVtx() ) { break; } - if ( prevProdVtx == mother->prodVtx() ) { break; } - - // Update the previous / current production vertex references - prevProdVtx = prodVtx; - prodVtx = mother->prodVtx(); - - // safeguard - if ( ! prodVtx || prodVtx->nIncomingParticles() == 0 ) { break; } - } - - // Check that the mother pointer is valid. If it is not valid, then - // the particle could not possibly come from any of the requested - // PDG Ids, hence return false - if ( ! mother ){ return false; } - - // If the mother PDG ID is in the parentPDGIds collection, then return true - if ( std::find( parentPDGIds.begin(), parentPDGIds.end(), motherPdgId ) != parentPDGIds.end() ){ - return true; - } - - // If we allow chained matching (I.e. not only _direct_ decays) and - // the mother particle does come from the request PDG ID(s), return true - if ( ! bOnlyDirect && isFrom( mother, parentPDGIds, bOnlyDirect ) ){ - return true; - } - } - - // If we did't find an ancestor with the requested pdg id, return false - return false; - } - - bool isFromWZDecay( const xAOD::TruthParticle * truthParticle, - bool bOnlyDirect /* = false */ ) { - // If the input does not have aproper production vertex reference or - // there are no incoming particle to the production vertex, directly - // return false - if ( ! truthParticle->hasProdVtx() || - ! truthParticle->prodVtx() || - truthParticle->prodVtx()->nIncomingParticles() == 0 ) { - return false; - } - - // The current production vertex - const xAOD::TruthVertex * prodVtx = truthParticle->prodVtx(); - // The previous production vertex (initialised to the current - // production vertex) - const xAOD::TruthVertex * prevProdVtx = prodVtx; - - - auto numIncoming = prodVtx->nIncomingParticles(); - for ( std::size_t motherIndex = 0; - motherIndex < numIncoming; - ++motherIndex ){ - - const xAOD::TruthParticle * mother = nullptr; - int motherAbsPdgId = truthParticle->absPdgId(); - - // Ascend through the decay chain until we find the "actual" - // decay, i.e. a change in the PDG ID. This skips all the - // non-decay truth table entries which come from "particle - // evolution" rather than physical decay - while ( truthParticle->absPdgId() == motherAbsPdgId ) { - mother = prodVtx->incomingParticle( motherIndex ); - if ( mother ) { - motherAbsPdgId = mother->absPdgId(); - } - else { break; } - - if ( truthParticle->absPdgId() != motherAbsPdgId ) { break; } - - // Include protection against cyclic or broken reference - // chains which can occur in SHERPA samples - if( ! mother->hasProdVtx() ) { break; } - if ( prevProdVtx == mother->prodVtx() ) { break; } - - // Update the previous / current production vertex references - prevProdVtx = prodVtx; - prodVtx = mother->prodVtx(); - - // safeguard - if ( ! prodVtx || prodVtx->nIncomingParticles() == 0 ) { break; } - } - - // Check that the mother pointer is valid. If it is not valid, then - // the particle could not possibly come from any of the requested - // PDG Ids, hence return false - if ( ! mother ){ return false; } - - // If the direct physical decay in the MC record was from a Z or W - // boson to the truth particle then return true - // Otherwise perform a vertex-based identification of W/Z's - if ( motherAbsPdgId == 23 || motherAbsPdgId == 24 ){ - return true; - } - - // The following vertex-based identification of W/Z's is needed - // for SHERPA samples where the W/Z particle is not explicitly - // in the particle record. At this point if we have a valid - // vertex, it should be a true decay vertex. - // - // If it is a W or Z then two of those decay products should be - // lepton / neutrino pair corresponding to the transitions - // W+ -> l+ nu - // W- -> l- nu~ - // Z -> l+ l- - // Z -> nu nu~ - // Hence loop through the outgoing particles of the truth vertex - // and check that the vertex matches the requirement. We - // simplify this check by just counting the number of leptonic - // outgoing particles which should be equal to 2. It is assumed - // that the MC generator does not produce unphysical decays. - // - // Furthermore, prompt W/Z's should come from a vertex with more - // than one incoming particle. Consequently, test this - // requirement prior to checking the outgoing states. - int nDecay = 0; - if ( prodVtx && prodVtx->nIncomingParticles() > 1 ) { - for ( const auto & child : prodVtx->outgoingParticleLinks() ){ - if ( ( * child )->absPdgId() > 10 && - ( * child )->absPdgId() < 17 ) { - nDecay++; - } - } - } - - // There must be exactly two leptonic outgoing particles in that vertex - if ( nDecay == 2 ){ - return true; - } - - // If we allow chained matching (I.e. not only _direct_ decays) and - // the mother particle does come from a W / Z, return true - if ( ! bOnlyDirect && isFromWZDecay( mother, bOnlyDirect ) ){ - return true; - } - } - - // We did not find any W / Z in the ancestry of the input particle -> - // return false - return false; - } - - bool isLeptonFromTau( const xAOD::TruthParticle * truthParticle ){ - // If the input particle is not a lepton directly terminate the - // algorithm retunring false - if ( truthParticle->absPdgId() != 11 && - truthParticle->absPdgId() != 12 && - truthParticle->absPdgId() != 13 && - truthParticle->absPdgId() != 14 && - truthParticle->absPdgId() != 15 && - truthParticle->absPdgId() != 16 ) { - return false; - } - return isFrom( truthParticle, { 15, -15 }, true ); - } - - bool isNotFromHadron( const xAOD::TruthParticle * truthParticle, - bool bOnlyDirect /* = false */, - bool bTauIsHadron /* = false */ ){ - // If there is no production vertex, either something is wrong, or - // we are at the beginning of the record. However, either way, the - // particle does not come from a hadron, hence return true. - if ( ! truthParticle->hasProdVtx() || - ! truthParticle->prodVtx() || - truthParticle->prodVtx()->nIncomingParticles() == 0 ) { - return true; - } - - // The current production vertex - const xAOD::TruthVertex * prodVtx = truthParticle->prodVtx(); - // The previous production vertex (initialised to the current - // production vertex) - const xAOD::TruthVertex * prevProdVtx = prodVtx; - - // Loop all the particles going into the production vertex of the - // current truth particle. - // * If the mother of any of the is a physical hadron return false - // * If the mother of any of them descends from a physical return false - // * Otherwise return true - auto numIncoming = prodVtx->nIncomingParticles(); - for ( std::size_t motherIndex = 0; - motherIndex < numIncoming; - ++motherIndex ){ - - int motherPdgId = truthParticle->pdgId(); - const xAOD::TruthParticle * mother = nullptr; - - // Ascend through the decay chain until we find the "actual" - // decay, i.e. a change in the PDG ID. This skips all the - // non-decay truth table entries which come from "particle - // evolution" rather than physical decay - while ( truthParticle->pdgId() == motherPdgId ) { - mother = prodVtx->incomingParticle( motherIndex ); - if ( mother ) { - motherPdgId = mother->pdgId(); - } - else { break; } - - // Include protection against cyclic or broken reference - // chains which can occur in SHERPA samples - if( ! mother->hasProdVtx() ) { break; } - if ( prevProdVtx == mother->prodVtx() ) { break; } - - // Update the previous / current production vertex references - prevProdVtx = prodVtx; - prodVtx = mother->prodVtx(); - - // safeguard - if ( ! prodVtx || prodVtx->nIncomingParticles() == 0 ) { break; } - } - - // Check that the mother pointer is valid. If it is not valid, then - // the particle could not possibly come from a hadron, hence return - // true - if ( ! mother ){ return true; } - - // If the mother particle is a "physical decayed" particle (HepMC - // status code) and a hadron, then return false. - if ( mother->status() == 2 && - ( MC::PID::isHadron( motherPdgId ) || - ( bTauIsHadron && MC::PID::isTau( motherPdgId ) ) ) ){ - return false; - } - // } else { - // std::cout << "Mother is: " << motherPdgId << ", " << mother->status() << std::endl; - // } - - // If we allow chained matching (I.e. not only _direct_ decays) and - // the mother particle does come from a hadron, return false - if ( ! bOnlyDirect && ! isNotFromHadron( mother, bOnlyDirect, bTauIsHadron ) ){ - return false; - } - } - // No hadronic && physical parents - return true; - } + namespace truth { + + + void initCommonMuonHistoryInfo(const xAOD::IParticle* muon, bool doPartonHistory) + { + muon->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag") = top::LepParticleOriginFlag::MissingTruthInfo; + muon->auxdecor<const xAOD::TruthParticle*>("truthMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthFirstNonLeptonMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthBMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthCMotherLink") = 0; + + if(doPartonHistory) + { + muon->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag") = top::LepPartonOriginFlag::MissingTruthInfo; + muon->auxdecor<const xAOD::TruthParticle*>("truthPartonMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthWMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthZMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthPhotonMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink") = 0; + muon->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink") = 0; + } + } + + void initRecoMuonHistoryInfo(const xAOD::Muon* muon, bool doPartonHistory) + { + muon->auxdecor<bool>("hasRecoMuonHistoryInfo")=false; + muon->auxdecor<const xAOD::TruthParticle*>("truthMuonLink") = 0; + initCommonMuonHistoryInfo(muon,doPartonHistory); + } + void initTruthMuonHistoryInfo(const xAOD::TruthParticle* truthmu, bool doPartonHistory) + { + truthmu->auxdecor<bool>("hasTruthMuonHistoryInfo")=false; + if(doPartonHistory) truthmu->auxdecor<bool>("hasTruthMuonPartonHistoryInfo")=false; + initCommonMuonHistoryInfo(truthmu,doPartonHistory); + + } + + void copyRecoMuonHistoryInfo(const xAOD::Muon* m_origin, const xAOD::Muon* m_target) + { + copyCommonMuonHistoryInfo(m_origin,m_target); + m_target->auxdecor<bool>("hasRecoMuonHistoryInfo") = m_origin->auxdecor<bool>("hasRecoMuonHistoryInfo"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthMuonLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthMuonLink"); + } + + void copyTruthMuonHistoryInfo(const xAOD::TruthParticle* tm_origin, const xAOD::TruthParticle* tm_target) + { + copyCommonMuonHistoryInfo(tm_origin,tm_target); + tm_target->auxdecor<bool>("hasTruthMuonHistoryInfo")= tm_origin->auxdecor<bool>("hasTruthMuonHistoryInfo"); + tm_target->auxdecor<bool>("hasTruthMuonPartonHistoryInfo")= tm_origin->auxdecor<bool>("hasTruthMuonPartonHistoryInfo"); + } + + void copyCommonMuonHistoryInfo(const xAOD::IParticle* m_origin, const xAOD::IParticle* m_target) + { + if(!m_origin->isAvailable<top::LepParticleOriginFlag>("LepParticleOriginFlag")) + { + ATH_MSG_ERROR(" top::truth::copyCommonMuonHistoryInfo called with an origin muon which has no truth info!"); + throw; + } + m_target->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag") = m_origin->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthFirstNonLeptonMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthFirstNonLeptonMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthBMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthBMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthCMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthCMotherLink"); + + if(m_origin->isAvailable<top::LepPartonOriginFlag>("LepPartonOriginFlag")) + { + m_target->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag") = m_origin->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthPartonMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthPartonMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthWMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthWMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthZMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthZMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthPhotonMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthPhotonMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink"); + m_target->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink"); + } + } + + const xAOD::TruthParticle* getTruthMuonAssociatedToRecoMuon(const xAOD::Muon* muon) + { + if(!muon) return 0; + const xAOD::TrackParticle* track = muon->primaryTrackParticle(); + if(!track) return 0; + + const xAOD::TruthParticle* truthmu= xAOD::TruthHelpers::getTruthParticle(*track); + if(!truthmu) return 0; + if(!truthmu->isMuon()) return 0; //note that the truth particle associated with a muon can be e.g. a pion/kaon in some cases (since pion/kaon decays are not done at generator level, but at simulation level), we ignore these cases + + return truthmu; + } + + void getRecoMuonHistory(const xAOD::Muon* muon, bool doPartonHistory, SampleXsection::showering shAlgo, bool verbose) + { + + if(verbose) ATH_MSG_INFO("getRecoMuonHistory:: ---------------entering in function-----------------"); + if(!muon) return; + + if(verbose) + { + //we retrieve the origin from the MCClassifier, it's useful for crosschecks; see https://gitlab.cern.ch/atlas/athena/blob/21.2/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifierDefs.h + int origin=0; + const static SG::AuxElement::Accessor<int> origmu("truthOrigin"); + if (origmu.isAvailable(*muon)) origin = origmu(*muon); + + ATH_MSG_INFO("getRecoMuonHistory::called on muon with pt="<<muon->pt()<<" origin="<<origin); + } + + if(doPartonHistory && shAlgo!=SampleXsection::pythia8 && shAlgo!=SampleXsection::herwigpp) + { + static int nWarnings=0; + if(nWarnings<10 || verbose) + { + ATH_MSG_WARNING("top::truth::getRecoMuonHistory : partonHistory can be checked only for pythia8 and herwigpp showering algorithms, SoftMuonAdditionalTruthInfoCheckPartonOrigin will be ignored for this sample"); + nWarnings++; + } + doPartonHistory=false; + } + + if(!muon->isAvailable<bool>("hasRecoMuonHistoryInfo")) //add default values + { + initRecoMuonHistoryInfo(muon,doPartonHistory); + } + else if(muon->auxdecor<bool>("hasRecoMuonHistoryInfo")) + { + if(verbose) ATH_MSG_INFO("getRecoMuonHistory::we already ran on this muon, exiting"); + return; //this means we already ran on this muon in some way + } + muon->auxdecor<bool>("hasRecoMuonHistoryInfo")=true; + + //first we retrieve the truth muon associated with the reco one + const xAOD::TruthParticle* truthmu = muon->auxdecor<const xAOD::TruthParticle*>("truthMuonLink"); //pointer to the truth muon associated with the reco muon + + if(!truthmu) truthmu=top::truth::getTruthMuonAssociatedToRecoMuon(muon); + + if(verbose) ATH_MSG_INFO("getRecoMuonHistory:: retrieved truth muon pointer="<<truthmu); + if(!truthmu) return; + + muon->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag") = top::LepParticleOriginFlag::Unknown; + if(doPartonHistory) muon->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag") = top::LepPartonOriginFlag::Unknown; + + if(verbose) + { + ATH_MSG_INFO("getRecoMuonHistory::---truth decay chain---"); + printDecayChain(truthmu, msg(MSG::Level::INFO)); + } + + getTruthMuonHistory(truthmu, doPartonHistory, shAlgo, verbose); + //we attach the truth muon to the reco muon + copyCommonMuonHistoryInfo(truthmu,muon); + + muon->auxdecor<const xAOD::TruthParticle*>("truthMuonLink") = truthmu; + + if(verbose) + { + ATH_MSG_INFO("getRecoMuonHistory:: written LepParticleOriginFlag decoration = "<<static_cast<int>(muon->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag"))); + if(doPartonHistory) ATH_MSG_INFO("getRecoMuonHistory:: written LepPartonOriginFlag decoration = "<<static_cast<int>(muon->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag"))); + ATH_MSG_INFO("getRecoMuonHistory:: exiting function"); + } + return; + + } + + ////getTruthMuonHistory///// + void getTruthMuonHistory(const xAOD::TruthParticle* truthmu, bool doPartonHistory, SampleXsection::showering shAlgo, bool verbose) + { + if(verbose) ATH_MSG_INFO("getTruthMuonHistory:: entering in function"); + + if(!truthmu) + { + if(verbose) ATH_MSG_INFO("getTruthMuonHistory:: -> called on empty truth muon"); + return; + } + if(!(truthmu->isMuon())) + { + if(verbose) ATH_MSG_INFO("getTruthMuonHistory:: -> called on non-muon particle"); + return; + } + + if(verbose) ATH_MSG_INFO("getTruthMuonHistory:: -> called on truth particle with pdgId="<<truthmu->pdgId()<<" barcode="<<truthmu->barcode()<<" status="<<truthmu->status()<<" pt="<<truthmu->pt()); + + if(!truthmu->isAvailable<bool>("hasTruthMuonHistoryInfo")) //add default values + { + initTruthMuonHistoryInfo(truthmu,doPartonHistory); + } + else if(truthmu->auxdecor<bool>("hasTruthMuonHistoryInfo")) + { + if(verbose) ATH_MSG_INFO("getTruthMuonHistory:: -> we already ran on this truth muon, exiting"); + return; + } + truthmu->auxdecor<bool>("hasTruthMuonHistoryInfo")=true; + + top::LepParticleOriginFlag lepParticleOriginFlag=top::LepParticleOriginFlag::Unknown; //flag defined in TopEvent/EventTools.h + const xAOD::TruthParticle* truthmu_mother=0; //direct mother of the muon + const xAOD::TruthParticle* truthmu_firstNonLeptonMother=0; //in case of X->muon or X->tau->muon, this will always contain X + const xAOD::TruthParticle* truthmu_Bmother=0; //first bottom hadron encountered when going through ancestors + const xAOD::TruthParticle* truthmu_Cmother=0; //first charmed hadron encountered when going through ancestors + + const xAOD::TruthParticle* initial_mu = getInitialStateParticle(truthmu); + if(initial_mu) truthmu_mother= initial_mu->parent(0); + + if(truthmu_mother && abs(truthmu_mother->pdgId())!=13) //let's then look at the history of this muon + { + + if(!truthmu_mother->isLepton()) truthmu_firstNonLeptonMother=truthmu_mother; //basically all cases apart from tau->muon + + if(verbose) ATH_MSG_INFO("getTruthMuonHistory::mother pdgId="<<truthmu_mother->pdgId()<<" isB="<<truthmu_mother->isBottomHadron()<<" isC="<<truthmu_mother->isCharmHadron()<<" isLight="<<truthmu_mother->isLightHadron()); + + if(truthmu_mother->isLightHadron()) lepParticleOriginFlag=top::LepParticleOriginFlag::FromLightHadron; //in this case we set the muon as coming from a light hadron and we don't investigate further + else if(truthmu_mother->isW()) //W->munu + { + lepParticleOriginFlag=top::LepParticleOriginFlag::FromLeptonicW; + } + else if(truthmu_mother->isZ()) //Z->mumu + { + lepParticleOriginFlag=top::LepParticleOriginFlag::FromLeptonicZ; + } + else if(truthmu_mother->isPhoton()) //gamma*->mumu decay + { + lepParticleOriginFlag=top::LepParticleOriginFlag::FromPhoton; + } + else if(truthmu_mother->isHiggs()) + { + lepParticleOriginFlag=top::LepParticleOriginFlag::FromHiggs; + } + else if(truthmu_mother->isBSM()) + { + lepParticleOriginFlag=top::LepParticleOriginFlag::FromBSM; + } + else if(truthmu_mother->isTau()) //muon from tau + { + lepParticleOriginFlag=top::truth::getTruthMuonFromTauHistory(truthmu_mother,truthmu_Bmother,truthmu_Cmother,truthmu_firstNonLeptonMother,verbose); + } + else if(truthmu_mother->isBottomHadron()) //muon from B->mu+X decay + { + lepParticleOriginFlag=top::LepParticleOriginFlag::FromB; + truthmu_Bmother=truthmu_mother; + } + else if(truthmu_mother->isCharmHadron()) //muon from D->mu+X decay, now we have to understand where the D is coming from + { + truthmu_Cmother=truthmu_mother; + lepParticleOriginFlag=top::truth::getTruthMuonFromCharmHistory(truthmu_Bmother,truthmu_Cmother,verbose); + }//end of if + }//end of if(truthmu_mother) + + if(verbose) + { + ATH_MSG_INFO("getTruthMuonHistory::LepParticleOriginFlag="<<static_cast<int>(lepParticleOriginFlag)); + if(truthmu) ATH_MSG_INFO("getTruthMuonHistory::-->truth muon pdgId="<<truthmu->pdgId()<<" barcode="<<truthmu->barcode()<<" pt="<<truthmu->pt()); + else ATH_MSG_INFO("getTruthMuonHistory::-->truth muon not found"); + if(truthmu_mother) ATH_MSG_INFO("getTruthMuonHistory::-->truth muon mother pdgId="<<truthmu_mother->pdgId()<<" barcode="<<truthmu_mother->barcode()<<" pt="<<truthmu_mother->pt()); + else ATH_MSG_INFO("getTruthMuonHistory::-->truth muon mother not found"); + if(truthmu_firstNonLeptonMother) ATH_MSG_INFO("getTruthMuonHistory::-->truthmu_firstNonLeptonMother pdgId="<<truthmu_firstNonLeptonMother->pdgId()<<" barcode="<<truthmu_firstNonLeptonMother->barcode()<<" pt="<<truthmu_firstNonLeptonMother->pt()); + else ATH_MSG_INFO("getTruthMuonHistory::-->truthmu_firstNonLeptonMother not found"); + if(truthmu_Bmother) ATH_MSG_INFO("getTruthMuonHistory::-->truth muon Bmother pdgId="<<truthmu_Bmother->pdgId()<<" barcode="<<truthmu_Bmother->barcode()<<" pt="<<truthmu_Bmother->pt()); + else ATH_MSG_INFO("getTruthMuonHistory::-->truth muon Bmother not found"); + if(truthmu_Cmother) ATH_MSG_INFO("getTruthMuonHistory::-->truth muon Cmother pdgId="<<truthmu_Cmother->pdgId()<<" barcode="<<truthmu_Cmother->barcode()<<" pt="<<truthmu_Cmother->pt()); + else ATH_MSG_INFO("getTruthMuonHistory::-->truth muon Cmother not found"); + } + + //we decorate also on the truth muon associated with the reco one, because in this way if the truth muon was already decorated in another copy of the muon (for systematics) we avoid losing time. + truthmu->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag") = lepParticleOriginFlag; + truthmu->auxdecor<const xAOD::TruthParticle*>("truthFirstNonLeptonMotherLink") = truthmu_firstNonLeptonMother; + truthmu->auxdecor<const xAOD::TruthParticle*>("truthMotherLink") = truthmu_mother; + truthmu->auxdecor<const xAOD::TruthParticle*>("truthBMotherLink") = truthmu_Bmother; + truthmu->auxdecor<const xAOD::TruthParticle*>("truthCMotherLink") = truthmu_Cmother; + + if(doPartonHistory) top::truth::getTruthMuonPartonHistory(truthmu, lepParticleOriginFlag, truthmu_Bmother, truthmu_Cmother, truthmu_firstNonLeptonMother, shAlgo, verbose); + + if(verbose) ATH_MSG_INFO("getTruthMuonHistory:: exiting from function"); + + return; + } + + /////getTruthMuonPartonHistory///// + void getTruthMuonPartonHistory(const xAOD::TruthParticle* truthmu, top::LepParticleOriginFlag lepParticleOriginFlag, const xAOD::TruthParticle* truthmu_Bmother, const xAOD::TruthParticle* truthmu_Cmother, const xAOD::TruthParticle* truthmu_firstNonLeptonMother, SampleXsection::showering shAlgo, bool verbose) + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: entering in function"); + + if(!truthmu && verbose) + { + ATH_MSG_INFO("getTruthMuonPartonHistory:: -> called on empty truth muon"); + return; + } + + if(!truthmu->isAvailable<bool>("hasTruthMuonPartonHistoryInfo"))//default values + { + initTruthMuonHistoryInfo(truthmu,true); + } + else if(truthmu->auxdecor<bool>("hasTruthMuonPartonHistoryInfo")) + { + if(verbose) ATH_MSG_INFO("getTruthMuonHistory:: -> we already ran on this truth muon, exiting"); + return; + } + truthmu->auxdecor<bool>("hasTruthMuonPartonHistoryInfo")=true; + + const xAOD::TruthParticle* truthmu_mother=truthmu_firstNonLeptonMother; + + if(!truthmu_mother) + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> no muon mother available, returning"); + return; + } + if(lepParticleOriginFlag==top::LepParticleOriginFlag::MissingTruthInfo || lepParticleOriginFlag==top::LepParticleOriginFlag::FromLightHadron) + { + + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from light hadron, will not fill info"); + return; + } + + top::LepPartonOriginFlag lepPartonOriginFlag=top::LepPartonOriginFlag::Unknown; + + //this is the priority we use to look for parents in order: top, higgs, BSM, W/Z, gamma* + auto get_priority = [](const xAOD::TruthParticle* p) -> int { + if(!p) return 999; + if(p->isTop()) return 0; + if(p->isHiggs()) return 10; + if(p->isBSM()) return 15; + if(p->isW() || p->isZ()) return 20; + if(p->isPhoton()) return 25; + return 100; + }; + + if(truthmu_mother->isTop()) // shouldn't happen, but maybe some generators don't store intermediate bosons + { + truthmu->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink") = truthmu_mother; + truthmu->auxdecor<const xAOD::TruthParticle*>("truthPartonMotherLink") = truthmu_mother; + if(truthmu_mother->pdgId()>0) lepPartonOriginFlag=top::LepPartonOriginFlag::FromTopViaLeptonicBoson; + else lepPartonOriginFlag=top::LepPartonOriginFlag::FromAntiTopViaLeptonicBoson; + } + else if(truthmu_mother->isHiggs()) + { + truthmu->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink") = truthmu_mother; + lepPartonOriginFlag=top::LepPartonOriginFlag::FromHiggs; + } + else if(truthmu_mother->isBSM()) + { + truthmu->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink") = truthmu_mother; + lepPartonOriginFlag=top::LepPartonOriginFlag::FromBSM; + } + else if(truthmu_mother->isW() || truthmu_mother->isZ() || truthmu_mother->isPhoton() ) //the muon is coming from a leptonically decaying boson (eventually via a boson->tau->mu) + { + lepPartonOriginFlag=top::LepPartonOriginFlag::FromLeptonicBoson; //this is the basic info if we don't find further infromation + + if(truthmu_mother->isW()) truthmu->auxdecor<const xAOD::TruthParticle*>("truthWMotherLink") = truthmu_mother; + else if(truthmu_mother->isZ()) truthmu->auxdecor<const xAOD::TruthParticle*>("truthZMotherLink") = truthmu_mother; + else if(truthmu_mother->isPhoton()) truthmu->auxdecor<const xAOD::TruthParticle*>("truthPhotonMotherLink") = truthmu_mother; + + //then we check in case we can find the mother of the boson + const xAOD::TruthParticle* initialStateBoson=top::truth::getInitialStateParticle(truthmu_mother,verbose); + const xAOD::TruthParticle* bosonOrigin=0; + unsigned int bosonOrigin_priority=999; + + if(initialStateBoson) + { + for(unsigned int ip=0; ip<initialStateBoson->nParents(); ip++) + { + const xAOD::TruthParticle* parent=initialStateBoson->parent(ip); + if(!parent) continue; + + unsigned int parent_priority=get_priority(parent); + if(parent_priority<bosonOrigin_priority) + { + bosonOrigin_priority=parent_priority; + bosonOrigin=parent; + } + } + } + if(bosonOrigin && bosonOrigin->isTop()) + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from boson from top"); + + truthmu->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink") = bosonOrigin; + if(bosonOrigin->pdgId()>0) lepPartonOriginFlag=top::LepPartonOriginFlag::FromTopViaLeptonicBoson; + else lepPartonOriginFlag=top::LepPartonOriginFlag::FromAntiTopViaLeptonicBoson; + } + else if(bosonOrigin && bosonOrigin->isHiggs()) + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from boson from higgs"); + truthmu->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink") = bosonOrigin; + lepPartonOriginFlag=top::LepPartonOriginFlag::FromHiggsViaLeptonicBosonToHF; + } + else if(bosonOrigin && bosonOrigin->isBSM()) + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from boson from BSM"); + truthmu->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink") = bosonOrigin; + lepPartonOriginFlag=top::LepPartonOriginFlag::FromBSMViaLeptonicBosonToHF; + } + else + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from boson not from top or higgs"); + lepPartonOriginFlag=top::LepPartonOriginFlag::FromLeptonicBoson; + } + } + else if(truthmu_Bmother || truthmu_Cmother) //in this case the muon is not coming from a boson direct decay, we treat only cases from HF hadrons + { + lepPartonOriginFlag=top::LepPartonOriginFlag::FromHFHadronOfUnkownOrigin; //default case + + bool isBHadronMother=truthmu_Bmother; + const xAOD::TruthParticle* hadronMother= isBHadronMother ? truthmu_Bmother : truthmu_Cmother; + const xAOD::TruthParticle* firstHadronMother=getFirstHFHadronOfSameFlavour(hadronMother,verbose); + + if(verbose) + { + ATH_MSG_INFO("getTruthMuonPartonHistory:: isBHadronmother="<<isBHadronMother<<" Bmom="<<truthmu_Bmother<<" Cmom="<<truthmu_Cmother<<" hadMom="<<hadronMother<<" firstHadMom="<<firstHadronMother); + ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from hadron pdgId="<<(hadronMother ? hadronMother->pdgId() : 0)<<", first hadron in chain pdgId="<<(firstHadronMother ? firstHadronMother->pdgId() : 0)); + } + if(firstHadronMother) + { + + const xAOD::TruthParticle* hf_parton_parent=0; + + if(shAlgo == SampleXsection::herwigpp) //in herwig we have pdgId==81 for clusters as hadron parents + { + if(firstHadronMother->parent(0) && firstHadronMother->parent(0)->pdgId()==81) + { + firstHadronMother=getInitialStateParticle(firstHadronMother->parent(0)); + } + } + + //first we find the HF parton that originated the HF hadron + for(unsigned int ip=0; ip<firstHadronMother->nParents(); ip++) + { + const xAOD::TruthParticle* parent=firstHadronMother->parent(ip); + if(!parent) continue; + if(isBHadronMother && abs(parent->pdgId())==5) + { + hf_parton_parent=parent; + break; + } + else if(!isBHadronMother && abs(parent->pdgId())==4) + { + hf_parton_parent=parent; + break; + } + + } + + truthmu->auxdecor<const xAOD::TruthParticle*>("truthPartonMotherLink") =hf_parton_parent; + + //the we get the first HF parton of the evolution chain + const xAOD::TruthParticle* initial_hf_parton_parent=0; + if(hf_parton_parent) initial_hf_parton_parent = top::truth::getInitialStateParticle(hf_parton_parent,verbose); + + //parton ancestor will be the particle/resonance originating the first HF quark + const xAOD::TruthParticle* parton_ancestor=0; + unsigned int parton_ancestor_priority=999; + + if(initial_hf_parton_parent) + { + for(unsigned int ip=0; ip<initial_hf_parton_parent->nParents(); ip++) + { + const xAOD::TruthParticle* parent=initial_hf_parton_parent->parent(ip); + if(!parent) continue; + if(!parton_ancestor) parton_ancestor=parent; + else + { + unsigned int priority =get_priority(parent); + if(priority < parton_ancestor_priority) + { + parton_ancestor_priority=priority; + parton_ancestor=parent; + } + } + } + } + + //finally we (hopefully) know where the HF hadron is originally coming from + if(parton_ancestor && parton_ancestor->isTop()) + { + truthmu->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink") = parton_ancestor; + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from HF from top"); + + if(parton_ancestor->pdgId()>0) lepPartonOriginFlag=top::LepPartonOriginFlag::FromTopViaQuarkToHF; + else lepPartonOriginFlag=top::LepPartonOriginFlag::FromAntiTopViaQuarkToHF; + } + else if(parton_ancestor && parton_ancestor->isHiggs()) + { + truthmu->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink") = parton_ancestor; + lepPartonOriginFlag=top::LepPartonOriginFlag::FromHiggsToHF; + } + else if(parton_ancestor && parton_ancestor->isBSM()) + { + truthmu->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink") = parton_ancestor; + lepPartonOriginFlag=top::LepPartonOriginFlag::FromBSMToHF; + } + else if(parton_ancestor && (parton_ancestor->isW() || parton_ancestor->isZ() || parton_ancestor->isPhoton())) + { + const xAOD::TruthParticle* first_bosonMotherOfHfQuark=top::truth::getInitialStateParticle(parton_ancestor); + + if(parton_ancestor->isW()) truthmu->auxdecor<const xAOD::TruthParticle*>("truthWMotherLink") = parton_ancestor; + else if(parton_ancestor->isZ()) truthmu->auxdecor<const xAOD::TruthParticle*>("truthZMotherLink") = parton_ancestor; + else if(parton_ancestor->isPhoton()) truthmu->auxdecor<const xAOD::TruthParticle*>("truthPhotonMotherLink") = parton_ancestor; + + const xAOD::TruthParticle* bosonOrigin=0; + unsigned int bosonOrigin_priority=999; + + if(first_bosonMotherOfHfQuark) + { + for(unsigned int ip=0; ip<first_bosonMotherOfHfQuark->nParents(); ip++) + { + const xAOD::TruthParticle* parent=first_bosonMotherOfHfQuark->parent(ip); + if(!parent) continue; + + unsigned int priority =get_priority(parent); + if(priority<bosonOrigin_priority) + { + bosonOrigin=parent; + bosonOrigin_priority=priority; + } + } + if(bosonOrigin && bosonOrigin->isTop()) + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from HF from boson from top"); + truthmu->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink") = bosonOrigin; + + if(bosonOrigin->pdgId()>0) lepPartonOriginFlag=top::LepPartonOriginFlag::FromTopViaHadronicBosonToHF; + else lepPartonOriginFlag=top::LepPartonOriginFlag::FromAntiTopViaHadronicBosonToHF; + } + else if(bosonOrigin && bosonOrigin->isHiggs()) + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from HF from boson from higgs"); + truthmu->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink") = bosonOrigin; + lepPartonOriginFlag=top::LepPartonOriginFlag::FromHiggsViaHadronicBosonToHF; + } + else if(bosonOrigin && bosonOrigin->isBSM()) + { + if(verbose) ATH_MSG_INFO("getTruthMuonPartonHistory:: -> muon from HF from boson from BSM"); + truthmu->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink") = bosonOrigin; + lepPartonOriginFlag=top::LepPartonOriginFlag::FromBSMViaHadronicBosonToHF; + } + else + { + lepPartonOriginFlag=top::LepPartonOriginFlag::FromHadronicBosonToHF; //not sure where this is coming from + } + } + }//end of V->HF->muon case + + }//end of HF->muon case + + }//end of non-bosonic case + + truthmu->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag") = lepPartonOriginFlag; + + if(verbose) ATH_MSG_INFO("getTruthMuonHistory::------> LepPartonOriginFlag="<<static_cast<int>(lepPartonOriginFlag)); + + return; + + }//end of getTruthMuonPartonHistory + + /////getTruthMuonFromCharmHistory///// + top::LepParticleOriginFlag getTruthMuonFromCharmHistory(const xAOD::TruthParticle* &truthmu_Bmother, const xAOD::TruthParticle* truthmu_Cmother, bool verbose) + { + if(verbose) ATH_MSG_INFO("called getTruthMuonFromCharmHistory"); + const xAOD::TruthParticle* initial_C_hadron=getFirstHFHadronOfSameFlavour(truthmu_Cmother); //we find the first non-Chadron ancestor of the C-hadron + + if(initial_C_hadron) + { + bool hasBHadronParent=false; + for(unsigned int ip=0; ip<initial_C_hadron->nParents(); ip++) + { + const xAOD::TruthParticle* parent=initial_C_hadron->parent(ip); + if(!parent) continue; + if(parent->isBottomHadron()) + { + hasBHadronParent=true; + truthmu_Bmother=parent; + break; + } + } + if(hasBHadronParent) return top::LepParticleOriginFlag::FromBtoC; + } + + return top::LepParticleOriginFlag::FromC; //we don't know where the C-hadron is coming from + } //end of getTruthMuonFromCharmHistory method + + /////getTruthMuonFromTauHistory///// + top::LepParticleOriginFlag getTruthMuonFromTauHistory(const xAOD::TruthParticle* tau, const xAOD::TruthParticle* &truthmu_Bmother, const xAOD::TruthParticle* &truthmu_Cmother, const xAOD::TruthParticle* &truthmu_firstNonLeptonMother, bool verbose) + { + if(!tau && verbose) + { + ATH_MSG_WARNING("getTruthMuonFromTauHistory called on empty tau"); + return top::LepParticleOriginFlag::FromTau; + } + if(!tau->isTau()) + { + ATH_MSG_ERROR("getTruthMuonFromTauHistory called on non-tau, pdgId"<<(tau->pdgId())); + throw; + } + const xAOD::TruthParticle* initialTau = top::truth::getInitialStateParticle(tau); + if(!initialTau) + { + if(verbose)ATH_MSG_INFO("getTruthMuonFromTauHistory:: could not find initial state tau"); + return top::LepParticleOriginFlag::FromTau; + } + + const xAOD::TruthParticle* tauMother=initialTau->parent(0); + + if(!tauMother) return top::LepParticleOriginFlag::FromTau; //muon from tau, we don't know where the tau is coming from + + if(!tauMother->isLepton()) truthmu_firstNonLeptonMother=tauMother; + + if(tauMother->isW()) //W->taunu with tau->mununu decay + { + return top::LepParticleOriginFlag::FromLeptonicWToTau; + } + if(tauMother->isZ()) //Z->tautau with tau->mununu + { + return top::LepParticleOriginFlag::FromLeptonicZToTau; + } + if(tauMother->isPhoton()) + { + return top::LepParticleOriginFlag::FromPhotonToTau; + } + if(tauMother->isHiggs()) + { + return top::LepParticleOriginFlag::FromHiggsToTau; + } + if(tauMother->isBSM()) + { + return top::LepParticleOriginFlag::FromBSMToTau; + } + if(tauMother->isBottomHadron()) //the muon is from a B->tau+X with tau->mununu decay + { + truthmu_Bmother=tauMother; + return top::LepParticleOriginFlag::FromBtoTau; + } + if(tauMother->isCharmHadron()) //now this is getting complicated, the muon is from e.g. D->tau+X with tau->mununu decay, now we have to understand where the D is coming from... + { + truthmu_Cmother=tauMother; + const xAOD::TruthParticle* initial_C_hadron=getFirstHFHadronOfSameFlavour(truthmu_Cmother); //we find the first non-Chadron ancestor of the C-hadron + + bool hasBHadronParent=false; + + for(unsigned int ip=0; ip<initial_C_hadron->nParents(); ip++) + { + const xAOD::TruthParticle* parent=initial_C_hadron->parent(ip); + if(!parent) continue; + if(parent->isBottomHadron()) + { + hasBHadronParent=true; + truthmu_Bmother=parent; + break; + } + } + if(hasBHadronParent) return top::LepParticleOriginFlag::FromBtoCtoTau; + else //in this case this is coming from D->tau->mu+X or something with no B-hadron ancestor + { + return top::LepParticleOriginFlag::FromCtoTau; + } + }//end of if(tauMother->isCharmHadron()) + + return top::LepParticleOriginFlag::FromTau; //in all other cases we don't know anything apart from the fact that the muon is coming from a tau + }//end of getTruthMuonFromTauHistory method + + //getFirstHadronOfSameFlavour// + const xAOD::TruthParticle* getFirstHFHadronOfSameFlavour(const xAOD::TruthParticle* truthParticle, bool verbose) + { + if(!truthParticle) return 0; + bool isBottomHadron=truthParticle->isBottomHadron(); + bool isCharmHadron=truthParticle->isCharmHadron(); + + if(!(isBottomHadron) && !(isCharmHadron)) + { + if(verbose) ATH_MSG_INFO("getFirstHFHadronOfSameFlavour:: this can be called only on HF hadrons..."); + return 0; + } + const xAOD::TruthParticle* parent=truthParticle; + int niterations=0; + while(parent) + { + if((niterations++)>100) + { + if(verbose) ATH_MSG_INFO("getFirstHFHadronOfSameFlavour:: too many iterations on particle "<<(truthParticle->pdgId())); + return 0; + } + + parent=getInitialStateParticle(parent,verbose); + if(!parent) + { + if(verbose) ATH_MSG_INFO("getFirstHFHadronOfSameFlavour:: initial state particle not found"); + break; + } + + if(verbose) ATH_MSG_INFO("getFirstHFHadronOfSameFlavour:: initial state particle found="<<(parent->pdgId())); + + bool hasSameFlavourParent=false; + for(unsigned int ip=0; ip<parent->nParents(); ip++) + { + if(parent->parent(ip)) + { + if((isBottomHadron && parent->parent(ip)->isBottomHadron())||(isCharmHadron && parent->parent(ip)->isCharmHadron())) + { + parent=parent->parent(ip); + hasSameFlavourParent=true; + break; + } + } + } + + if(!hasSameFlavourParent) + { + if(verbose) ATH_MSG_INFO("getFirstHFHadronOfSameFlavour:: parent="<<(parent->pdgId())<<" has no same flavour ancestor"); + break; + } + else + { + if(verbose) ATH_MSG_INFO("getFirstHFHadronOfSameFlavour:: found same flavour parent="<<(parent->pdgId())); + } + + } + return parent; + } + //end of getFirstHadronOfSameFlavour method// + + //getInitialStateParticle// + const xAOD::TruthParticle* getInitialStateParticle(const xAOD::TruthParticle* truthParticle, bool verbose) + { + if(!truthParticle) return 0; + int pdgId=truthParticle->pdgId(); + int niterations=0; + const xAOD::TruthParticle* parent=truthParticle; + + while(parent) + { + if((niterations++)>100) + { + if(verbose) ATH_MSG_INFO("getInitialStateParticle:: too many iterations for particle "<<(truthParticle->pdgId())); + return 0; + } + + bool hasParentWithSamePdgId=false; + for(unsigned int ip=0; ip<parent->nParents(); ip++) + { + if(parent->parent(ip) && (parent->parent(ip)->pdgId()==pdgId)) + { + parent=parent->parent(ip); + hasParentWithSamePdgId=true; + break; + } + } + if(!hasParentWithSamePdgId) break; + } + return parent; + } + //end of getInitialStateParticle method// + + void printDecayChain(const xAOD::TruthParticle* truthPart, + std::ostream& os /* = std::cout */, + const std::string& prefix /* = "" */) { + // Protect against a faulty production vertex reference. + if (!truthPart || !truthPart->prodVtx()) { + os << prefix << "[" << (truthPart ? truthPart->pdgId() :0x0) << " <- NULL]" << '\n'; + return; + } + + os << prefix << "[" << truthPart->pdgId(); + int niterations=0; + + while (truthPart) { + if((niterations++)>30) + { + os<<" STOP! too many iterations "; + break; + } + if(truthPart->nParents()<1) break; + + os << " <- "; + const xAOD::TruthParticle* firstWithSamePdgId=0; + const xAOD::TruthParticle* firstNonParton=0; + const xAOD::TruthParticle* firstCorrectFlavorQuark=0; + + for(unsigned int ip=0; ip<truthPart->nParents(); ip++) + { + if(ip>0) os<<", "; + os<<" "<<(truthPart->parent(ip) ? truthPart->parent(ip)->pdgId() : 0); + if(!truthPart->parent(ip)) continue; + + if(!firstWithSamePdgId && truthPart->parent(ip)->pdgId()==truthPart->pdgId()) + { + firstWithSamePdgId = truthPart->parent(ip); + } + if(!firstNonParton && !truthPart->parent(ip)->isParton()) + { + firstNonParton = truthPart->parent(ip); + } + if(truthPart->isBottomHadron() && abs(truthPart->parent(ip)->pdgId())==5) + { + firstCorrectFlavorQuark = truthPart->parent(ip); + } + if(truthPart->isCharmHadron() && abs(truthPart->parent(ip)->pdgId())==4) + { + firstCorrectFlavorQuark = truthPart->parent(ip); + } + + } + if(firstWithSamePdgId) truthPart=firstWithSamePdgId; + else if(firstNonParton) truthPart=firstNonParton; + else if(firstCorrectFlavorQuark) truthPart=firstCorrectFlavorQuark; + else truthPart=truthPart->parent(0); + + } + os << "]" << '\n'; + } + + bool isFrom(const xAOD::TruthParticle* truthParticle, + const std::vector<int>& parentPDGIds, + bool bOnlyDirect /* = false */) { + // If the input does not have aproper production vertex reference or + // there are no incoming particle to the production vertex, directly + // return false + if (!truthParticle->hasProdVtx() || + !truthParticle->prodVtx() || + truthParticle->prodVtx()->nIncomingParticles() == 0) { + return false; + } + + // The current production vertex + const xAOD::TruthVertex* prodVtx = truthParticle->prodVtx(); + // The previous production vertex (initialised to the current + // production vertex) + const xAOD::TruthVertex* prevProdVtx = prodVtx; + + auto numIncoming = prodVtx->nIncomingParticles(); + for (std::size_t motherIndex = 0; + motherIndex < numIncoming; + ++motherIndex) { + const xAOD::TruthParticle* mother = nullptr; + int motherPdgId = truthParticle->pdgId(); + + // Ascend through the decay chain until we find the "actual" + // decay, i.e. a change in the PDG ID. This skips all the + // non-decay truth table entries which come from "particle + // evolution" rather than physical decay + while (truthParticle->pdgId() == motherPdgId) { + mother = prodVtx->incomingParticle(motherIndex); + if (mother) { + motherPdgId = mother->pdgId(); + } else { + break; + } + + if (truthParticle->pdgId() != motherPdgId) { + break; + } + + // Include protection against cyclic or broken reference + // chains which can occur in SHERPA samples + if (!mother->hasProdVtx()) { + break; + } + if (prevProdVtx == mother->prodVtx()) { + break; + } + + // Update the previous / current production vertex references + prevProdVtx = prodVtx; + prodVtx = mother->prodVtx(); + + // safeguard + if (!prodVtx || prodVtx->nIncomingParticles() == 0) { + break; + } + } + + // Check that the mother pointer is valid. If it is not valid, then + // the particle could not possibly come from any of the requested + // PDG Ids, hence return false + if (!mother) { + return false; + } + + // If the mother PDG ID is in the parentPDGIds collection, then return true + if (std::find(parentPDGIds.begin(), parentPDGIds.end(), motherPdgId) != parentPDGIds.end()) { + return true; + } + + // If we allow chained matching (I.e. not only _direct_ decays) and + // the mother particle does come from the request PDG ID(s), return true + if (!bOnlyDirect && isFrom(mother, parentPDGIds, bOnlyDirect)) { + return true; + } + } + + // If we did't find an ancestor with the requested pdg id, return false + return false; + } + + bool isFromWZDecay(const xAOD::TruthParticle* truthParticle, + bool bOnlyDirect /* = false */) { + // If the input does not have aproper production vertex reference or + // there are no incoming particle to the production vertex, directly + // return false + if (!truthParticle->hasProdVtx() || + !truthParticle->prodVtx() || + truthParticle->prodVtx()->nIncomingParticles() == 0) { + return false; + } + + // The current production vertex + const xAOD::TruthVertex* prodVtx = truthParticle->prodVtx(); + // The previous production vertex (initialised to the current + // production vertex) + const xAOD::TruthVertex* prevProdVtx = prodVtx; + + + auto numIncoming = prodVtx->nIncomingParticles(); + for (std::size_t motherIndex = 0; + motherIndex < numIncoming; + ++motherIndex) { + const xAOD::TruthParticle* mother = nullptr; + int motherAbsPdgId = truthParticle->absPdgId(); + + // Ascend through the decay chain until we find the "actual" + // decay, i.e. a change in the PDG ID. This skips all the + // non-decay truth table entries which come from "particle + // evolution" rather than physical decay + while (truthParticle->absPdgId() == motherAbsPdgId) { + mother = prodVtx->incomingParticle(motherIndex); + if (mother) { + motherAbsPdgId = mother->absPdgId(); + } else { + break; + } + + if (truthParticle->absPdgId() != motherAbsPdgId) { + break; + } + + // Include protection against cyclic or broken reference + // chains which can occur in SHERPA samples + if (!mother->hasProdVtx()) { + break; + } + if (prevProdVtx == mother->prodVtx()) { + break; + } + + // Update the previous / current production vertex references + prevProdVtx = prodVtx; + prodVtx = mother->prodVtx(); + + // safeguard + if (!prodVtx || prodVtx->nIncomingParticles() == 0) { + break; + } + } + + // Check that the mother pointer is valid. If it is not valid, then + // the particle could not possibly come from any of the requested + // PDG Ids, hence return false + if (!mother) { + return false; + } + + // If the direct physical decay in the MC record was from a Z or W + // boson to the truth particle then return true + // Otherwise perform a vertex-based identification of W/Z's + if (motherAbsPdgId == 23 || motherAbsPdgId == 24) { + return true; + } + + // The following vertex-based identification of W/Z's is needed + // for SHERPA samples where the W/Z particle is not explicitly + // in the particle record. At this point if we have a valid + // vertex, it should be a true decay vertex. + // + // If it is a W or Z then two of those decay products should be + // lepton / neutrino pair corresponding to the transitions + // W+ -> l+ nu + // W- -> l- nu~ + // Z -> l+ l- + // Z -> nu nu~ + // Hence loop through the outgoing particles of the truth vertex + // and check that the vertex matches the requirement. We + // simplify this check by just counting the number of leptonic + // outgoing particles which should be equal to 2. It is assumed + // that the MC generator does not produce unphysical decays. + // + // Furthermore, prompt W/Z's should come from a vertex with more + // than one incoming particle. Consequently, test this + // requirement prior to checking the outgoing states. + int nDecay = 0; + if (prodVtx && prodVtx->nIncomingParticles() > 1) { + for (const auto& child : prodVtx->outgoingParticleLinks()) { + if ((*child)->absPdgId() > 10 && + (*child)->absPdgId() < 17) { + nDecay++; + } + } + } + + // There must be exactly two leptonic outgoing particles in that vertex + if (nDecay == 2) { + return true; + } + + // If we allow chained matching (I.e. not only _direct_ decays) and + // the mother particle does come from a W / Z, return true + if (!bOnlyDirect && isFromWZDecay(mother, bOnlyDirect)) { + return true; + } + } + + // We did not find any W / Z in the ancestry of the input particle -> + // return false + return false; + } + + bool isLeptonFromTau(const xAOD::TruthParticle* truthParticle) { + // If the input particle is not a lepton directly terminate the + // algorithm retunring false + if (truthParticle->absPdgId() != 11 && + truthParticle->absPdgId() != 12 && + truthParticle->absPdgId() != 13 && + truthParticle->absPdgId() != 14 && + truthParticle->absPdgId() != 15 && + truthParticle->absPdgId() != 16) { + return false; + } + return isFrom(truthParticle, {15, -15}, true); + } + + bool isNotFromHadron(const xAOD::TruthParticle* truthParticle, + bool bOnlyDirect /* = false */, + bool bTauIsHadron /* = false */) { + // If there is no production vertex, either something is wrong, or + // we are at the beginning of the record. However, either way, the + // particle does not come from a hadron, hence return true. + if (!truthParticle->hasProdVtx() || + !truthParticle->prodVtx() || + truthParticle->prodVtx()->nIncomingParticles() == 0) { + return true; + } + + // The current production vertex + const xAOD::TruthVertex* prodVtx = truthParticle->prodVtx(); + // The previous production vertex (initialised to the current + // production vertex) + const xAOD::TruthVertex* prevProdVtx = prodVtx; + + // Loop all the particles going into the production vertex of the + // current truth particle. + // * If the mother of any of the is a physical hadron return false + // * If the mother of any of them descends from a physical return false + // * Otherwise return true + auto numIncoming = prodVtx->nIncomingParticles(); + for (std::size_t motherIndex = 0; + motherIndex < numIncoming; + ++motherIndex) { + int motherPdgId = truthParticle->pdgId(); + const xAOD::TruthParticle* mother = nullptr; + + // Ascend through the decay chain until we find the "actual" + // decay, i.e. a change in the PDG ID. This skips all the + // non-decay truth table entries which come from "particle + // evolution" rather than physical decay + while (truthParticle->pdgId() == motherPdgId) { + mother = prodVtx->incomingParticle(motherIndex); + if (mother) { + motherPdgId = mother->pdgId(); + } else { + break; + } + + // Include protection against cyclic or broken reference + // chains which can occur in SHERPA samples + if (!mother->hasProdVtx()) { + break; + } + if (prevProdVtx == mother->prodVtx()) { + break; + } + + // Update the previous / current production vertex references + prevProdVtx = prodVtx; + prodVtx = mother->prodVtx(); + + // safeguard + if (!prodVtx || prodVtx->nIncomingParticles() == 0) { + break; + } + } + + // Check that the mother pointer is valid. If it is not valid, then + // the particle could not possibly come from a hadron, hence return + // true + if (!mother) { + return true; + } + + // If the mother particle is a "physical decayed" particle (HepMC + // status code) and a hadron, then return false. + if (mother->status() == 2 && + (MC::PID::isHadron(motherPdgId) || + (bTauIsHadron && MC::PID::isTau(motherPdgId)))) { + return false; + } + // If we allow chained matching (I.e. not only _direct_ decays) and + // the mother particle does come from a hadron, return false + if (!bOnlyDirect && !isNotFromHadron(mother, bOnlyDirect, bTauIsHadron)) { + return false; + } + } + // No hadronic && physical parents + return true; } + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/MsgCategory.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/MsgCategory.h new file mode 100644 index 000000000000..531d49247e10 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/MsgCategory.h @@ -0,0 +1,11 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ +#ifndef TOPPARTICLELEVEL_MSG_CATEGORY_H_ +#define TOPPARTICLELEVEL_MSG_CATEGORY_H_ +#include <AsgMessaging/MessageCheck.h> + +// message category for stuff in this package that does not inherit from AsgTool +ANA_MSG_HEADER(TopParticleLevel) + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ObjectSelectorBase.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ObjectSelectorBase.h index 209e8cd3355e..d2ad082bb6ec 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ObjectSelectorBase.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ObjectSelectorBase.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ObjectSelectorBase.h // Description: @@ -11,14 +11,13 @@ #define _TOP_OBJECTSELECTORBASE_H_ namespace top { - - template <typename ObjectT> - class ObjectSelectorBase { - public: - ObjectSelectorBase(){} - virtual ~ObjectSelectorBase(){} - virtual bool apply( const ObjectT & obj ) = 0; - }; + template <typename ObjectT> + class ObjectSelectorBase { + public: + ObjectSelectorBase() {} + virtual ~ObjectSelectorBase() {} + virtual bool apply(const ObjectT& obj) = 0; + }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelElectronObjectSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelElectronObjectSelector.h index e5cf9de58910..3857ad0a92d8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelElectronObjectSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelElectronObjectSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelElectronObjectSelector.h // Description: @@ -15,35 +15,33 @@ #include "xAODTruth/TruthParticleContainer.h" namespace top { - - class ParticleLevelElectronObjectSelector - : public ObjectSelectorBase<xAOD::TruthParticle> { - public: - // Struct used to store the cut values used by the object selector. It - // is important that the object has a sensible default config because it - // will be default constructed for the trivial constructor of the object - // selector. - struct Options { - Options( double ptMin = 25.e3, - double etaMax = 2.5, - bool notFromHadron = true, - bool tauIsHadron = false ) : - pt_min( ptMin ), - eta_max( etaMax ), - not_from_hadron( notFromHadron ), - tau_is_hadron( tauIsHadron ){} - double pt_min; - double eta_max; - bool not_from_hadron; - bool tau_is_hadron; - }; - public: - ParticleLevelElectronObjectSelector( Options cuts = Options() ); - virtual bool apply( const xAOD::TruthParticle & truthParticle ); - private: - Options m_opt; + class ParticleLevelElectronObjectSelector + : public ObjectSelectorBase<xAOD::TruthParticle> { + public: + // Struct used to store the cut values used by the object selector. It + // is important that the object has a sensible default config because it + // will be default constructed for the trivial constructor of the object + // selector. + struct Options { + Options(double ptMin = 25.e3, + double etaMax = 2.5, + bool notFromHadron = true, + bool tauIsHadron = false) : + pt_min(ptMin), + eta_max(etaMax), + not_from_hadron(notFromHadron), + tau_is_hadron(tauIsHadron) {} + double pt_min; + double eta_max; + bool not_from_hadron; + bool tau_is_hadron; }; - + public: + ParticleLevelElectronObjectSelector(Options cuts = Options()); + virtual bool apply(const xAOD::TruthParticle& truthParticle); + private: + Options m_opt; + }; } #endif /* _TOP_PARTICLE_LEVEL_ELECTRONOBJECTSELECTOR_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelEvent.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelEvent.h index a4decb7a5bfb..a4949c91c471 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelEvent.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelEvent.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelEvent.h // Description: @@ -12,55 +12,72 @@ #include <string> #include <unordered_map> +#include <iostream> #include "xAODEventInfo/EventInfo.h" #include "xAODJet/JetContainer.h" #include "xAODTruth/TruthParticleContainer.h" #include "xAODMissingET/MissingET.h" +#include "TopEvent/Event.h" namespace top { + class ParticleLevelEvent { + public: + ParticleLevelEvent() + : m_info(nullptr), + m_electrons(nullptr), + m_muons(nullptr), + m_photons(nullptr), + m_jets(nullptr), + m_RCJets(SG::VIEW_ELEMENTS), + m_largeRJets(nullptr), + m_met(nullptr), + m_selectionDecisions() {} - class ParticleLevelEvent { - public: - ParticleLevelEvent() - : m_info( nullptr ), - m_electrons( nullptr ), - m_muons( nullptr ), - m_photons( nullptr ), - m_jets( nullptr ), - m_largeRJets( nullptr ), - m_met( nullptr ), - m_selectionDecisions(){} - - /// Pointer to the event info object - const xAOD::EventInfo * m_info; - - /// Pointer to truth level electrons - const xAOD::TruthParticleContainer * m_electrons; - - /// Pointer to truth level muons - const xAOD::TruthParticleContainer * m_muons; - - /// Pointer to truth level photons - const xAOD::TruthParticleContainer * m_photons; - - /// Pointer to truth level jets - const xAOD::JetContainer * m_jets; - - /// Pointer to the truth level large R jets. - const xAOD::JetContainer * m_largeRJets; - - // Pointer to truth level MET - const xAOD::MissingET * m_met; - - // Maps from the name of an event selection line to the result of - // applying that event selection onto this ParticleLevelEvent. At the - // moment, the mapped value (albeit being of type 'int') is inteded just - // as a true / false statement. Must be mutable because the - // EventSelectionManager will modify it. - mutable std::unordered_map<std::string, int> m_selectionDecisions; - }; + /// Pointer to the event info object + const xAOD::EventInfo* m_info; + + /// Pointer to truth level electrons + const xAOD::TruthParticleContainer* m_electrons; + + /// Pointer to truth level muons + const xAOD::TruthParticleContainer* m_muons; + + /// Pointer to truth level soft-muons + const xAOD::TruthParticleContainer* m_softmuons; + + /// Pointer to truth level photons + const xAOD::TruthParticleContainer* m_photons; + + /// Pointer to truth level jets + const xAOD::JetContainer* m_jets; + + ///Container of recluster jets (can be sorted) + xAOD::JetContainer m_RCJets; + + /// Containers of variable-R reclustered jets (can be sorted) + mutable std::unordered_map< std::string, std::shared_ptr<xAOD::JetContainer> > m_VarRCJets; + + /// Pointer to the truth level large R jets. + const xAOD::JetContainer* m_largeRJets; + + /// Pointer to truth level photons + const xAOD::TruthParticleContainer* m_taus; + + // Pointer to truth level MET + const xAOD::MissingET* m_met; + + // Maps from the name of an event selection line to the result of + // applying that event selection onto this ParticleLevelEvent. At the + // moment, the mapped value (albeit being of type 'int') is inteded just + // as a true / false statement. Must be mutable because the + // EventSelectionManager will modify it. + mutable std::unordered_map<std::string, int> m_selectionDecisions; + }; } +/// Ostream overload operator +std::ostream& operator << (std::ostream& os, const top::ParticleLevelEvent& plEvent); + #endif /* _TOP_PARTICLELEVELEVENT_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelJetObjectSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelJetObjectSelector.h index 4eac883a0d83..38517e27acd4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelJetObjectSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelJetObjectSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelJetObjectSelector.h // Description: @@ -15,27 +15,25 @@ #include "xAODJet/JetContainer.h" namespace top { - - class ParticleLevelJetObjectSelector - : public ObjectSelectorBase<xAOD::Jet> { - public: - // Struct used to store the cut values used by the object selector. It - // is important that the object has a sensible default config because it - // will be default constructed for the trivial constructor of the object - // selector. - struct Options { - Options( double ptMin = 25.e3, double etaMax = 2.5 ) : - pt_min( ptMin ), eta_max( etaMax ){} - double pt_min; - double eta_max; - }; - public: - ParticleLevelJetObjectSelector( Options opt = Options() ); - virtual bool apply( const xAOD::Jet & jet ); - private: - Options m_opt; + class ParticleLevelJetObjectSelector + : public ObjectSelectorBase<xAOD::Jet> { + public: + // Struct used to store the cut values used by the object selector. It + // is important that the object has a sensible default config because it + // will be default constructed for the trivial constructor of the object + // selector. + struct Options { + Options(double ptMin = 25.e3, double etaMax = 2.5) : + pt_min(ptMin), eta_max(etaMax) {} + double pt_min; + double eta_max; }; - + public: + ParticleLevelJetObjectSelector(Options opt = Options()); + virtual bool apply(const xAOD::Jet& jet); + private: + Options m_opt; + }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelLoader.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelLoader.h index bc4ad6980be6..d0ed42e648e5 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelLoader.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelLoader.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelLoader.h // Description: @@ -13,6 +13,7 @@ #include <memory> #include "TopParticleLevel/ObjectSelectorBase.h" +#include "TopParticleLevel/ParticleLevelRCJetObjectLoader.h" #include "AsgTools/AsgTool.h" @@ -31,104 +32,110 @@ // Forward Declarations namespace top { - class ParticleLevelEvent; - class TopConfig; + class ParticleLevelEvent; + class TopConfig; } namespace top { + /*! + * @brief Loading tool which creates a particle level event object. + * + * After creation of the loader tool, it will be in of of two states: either + * it is "active" or not (can be tested using the active() member function). + * If the tool is not active, then the load function is a no-op, it will + * return an "empty" ParticleLevelEvent object. The active() member function + * allows for the enclosing (i.e. calling) program to conditionally branch + * into computing intensive parts depending on whether particle level data + * is available or not. The loader tool is configured to be non-"active" if + * the input data is not monte carlo or any of the required collection names + * are empty respectively None + */ + class ParticleLevelLoader final: public asg::AsgTool { + public: + /*! + * @brief Constructor of the loader tool. + */ + ParticleLevelLoader(const std::shared_ptr<top::TopConfig>& cfg); + + /*! + * @brief Destructor of the loader tool. + */ + virtual ~ParticleLevelLoader(); + + /*! + * @brief Loading function. Does the actual work. This function will + * load the truth information from the #xaodEvent and return this data + * transformed into a truth level event. The data stored in the + * ParticleLevel is owned by the truth event loader. + * @param xaodEvent The input data event object. + * @return ParticleLevelEvent object. + */ + ParticleLevelEvent load(); /*! - * @brief Loading tool which creates a particle level event object. - * - * After creation of the loader tool, it will be in of of two states: either - * it is "active" or not (can be tested using the active() member function). - * If the tool is not active, then the load function is a no-op, it will - * return an "empty" ParticleLevelEvent object. The active() member function - * allows for the enclosing (i.e. calling) program to conditionally branch - * into computing intensive parts depending on whether particle level data - * is available or not. The loader tool is configured to be non-"active" if - * the input data is not monte carlo or any of the required collection names - * are empty respectively None + * @brief Function that can be used to test whether the ParticleLevelLoader + * is active. The loader is set to inactive if the names of the truth + * collections are unavailable. This is determined at construction. */ - class ParticleLevelLoader final : public asg::AsgTool { - public: - /*! - * @brief Constructor of the loader tool. - */ - ParticleLevelLoader( const std::shared_ptr<top::TopConfig> & cfg ); - - /*! - * @brief Destructor of the loader tool. - */ - virtual ~ParticleLevelLoader(); - - /*! - * @brief Loading function. Does the actual work. This function will - * load the truth information from the #xaodEvent and return this data - * transformed into a truth level event. The data stored in the - * ParticleLevel is owned by the truth event loader. - * @param xaodEvent The input data event object. - * @return ParticleLevelEvent object. - */ - ParticleLevelEvent load(); - - /*! - * @brief Function that can be used to test whether the ParticleLevelLoader - * is active. The loader is set to inactive if the names of the truth - * collections are unavailable. This is determined at construction. - */ - bool active() const { return m_active; } - - protected: - bool loadDressedLeptons(const xAOD::TruthParticleContainer & input, - std::unique_ptr<xAOD::TruthParticleContainer> & store, - std::unique_ptr<xAOD::ShallowAuxContainer> & storeAux) const; - - bool isDressingPhoton(const xAOD::TruthParticle & photon, - const xAOD::TruthParticleContainer & dressedParticles, - const float dressingCone = 0.1) const; - - private: - // The global config object - const std::shared_ptr<top::TopConfig> & m_config; - - // The tools used for electron, muon, and jet object selection. The - // basic idea is to allow exchanging these tools for custom ones, - // however, this is not implemented (yet). - std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Electron; - std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Muon; - std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Photon; - std::unique_ptr<ObjectSelectorBase<xAOD::Jet> > m_objectSelector_Jet; - std::unique_ptr<ObjectSelectorBase<xAOD::Jet> > m_objectSelector_LargeRJet; - private: - // The dressed leptons (shallow copies of the input containers) - std::unique_ptr<xAOD::TruthParticleContainer> m_electronsDressed; - std::unique_ptr<xAOD::ShallowAuxContainer> m_electronsDressedAux; - - std::unique_ptr<xAOD::TruthParticleContainer> m_muonsDressed; - std::unique_ptr<xAOD::ShallowAuxContainer> m_muonsDressedAux; - - std::unique_ptr<xAOD::TruthParticleContainer> m_goodElectrons; - std::unique_ptr<xAOD::TruthParticleAuxContainer> m_goodElectronsAux; - - std::unique_ptr<xAOD::TruthParticleContainer> m_goodMuons; - std::unique_ptr<xAOD::TruthParticleAuxContainer> m_goodMuonsAux; - - std::unique_ptr<xAOD::TruthParticleContainer> m_goodPhotons; - std::unique_ptr<xAOD::TruthParticleAuxContainer> m_goodPhotonsAux; - - - std::unique_ptr<xAOD::JetContainer> m_goodJets; - std::unique_ptr<xAOD::JetAuxContainer> m_goodJetsAux; + bool active() const {return m_active;} + protected: + bool loadDressedLeptons(const xAOD::TruthParticleContainer& input, + std::unique_ptr<xAOD::TruthParticleContainer>& store, + std::unique_ptr<xAOD::ShallowAuxContainer>& storeAux) const; + + bool isDressingPhoton(const xAOD::TruthParticle& photon, + const xAOD::TruthParticleContainer& dressedParticles, + const float dressingCone = 0.1) const; + private: + // The global config object + const std::shared_ptr<top::TopConfig>& m_config; + + // The tools used for electron, muon, and jet object selection. The + // basic idea is to allow exchanging these tools for custom ones, + // however, this is not implemented (yet). + std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Electron; + std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Muon; + std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Photon; + std::unique_ptr<ObjectSelectorBase<xAOD::Jet> > m_objectSelector_Jet; + std::unique_ptr<ObjectSelectorBase<xAOD::Jet> > m_objectSelector_LargeRJet; + std::unique_ptr<ObjectSelectorBase<xAOD::TruthParticle> > m_objectSelector_Tau; + std::unique_ptr<ParticleLevelRCJetObjectLoader> m_particleLevelRCJetObjectLoader; + std::map<std::string, std::unique_ptr<ParticleLevelRCJetObjectLoader> > m_particleLevelVarRCJetObjectLoader; + std::vector<std::string> m_VarRCJetRho; + std::vector<std::string> m_VarRCJetMassScale; + private: + // The dressed leptons (shallow copies of the input containers) + std::unique_ptr<xAOD::TruthParticleContainer> m_electronsDressed; + std::unique_ptr<xAOD::ShallowAuxContainer> m_electronsDressedAux; + + std::unique_ptr<xAOD::TruthParticleContainer> m_muonsDressed; + std::unique_ptr<xAOD::ShallowAuxContainer> m_muonsDressedAux; + + std::unique_ptr<xAOD::TruthParticleContainer> m_goodElectrons; + std::unique_ptr<xAOD::TruthParticleAuxContainer> m_goodElectronsAux; + + std::unique_ptr<xAOD::TruthParticleContainer> m_goodMuons; + std::unique_ptr<xAOD::TruthParticleAuxContainer> m_goodMuonsAux; + + std::unique_ptr<xAOD::TruthParticleContainer> m_goodSoftMuons; + std::unique_ptr<xAOD::TruthParticleAuxContainer> m_goodSoftMuonsAux; + + std::unique_ptr<xAOD::TruthParticleContainer> m_goodPhotons; + std::unique_ptr<xAOD::TruthParticleAuxContainer> m_goodPhotonsAux; + + std::unique_ptr<xAOD::JetContainer> m_goodJets; + std::unique_ptr<xAOD::JetAuxContainer> m_goodJetsAux; std::unique_ptr<xAOD::JetContainer> m_goodLargeRJets; - std::unique_ptr<xAOD::JetAuxContainer> m_goodLargeRJetsAux; + std::unique_ptr<xAOD::JetAuxContainer> m_goodLargeRJetsAux; - // Flag denoting whether the loader tool is active. Will be set by the - // constructor and remains unchanged afterwards. - const bool m_active; - }; + std::unique_ptr<xAOD::TruthParticleContainer> m_goodTaus; + std::unique_ptr<xAOD::TruthParticleAuxContainer> m_goodTausAux; + // Flag denoting whether the loader tool is active. Will be set by the + // constructor and remains unchanged afterwards. + const bool m_active; + }; } #endif /* _TOP_PARTICLELEVEL_EVENTLOADER_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelMuonObjectSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelMuonObjectSelector.h index 4e579bec8394..5abbad3ea4be 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelMuonObjectSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelMuonObjectSelector.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelMuonObjectSelector.h // Description: @@ -15,35 +15,33 @@ #include "xAODTruth/TruthParticleContainer.h" namespace top { - - class ParticleLevelMuonObjectSelector - : public ObjectSelectorBase<xAOD::TruthParticle> { - public: - // Struct used to store the cut values used by the object selector. It - // is important that the object has a sensible default config because it - // will be default constructed for the trivial constructor of the object - // selector. - struct Options { - Options( double ptMin = 25.e3, - double etaMax = 2.5, - bool notFromHadron = true, - bool tauIsHadron = false ) : - pt_min( ptMin ), - eta_max( etaMax ), - not_from_hadron( notFromHadron ), - tau_is_hadron( tauIsHadron ){} - double pt_min; - double eta_max; - bool not_from_hadron; - bool tau_is_hadron; - }; - public: - ParticleLevelMuonObjectSelector( Options opt = Options() ); - virtual bool apply( const xAOD::TruthParticle & truthParticle ); - private: - Options m_opt; + class ParticleLevelMuonObjectSelector + : public ObjectSelectorBase<xAOD::TruthParticle> { + public: + // Struct used to store the cut values used by the object selector. It + // is important that the object has a sensible default config because it + // will be default constructed for the trivial constructor of the object + // selector. + struct Options { + Options(double ptMin = 25.e3, + double etaMax = 2.5, + bool notFromHadron = true, + bool tauIsHadron = false) : + pt_min(ptMin), + eta_max(etaMax), + not_from_hadron(notFromHadron), + tau_is_hadron(tauIsHadron) {} + double pt_min; + double eta_max; + bool not_from_hadron; + bool tau_is_hadron; }; - + public: + ParticleLevelMuonObjectSelector(Options opt = Options()); + virtual bool apply(const xAOD::TruthParticle& truthParticle); + private: + Options m_opt; + }; } #endif /* _TOP_PARTICLE_LEVEL_MUONOBJECTSELECTOR_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelPhotonObjectSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelPhotonObjectSelector.h index 53b976ebf5a0..f8e4b190d4cf 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelPhotonObjectSelector.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelPhotonObjectSelector.h @@ -1,20 +1,11 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // Filename: ParticleLevelPhotonObjectSelector.h // Description: // Author: Fabian Wilk // Created: Wed Oct 12 11:37:51 2016 -// -// (c) by The ATLAS Collaboration -// by Fabian Wilk <mail@fabianwilk.de> -// -// This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 -// International License. -// -// You should have received a copy of the license along with this work. -// If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. #ifndef _TOP_PARTICLE_LEVEL_PHOTONOBJECTSELECTOR_H_ #define _TOP_PARTICLE_LEVEL_PHOTONOBJECTSELECTOR_H_ @@ -32,34 +23,31 @@ #include "TopEvent/EventTools.h" namespace top { - - class ParticleLevelPhotonObjectSelector - : public ObjectSelectorBase<xAOD::TruthParticle> { - public: - // Struct used to store the cut values used by the object selector. It - // is important that the object has a sensible default config because it - // will be default constructed for the trivial constructor of the object - // selector. - struct Options { - Options(double ptMin = 25.e3, - double etaMax = 2.5, - const std::string & Origin = "", - const std::string & Isolation = ""); - - double pt_min; - double eta_max; - std::vector<MCTruthPartClassifier::ParticleOrigin> origin; - std::string isolationVar; - float isolationCut; - }; - - public: - ParticleLevelPhotonObjectSelector(Options cuts = Options()); - virtual bool apply(const xAOD::TruthParticle & truthParticle); - - private: - Options m_opt; + class ParticleLevelPhotonObjectSelector + : public ObjectSelectorBase<xAOD::TruthParticle> { + public: + // Struct used to store the cut values used by the object selector. It + // is important that the object has a sensible default config because it + // will be default constructed for the trivial constructor of the object + // selector. + struct Options { + Options(double ptMin = 25.e3, + double etaMax = 2.5, + const std::string& Origin = "", + const std::string& Isolation = ""); + + double pt_min; + double eta_max; + std::vector<MCTruthPartClassifier::ParticleOrigin> origin; + std::string isolationVar; + float isolationCut; }; + public: + ParticleLevelPhotonObjectSelector(Options cuts = Options()); + virtual bool apply(const xAOD::TruthParticle& truthParticle); + private: + Options m_opt; + }; } #endif /* _TOP_PARTICLE_LEVEL_PHOTONOBJECTSELECTOR_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelRCJetObjectLoader.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelRCJetObjectLoader.h new file mode 100644 index 000000000000..970a9348f41e --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelRCJetObjectLoader.h @@ -0,0 +1,139 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +//Load the reclustering tool for the collection of truth jets already selected. +//Create the collection of reclustered jets and save them in the evtStore(). +//There is also the pass selection to apply the cut on eta and pt on the reclustered jets. + +#ifndef ParticleLevelRCJetObjectLoader_H_ +#define ParticleLevelRCJetObjectLoader_H_ + +#include "TopParticleLevel/ObjectSelectorBase.h" +#include "AsgTools/AsgTool.h" +#include "xAODCore/ShallowCopy.h" + +#include "xAODRootAccess/TEvent.h" +#include "xAODRootAccess/TStore.h" +#include "xAODRootAccess/TActiveStore.h" + +#include "xAODJet/JetContainer.h" +#include "xAODJet/JetAuxContainer.h" +#include "JetReclustering/JetReclusteringTool.h" + +#include <unordered_map> +#include <unordered_set> +#include <memory> +#include <set> +#include <list> +#include <vector> + + +namespace top { + class ParticleLevelEvent; + class TopConfig; +} + +namespace fastjet { + class JetDefinition; + namespace contrib { + class Nsubjettiness; + class EnergyCorrelator; + } +} +namespace JetSubStructureUtils { + class KtSplittingScale; + class Qw; + class EnergyCorrelatorGeneralized; +} + + +class ParticleLevelRCJetObjectLoader: public asg::AsgTool { +public: + //Default - so root can load based on a name + ParticleLevelRCJetObjectLoader(const std::shared_ptr<top::TopConfig>& cfg); + + + //Default - so we can clean up + ~ParticleLevelRCJetObjectLoader(); + + //Run once at the start of the job + StatusCode initialize(); + + //Run for every event (in every systematic) that needs saving + StatusCode execute(const top::ParticleLevelEvent& plEvent); + + + //Clean-up remaining things + StatusCode finalize(); + + bool passSelection(const xAOD::Jet& jet) const; + + //Access all of the container names from the Event Saver + std::string inputContainerName() {return m_InputJetContainer;}; + std::string rcjetContainerName() {return m_OutputJetContainer;}; +private: + std::string m_name; + const std::shared_ptr<top::TopConfig>& m_config; + + bool m_VarRCjets; + std::string m_VarRCjets_rho; + std::string m_VarRCjets_mass_scale; + + float m_ptcut; // in GeV + float m_etamax; + float m_inputJetPtMin; + float m_inputJetEtaMax; + float m_trim; + float m_radius; + float m_minradius; + float m_massscale; + + bool m_useJSS; + bool m_useAdditionalJSS; + + std::string m_treeName; + + std::string m_InJetContainerBase; + std::string m_OutJetContainerBase; + std::string m_InputJetContainer; + std::string m_OutputJetContainer; + + + + + //Substructure tool definitions + std::shared_ptr<fastjet::JetDefinition> m_jet_def_rebuild; + std::shared_ptr<fastjet::contrib::Nsubjettiness> m_nSub1_beta1; + std::shared_ptr<fastjet::contrib::Nsubjettiness> m_nSub2_beta1; + std::shared_ptr<fastjet::contrib::Nsubjettiness> m_nSub3_beta1; + std::shared_ptr<fastjet::contrib::EnergyCorrelator> m_ECF1; + std::shared_ptr<fastjet::contrib::EnergyCorrelator> m_ECF2; + std::shared_ptr<fastjet::contrib::EnergyCorrelator> m_ECF3; + std::shared_ptr<JetSubStructureUtils::KtSplittingScale> m_split12; + std::shared_ptr<JetSubStructureUtils::KtSplittingScale> m_split23; + std::shared_ptr<JetSubStructureUtils::Qw> m_qw; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF332; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF461; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF322; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF331; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF422; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF441; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF212; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF321; + std::shared_ptr<JetSubStructureUtils::EnergyCorrelatorGeneralized> m_gECF311; + + std::map<std::string, float> mass_scales = { + {"m_t", 172500.}, + {"m_w", 80385.}, + {"m_z", 91188.}, + {"m_h", 125090.} + }; + + + //re-clustered jets + // -> need unordered map for systematics + std::shared_ptr<JetReclusteringTool> m_jetReclusteringTool; +}; + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelTauObjectSelector.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelTauObjectSelector.h new file mode 100644 index 000000000000..1cd147e972d4 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/ParticleLevelTauObjectSelector.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef _TOP_PARTICLE_LEVEL_TAUOBJECTSELECTOR_H_ +#define _TOP_PARTICLE_LEVEL_TAUOBJECTSELECTOR_H_ + +#include "TopParticleLevel/ObjectSelectorBase.h" + +#include "xAODTruth/TruthParticleContainer.h" + +namespace top { + class ParticleLevelTauObjectSelector + : public ObjectSelectorBase<xAOD::TruthParticle> { + public: + // Struct used to store the cut values used by the object selector. It + // is important that the object has a sensible default config because it + // will be default constructed for the trivial constructor of the object + // selector. + struct Options { + Options(double ptMin = 25.e3, + double etaMax = 2.5) : + pt_min(ptMin), + eta_max(etaMax) {} + double pt_min; + double eta_max; + }; + public: + ParticleLevelTauObjectSelector(Options opt = Options()); + virtual bool apply(const xAOD::TruthParticle& truthParticle); + private: + Options m_opt; + }; +} + +#endif /* _TOP_PARTICLE_LEVEL_TAUOBJECTSELECTOR_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/TruthTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/TruthTools.h index 0d04a51886cf..9377bbb3ebf4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/TruthTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/TopParticleLevel/TruthTools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // Filename: TruthTools.h // Description: @@ -15,165 +15,209 @@ #include <string> #include "xAODTruth/TruthParticleContainer.h" +#include "xAODMuon/MuonContainer.h" +#include "TopEvent/EventTools.h" +#include "TopDataPreparation/SampleXsection.h" +#include "xAODBase/IParticle.h" namespace top { - namespace truth { + namespace truth { + //Functions to decorate a muon with information on its truth-origin. Particle-level origin added on softmuons if config options SoftMuonAdditionalTruthInfo is True. + //Its output should be regarded as experimental and thoroughly tested by analyzers before officially including it in the analysis. + //It is strongly suggested to check its output against the true_origin (calculated by the MCTruthClassifier) to ensure behaviour is as expected. + //Parton-level added if SoftMuonAdditionalTruthInfo is True and SoftMuonAdditionalTruthInfoCheckPartonOrigin is True. + //Parton-level currently only usable on pythia8 and herwig7, will be automatically disabled for other PS generators. + //Some decorations are already written in the default output ntuple, check EventSaverFlatNtuple.cxx + //Some other are available for usage in custom savers: + //<const xAOD::TruthParticle*>("truthMuonLink") -> link to the truth muon associated with reco (can be null if not found) + //<top::LepParticleOriginFlag>("LepParticleOriginFlag") -> flag defined in TopEvent/EventTools.h + //<top::LepPartonOriginFlag>("LepPartonOriginFlag") -> flag defined in TopEvent/EventTools.h + //Then several <const xAOD::TruthParticle*>(...) decorations are also added (pointers are 0 when corresponding particle is not available): + //truthMotherLink -> first direct mother of the truth muon + //truthFirstNonLeptonMotherLink -> self-explanatory, will be different from truthMotherLink if the muon is from a Tau + //truthBMotherLink -> first B-hadron encountered when going back through the chain of ancestors + //truthCMotherLink -> first C-hadron encountered when going back through the chain of ancestors + //The following are added when using the parton-level flag + //truthPartonMotherLink -> link to first b/c quark encountered when going back through the chain of ancestors for muons from Heavy Flavour hadrons decays + //truthTopMotherLink, truthWMotherLink, truthZMotherLink, truthPhotonMotherLink, truthHiggsMotherLink, truthBSMMotherLink -> link to first Top/W/Z/gamma*/Higgs/BSM-particle encountered when going back through the chain of ancestors - /*! - * @brief Prints the decay chain leading up to a certain particle to a - * std::ostream. - * @param part Pointer to xAOD::TruthParticle whose decay origin shall - * be printed. - * @param os The std::ostream into which the decay chain shall be - * printed. Defaults to std::cout. - * @param prefix A string which will be prefixed to the output. - */ - void printDecayChain( const xAOD::TruthParticle * part, - std::ostream & os = std::cout, - const std::string & prefix = "" ); + void getTruthMuonHistory(const xAOD::TruthParticle* truth_muon, bool doPartonHistory, SampleXsection::showering shAlgo, bool verbose=false); + void getTruthMuonPartonHistory(const xAOD::TruthParticle* truthmu, top::LepParticleOriginFlag lepParticleOriginFlag, const xAOD::TruthParticle* truthmu_Bmother, const xAOD::TruthParticle* truthmu_Cmother, const xAOD::TruthParticle* truthmu_firstNonLeptonMother, SampleXsection::showering shAlgo, bool verbose=false); + //helper methods + top::LepParticleOriginFlag getTruthMuonFromTauHistory(const xAOD::TruthParticle* tauMother, const xAOD::TruthParticle* &truthmu_Bmother, const xAOD::TruthParticle* &truthmu_Cmother, const xAOD::TruthParticle* &truthmu_firstNonLeptonMother, bool verbose=false); + top::LepParticleOriginFlag getTruthMuonFromCharmHistory(const xAOD::TruthParticle* &truthmu_Bmother, const xAOD::TruthParticle* truthmu_Cmother, bool verbose=false); + + //function that gets the truth muon associated from a reco muon, runs getTruthMuonHistory on it, and then takes care of propagating the decorations + void getRecoMuonHistory(const xAOD::Muon* muon, bool doPartonHistory, SampleXsection::showering shAlgo, bool verbose=false); + + //helper methods + const xAOD::TruthParticle* getInitialStateParticle(const xAOD::TruthParticle* truthParticle, bool verbose=false); + const xAOD::TruthParticle* getFirstHFHadronOfSameFlavour(const xAOD::TruthParticle* truthParticle, bool verbose=false); + const xAOD::TruthParticle* getTruthMuonAssociatedToRecoMuon(const xAOD::Muon* muon); + //to initialize correctly all decorations to default values + void initTruthMuonHistoryInfo(const xAOD::TruthParticle* truth_muon, bool doPartonHistory); + void initRecoMuonHistoryInfo(const xAOD::Muon* muon, bool doPartonHistory); + //additional method to share common code between the two methods above + void initCommonMuonHistoryInfo(const xAOD::IParticle* muon, bool doPartonHistory); + //helper methods to copy info from one muon to another + void copyTruthMuonHistoryInfo(const xAOD::TruthParticle* tm_origin, const xAOD::TruthParticle* tm_target); + void copyRecoMuonHistoryInfo(const xAOD::Muon* m_origin, const xAOD::Muon* m_target); + //additional method to share common code between the two methods above + void copyCommonMuonHistoryInfo(const xAOD::IParticle* m_origin, const xAOD::IParticle* m_target); + + /*! + * @brief Prints the decay chain leading up to a certain particle to a + * std::ostream. + * @param part Pointer to xAOD::TruthParticle whose decay origin shall + * be printed. + * @param os The std::ostream into which the decay chain shall be + * printed. Defaults to std::cout. + * @param prefix A string which will be prefixed to the output. + */ + void printDecayChain(const xAOD::TruthParticle* part, + std::ostream& os = std::cout, + const std::string& prefix = ""); - /** - * @brief Check if a certain pdg ID corresponds to a B hadron. - * This follows the official PDG Monte-Carlo numbering scheme - * (c.f. http://pdg.lbl.gov/2007/reviews/montecarlorpp.pdf) which defines - * the PDG ID to be a 7 digit number in the form - * +- n_r n_L n_q1 n_q2 n_q3 n_J - * where - * n_q1 = 0, n_q2 >= n_q3 (for mesons) - * n_q1 >= n_q2 >= n_q3 (for baryons) - * n_q1 >= n_q2, n_q3 = 0 (for diquarks) - * the n_qi denote the flavour of the quark composing the hadron, i.e. - * n_q = 1 -> d n_q = 2 -> u - * n_q = 3 -> s n_q = 4 -> 4 - * n_q = 5 -> b - * The digit \f$n_J\f$ encodes the total angular momentum \f$J\f$ of a - * compound system. \f$n_L\f$ is used to distinguish compound objects which - * have the same total angular momentum but different spin (\f$S\f$) and orbital - * (\f$L\f$) angular momentum numbers. Finally, \f$n_r\f$ is used to label - * mesons which are radially exited. - * - * @param pdgId The PDG ID to test. - * - * @return True if pdg ID corresponds to B hadron, false otherwise. - */ - inline bool isBHadron( int pdgId ){ - return ( ( 510 < pdgId && pdgId < 555 ) || // Check for (normal) Mesons / Diquarks - ( 5100 < pdgId && pdgId < 5555 ) || // Check for (normal) Baryons - ( pdgId / 100 ) % 10 == 5 || // Check exited Mesons (and Baryons with double beauty) - ( pdgId / 1000 ) % 10 == 5 ); // Check exited Baryons - } - - - /** - * @brief Function to determine whether the input particle was produced - * in the physical decay of a particle of given PDG ID. - * - * The algorithm uses the MC Truth Record. - * The algorithm works by ascending through the decay chain following - * the production vertex reference (obtained by the prodVtx() member - * function of the xAOD::TruthParticle). From the input particle, the - * algorithm ascends through the chain until the PDG ID of the particle - * found as first incoming particle is not equal to the PDG ID of the - * input particle. The last production vertex found during this ascent - * should then correspond to the physical production vertex of the input - * particle. - * - * @param truthParticle The input particle. - * @param parentPDGIds A list of PDG IDs which are valid parents - * @param bOnlyDirect A flag denoting whether "chained matching" is - * allowed. In chained matching mode, intermittend particles are - * allowed, i.e. for the chain - * A -> B -> C - * isFrom( C, A ) is true (for A != B != C). If only direct decays are - * considered, this is only the case if A == B or B == C. Defaults to false. - * - * @return Return true if the input particle was produced in the decay - * of a particle which has a PDG ID that is listed in - * parentPDGIds. Return false otherwise. Also return false if - * the input particle has an invalid production vertex reference. - */ - bool isFrom( const xAOD::TruthParticle * truthParticle, - const std::vector<int> & parentPDGIds, - bool bOnlyDirect = false ); - - /** - * @brief Function to determine whether a given truth particle is a - * result of a decay chain that started in the decay of a W or Z boson. - * - * The algorithm works by ascending through the decay chain following - * the production vertex reference (obtained by the prodVtx() member - * function of the xAOD::TruthParticle). From the input particle, the - * algorithm ascends through the chain until the PDG ID of the particle - * found as first incoming particle is not equal to the PDG ID of the - * input particle. The last production vertex found during this ascent - * should then correspond to the physical production vertex of the input - * particle. - * - * If the PDG ID of the mother particle (i.e. the incoming particle to - * the truth decay vertex) corresponds to a W / Z boson the algorithm - * terminates directly, returning true. Otherwise a vertex-based check - * is employed (which was designed to operate on SHERPA samples, c.f. - * the JetSimTools-00-02-09 package - * [svn: /Reconstruction/Jet/JetSimTools]). - * - * @param truthParticle The input particle. - * @param bOnlyDirect A flag denoting whether "chained matching" is - * allowed. In chained matching mode, intermittend particles are - * allowed, i.e. for the chain - * A -> B -> C - * isFrom( C, A ) is true (for A != B != C). If only direct decays are - * considered, this is only the case if A == B or B == C. Defaults to false. - * - * @return Return true if the input particle was created in a physical - * decay of a W or Z boson. Otherwise return false. Will also - * return false if the prduction vertex of the input particle is - * invalid or has zero incoming particles. - */ - bool isFromWZDecay( const xAOD::TruthParticle * truthParticle, - bool bOnlyDirect = false ); + /** + * @brief Check if a certain pdg ID corresponds to a B hadron. + * This follows the official PDG Monte-Carlo numbering scheme + * (c.f. http://pdg.lbl.gov/2007/reviews/montecarlorpp.pdf) which defines + * the PDG ID to be a 7 digit number in the form + * +- n_r n_L n_q1 n_q2 n_q3 n_J + * where + * n_q1 = 0, n_q2 >= n_q3 (for mesons) + * n_q1 >= n_q2 >= n_q3 (for baryons) + * n_q1 >= n_q2, n_q3 = 0 (for diquarks) + * the n_qi denote the flavour of the quark composing the hadron, i.e. + * n_q = 1 -> d n_q = 2 -> u + * n_q = 3 -> s n_q = 4 -> 4 + * n_q = 5 -> b + * The digit \f$n_J\f$ encodes the total angular momentum \f$J\f$ of a + * compound system. \f$n_L\f$ is used to distinguish compound objects which + * have the same total angular momentum but different spin (\f$S\f$) and orbital + * (\f$L\f$) angular momentum numbers. Finally, \f$n_r\f$ is used to label + * mesons which are radially exited. + * + * @param pdgId The PDG ID to test. + * + * @return True if pdg ID corresponds to B hadron, false otherwise. + */ + inline bool isBHadron(int pdgId) { + return((510 < pdgId && pdgId < 555) || // Check for (normal) Mesons / Diquarks + (5100 < pdgId && pdgId < 5555) ||// Check for (normal) Baryons + (pdgId / 100) % 10 == 5 || // Check exited Mesons (and Baryons with double beauty) + (pdgId / 1000) % 10 == 5); // Check exited Baryons + } - /** - * @brief Function the check if a particle is a lepton which was - * produced in the decay of a tau lepton. - * - * @param truthParticle The input truth particle which will be checked. - * - * @return True if the input particle is a lepton and it has a parent - * which was a tau. False otherwise. Will also return false if - * the production vertex of the input particle is invalid. - */ - bool isLeptonFromTau( const xAOD::TruthParticle * truthParticle ); + /** + * @brief Function to determine whether the input particle was produced + * in the physical decay of a particle of given PDG ID. + * + * The algorithm uses the MC Truth Record. + * The algorithm works by ascending through the decay chain following + * the production vertex reference (obtained by the prodVtx() member + * function of the xAOD::TruthParticle). From the input particle, the + * algorithm ascends through the chain until the PDG ID of the particle + * found as first incoming particle is not equal to the PDG ID of the + * input particle. The last production vertex found during this ascent + * should then correspond to the physical production vertex of the input + * particle. + * + * @param truthParticle The input particle. + * @param parentPDGIds A list of PDG IDs which are valid parents + * @param bOnlyDirect A flag denoting whether "chained matching" is + * allowed. In chained matching mode, intermittend particles are + * allowed, i.e. for the chain + * A -> B -> C + * isFrom( C, A ) is true (for A != B != C). If only direct decays are + * considered, this is only the case if A == B or B == C. Defaults to false. + * + * @return Return true if the input particle was produced in the decay + * of a particle which has a PDG ID that is listed in + * parentPDGIds. Return false otherwise. Also return false if + * the input particle has an invalid production vertex reference. + */ + bool isFrom(const xAOD::TruthParticle* truthParticle, + const std::vector<int>& parentPDGIds, + bool bOnlyDirect = false); - /** - * @brief Check whether a given truth particle is a lepton. - * @param truthParticle The input truth particle to be tested. - * @return Return true if input is a lepton, false otherwise. - */ - inline bool isLepton( const xAOD::TruthParticle * truthParticle ){ - return ( 10 < truthParticle->absPdgId() && truthParticle->absPdgId() < 17 ); - } + /** + * @brief Function to determine whether a given truth particle is a + * result of a decay chain that started in the decay of a W or Z boson. + * + * The algorithm works by ascending through the decay chain following + * the production vertex reference (obtained by the prodVtx() member + * function of the xAOD::TruthParticle). From the input particle, the + * algorithm ascends through the chain until the PDG ID of the particle + * found as first incoming particle is not equal to the PDG ID of the + * input particle. The last production vertex found during this ascent + * should then correspond to the physical production vertex of the input + * particle. + * + * If the PDG ID of the mother particle (i.e. the incoming particle to + * the truth decay vertex) corresponds to a W / Z boson the algorithm + * terminates directly, returning true. Otherwise a vertex-based check + * is employed (which was designed to operate on SHERPA samples, c.f. + * the JetSimTools-00-02-09 package + * [svn: /Reconstruction/Jet/JetSimTools]). + * + * @param truthParticle The input particle. + * @param bOnlyDirect A flag denoting whether "chained matching" is + * allowed. In chained matching mode, intermittend particles are + * allowed, i.e. for the chain + * A -> B -> C + * isFrom( C, A ) is true (for A != B != C). If only direct decays are + * considered, this is only the case if A == B or B == C. Defaults to false. + * + * @return Return true if the input particle was created in a physical + * decay of a W or Z boson. Otherwise return false. Will also + * return false if the prduction vertex of the input particle is + * invalid or has zero incoming particles. + */ + bool isFromWZDecay(const xAOD::TruthParticle* truthParticle, + bool bOnlyDirect = false); - /*! - * @brief Check whether a given truth particle is not produced in the - * decay of physical hadrons or their descendents. This must be done in - * a recursive manner, i.e. the decay chain must be traversed upwards - * until the initial state is found. - * @param truthParticle The truth particle to be tested. - * @param bOnlyDirect A flag denoting whether "chained matching" is - * allowed. In chained matching mode, intermittend particles are - * allowed, i.e. for the chain - * A -> B -> C - * isFrom( C, A ) is true (for A != B != C). If only direct decays are - * considered, this is only the case if A == B or B == C. Defaults to - * false. - * @param bTauIsHadron If true, any intermediate tauons are treated as hadrons. - * @return True if truthParticle does not descend from a physical - * hadron, false otherwise. - */ - bool isNotFromHadron( const xAOD::TruthParticle * truthParticle, - bool bOnlyDirect = false, bool bTauIsHadron = false ); + /** + * @brief Function the check if a particle is a lepton which was + * produced in the decay of a tau lepton. + * + * @param truthParticle The input truth particle which will be checked. + * + * @return True if the input particle is a lepton and it has a parent + * which was a tau. False otherwise. Will also return false if + * the production vertex of the input particle is invalid. + */ + bool isLeptonFromTau(const xAOD::TruthParticle* truthParticle); + /** + * @brief Check whether a given truth particle is a lepton. + * @param truthParticle The input truth particle to be tested. + * @return Return true if input is a lepton, false otherwise. + */ + inline bool isLepton(const xAOD::TruthParticle* truthParticle) { + return(10 < truthParticle->absPdgId() && truthParticle->absPdgId() < 17); } + + /*! + * @brief Check whether a given truth particle is not produced in the + * decay of physical hadrons or their descendents. This must be done in + * a recursive manner, i.e. the decay chain must be traversed upwards + * until the initial state is found. + * @param truthParticle The truth particle to be tested. + * @param bOnlyDirect A flag denoting whether "chained matching" is + * allowed. In chained matching mode, intermittend particles are + * allowed, i.e. for the chain + * A -> B -> C + * isFrom( C, A ) is true (for A != B != C). If only direct decays are + * considered, this is only the case if A == B or B == C. Defaults to + * false. + * @param bTauIsHadron If true, any intermediate tauons are treated as hadrons. + * @return True if truthParticle does not descend from a physical + * hadron, false otherwise. + */ + bool isNotFromHadron(const xAOD::TruthParticle* truthParticle, + bool bOnlyDirect = false, bool bTauIsHadron = false); + } } #endif /* _TOP_PARTICLE_LEVEL_TRUTHTOOLS_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt index e39ada9b15a4..6ca87a659784 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt @@ -1,6 +1,7 @@ +# Auto-generated on: 2017-03-08 14:47:38.930377 # Declare the name of this package: -atlas_subdir( TopPartons ) +atlas_subdir( TopPartons None ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -14,10 +15,13 @@ atlas_depends_on_subdirs( PUBLIC # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore TMVA Graf ) +# Custom definitions needed for this package: +add_definitions( -g ) + # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopPartons _cintDictSource - ROOT_HEADERS TopPartons/PartonHistory.h Root/LinkDef.h - EXTERNAL_PACKAGES ROOT ) + ROOT_HEADERS Root/LinkDef.h + EXTERNAL_PACKAGES ROOT ) # Build a library that other components can link against: atlas_add_library( TopPartons Root/*.cxx Root/*.h Root/*.icc diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTTZPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTTZPartonHistory.cxx new file mode 100644 index 000000000000..744ce9d35cd6 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTTZPartonHistory.cxx @@ -0,0 +1,197 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopPartons/CalcTTZPartonHistory.h" +#include "TopConfiguration/TopConfig.h" +#include "TopPartons/PartonHistoryUtils.h" + +namespace top { + CalcTTZPartonHistory::CalcTTZPartonHistory(const std::string& name) : CalcTtbarPartonHistory(name) {} + + void CalcTTZPartonHistory::zHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* ttbarPartonHistory) { + ttbarPartonHistory->IniVarZ(); + + TLorentzVector Z; + TLorentzVector ZDecay1; + TLorentzVector ZDecay2; + int ZDecay1_pdgId; + int ZDecay2_pdgId; + bool is_on_shell; + bool event_has_Z = CalcTTZPartonHistory::getZ(truthParticles, + &Z, + &ZDecay1, + &ZDecay1_pdgId, + &ZDecay2, + &ZDecay2_pdgId, + &is_on_shell); + + if (event_has_Z && !m_ancestry_corrupted) { + ttbarPartonHistory->auxdecor< float >("MC_Z_m") = Z.M(); + ttbarPartonHistory->auxdecor< float >("MC_Z_pt") = Z.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Z_eta") = Z.Eta(); + ttbarPartonHistory->auxdecor< float >("MC_Z_phi") = Z.Phi(); + + ttbarPartonHistory->auxdecor< float >("MC_Zdecay1_m") = ZDecay1.M(); + ttbarPartonHistory->auxdecor< float >("MC_Zdecay1_pt") = ZDecay1.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Zdecay1_eta") = ZDecay1.Eta(); + ttbarPartonHistory->auxdecor< float >("MC_Zdecay1_phi") = ZDecay1.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Zdecay1_pdgId") = ZDecay1_pdgId; + + ttbarPartonHistory->auxdecor< float >("MC_Zdecay2_m") = ZDecay2.M(); + ttbarPartonHistory->auxdecor< float >("MC_Zdecay2_pt") = ZDecay2.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Zdecay2_eta") = ZDecay2.Eta(); + ttbarPartonHistory->auxdecor< float >("MC_Zdecay2_phi") = ZDecay2.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Zdecay2_pdgId") = ZDecay2_pdgId; + + ttbarPartonHistory->auxdecor< int >("MC_Z_IsOnShell") = static_cast<int>(is_on_shell); + } // if + + ttbarPartonHistory->auxdecor< int >("MC_Z_AncestryCorrupted") = static_cast<int>(m_ancestry_corrupted); + } + + bool CalcTTZPartonHistory::getZ(const xAOD::TruthParticleContainer* truthParticles, + TLorentzVector* Z_p4, + TLorentzVector* ZDecay1, + int* ZDecay1_pdgId, + TLorentzVector* ZDecay2, + int* ZDecay2_pdgId, + bool* is_on_shell) { + bool hasZ { + false + }; + bool hasZDecay1 { + false + }; + bool hasZDecay2 { + false + }; + + *is_on_shell = false; + m_ancestry_corrupted = false; + + // First check for real (on-shell) Z bosons in the truth record + // (PDG ID 23). Only consider Z bosons at the end of the chain + // of radiative corrections (i.e. a Z boson decaying into + // something else than a Z). + for (const auto& p : *truthParticles) { + if (!p->isZ()) continue; + if (PartonHistoryUtils::hasParticleIdenticalParent(p)) continue; + + const auto& z = PartonHistoryUtils::findAfterFSR(p); + *is_on_shell = true; + if (z->nChildren() != 2) continue; + + *Z_p4 = z->p4(); + hasZ = true; + + for (size_t i = 0; i < z->nChildren(); ++i) { + const auto& child = z->child(i); + if (!child) continue; + if (child->pdgId() > 0) { + *ZDecay1 = PartonHistoryUtils::findAfterFSR(child)->p4(); + *ZDecay1_pdgId = child->pdgId(); + hasZDecay1 = true; + } else { + *ZDecay2 = PartonHistoryUtils::findAfterFSR(child)->p4(); + *ZDecay2_pdgId = child->pdgId(); + hasZDecay2 = true; + } + } // for + } // for + + // Our job is done if the event has a real Z boson. + if (hasZ && (!hasZDecay1 || !hasZDecay2)) m_ancestry_corrupted = true; + if (hasZ) return hasZ && hasZDecay1 && hasZDecay2; + + // For off-shell Z bosons it's a bit more tricky. We now look + // for two same-flavour particles that are attached to the + // ttbar vertex. + for (const auto& p : *truthParticles) { + if (abs(p->pdgId()) > 19) continue; // Only elementary fermions + if (p->pdgId() < 0) continue; // No anti-particles (to avoid + // double-counting) + const auto& sibling = getFlavourSibling(p); + if (!sibling) continue; + + // Check whether the particle is attached to the ttbar vertex. + bool has_top_sibling { + false + }; + bool has_antitop_sibling { + false + }; + const auto& parent = p->parent(0); + if (!parent) continue; + for (size_t i = 0; i < parent->nChildren(); ++i) { + const auto* child = parent->child(i); + if (!child) continue; + if (child == p) continue; // Make sure we don't look at our candidate. + if (child->pdgId() == 6) has_top_sibling = true; + if (child->pdgId() == -6) has_antitop_sibling = true; + if (has_top_sibling && has_antitop_sibling) break; + } + if (!(has_top_sibling && has_antitop_sibling)) continue; + + *ZDecay1 = p->p4(); + *ZDecay1_pdgId = p->pdgId(); + hasZDecay1 = true; + *ZDecay2 = sibling->p4(); + *ZDecay2_pdgId = sibling->pdgId(); + hasZDecay2 = true; + + *Z_p4 = *ZDecay1 + *ZDecay2; + hasZ = true; + } // for + + if (hasZ && (!hasZDecay1 || !hasZDecay2)) m_ancestry_corrupted = true; + return hasZ && hasZDecay1 && hasZDecay2; + } + + const xAOD::TruthParticle* CalcTTZPartonHistory::getFlavourSibling(const xAOD::TruthParticle* particle) { + const auto& parent = particle->parent(0); + + if (!parent) return nullptr; + + for (size_t i = 0; i < parent->nChildren(); ++i) { + const auto& sibling_candidate = parent->child(i); + if (!sibling_candidate) continue; + if (sibling_candidate->pdgId() == -particle->pdgId()) { + return sibling_candidate; + } + } + return nullptr; + } + + StatusCode CalcTTZPartonHistory::execute() { + // Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* ttbarPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(ttbarPartonHistory); + + // Recover the parton history for ttbar events + ttbarHistorySaver(truthParticles, ttbarPartonHistory); + zHistorySaver(truthParticles, ttbarPartonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTbbarPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTbbarPartonHistory.cxx index 934af9122153..ea3121d9b2f7 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTbbarPartonHistory.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTbbarPartonHistory.cxx @@ -1,116 +1,114 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopPartons/CalcTbbarPartonHistory.h" #include "TopConfiguration/TopConfig.h" -namespace top{ - - CalcTbbarPartonHistory::CalcTbbarPartonHistory(const std::string& name) : CalcTopPartonHistory( name ){} - - void CalcTbbarPartonHistory::tbbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* tbbarPartonHistory){ - - tbbarPartonHistory->IniVarTbbar(); - - TLorentzVector t_before, t_after; - TLorentzVector Wp; - TLorentzVector b_from_top; - TLorentzVector WpDecay1; - TLorentzVector WpDecay2; - int WpDecay1_pdgId; - int WpDecay2_pdgId; - bool event_top = CalcTopPartonHistory::topWb(truthParticles, 6, t_before, t_after, Wp, b_from_top, WpDecay1, WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId); - if(!event_top)event_top = CalcTopPartonHistory::topWb(truthParticles, -6, t_before, t_after, Wp, b_from_top, WpDecay1, WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId); - - TLorentzVector b_beforeFSR; - TLorentzVector b_afterFSR; - bool event_b = CalcTopPartonHistory::b(truthParticles, b_beforeFSR, b_afterFSR); - - if (event_top && event_b){ - TLorentzVector temp = t_before+b_beforeFSR; - tbbarPartonHistory->auxdecor< float >( "MC_tbbar_beforeFSR_m" ) = temp.M(); - tbbarPartonHistory->auxdecor< float >( "MC_tbbar_beforeFSR_pt" ) = temp.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_tbbar_beforeFSR_phi" ) = temp.Phi(); - fillEtaBranch(tbbarPartonHistory,"MC_tbbar_beforeFSR_eta", temp); - - temp = WpDecay1+WpDecay2+b_from_top + b_afterFSR; - tbbarPartonHistory->auxdecor< float >( "MC_tbbar_afterFSR_m" ) = temp.M(); - tbbarPartonHistory->auxdecor< float >( "MC_tbbar_afterFSR_pt" ) = temp.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_tbbar_afterFSR_phi" ) = temp .Phi(); - fillEtaBranch(tbbarPartonHistory, "MC_tbbar_afterFSR_eta", temp); - }//if - if (event_top){ - tbbarPartonHistory->auxdecor< float >( "MC_t_beforeFSR_m" ) = t_before.M(); - tbbarPartonHistory->auxdecor< float >( "MC_t_beforeFSR_pt" ) = t_before.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_t_beforeFSR_phi" ) = t_before.Phi(); - fillEtaBranch(tbbarPartonHistory,"MC_t_beforeFSR_eta", t_before); - - tbbarPartonHistory->auxdecor< float >( "MC_W_from_t_m" ) = Wp.M(); - tbbarPartonHistory->auxdecor< float >( "MC_W_from_t_pt" ) = Wp.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_W_from_t_phi" ) = Wp.Phi(); - fillEtaBranch(tbbarPartonHistory, "MC_W_from_t_eta", Wp); - - tbbarPartonHistory->auxdecor< float >( "MC_b_from_t_m" ) = b_from_top.M(); - tbbarPartonHistory->auxdecor< float >( "MC_b_from_t_pt" ) = b_from_top.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_b_from_t_phi" ) = b_from_top.Phi(); - fillEtaBranch(tbbarPartonHistory,"MC_b_from_t_eta", b_from_top); - - tbbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_t_m" ) = WpDecay1.M(); - tbbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_t_pt" ) = WpDecay1.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_t_phi" ) = WpDecay1.Phi(); - tbbarPartonHistory->auxdecor< int >( "MC_Wdecay1_from_t_pdgId" ) = WpDecay1_pdgId; - fillEtaBranch(tbbarPartonHistory,"MC_Wdecay1_from_t_eta", WpDecay1); - - tbbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_t_m" ) = WpDecay2.M(); - tbbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_t_pt" ) = WpDecay2.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_t_phi" ) = WpDecay2.Phi(); - tbbarPartonHistory->auxdecor< int >( "MC_Wdecay2_from_t_pdgId" ) = WpDecay2_pdgId; - fillEtaBranch(tbbarPartonHistory,"MC_Wdecay2_from_t_eta", WpDecay2); - }//if - if (event_b){ - - tbbarPartonHistory->auxdecor< float >( "MC_b_beforeFSR_m" ) = b_beforeFSR.M(); - tbbarPartonHistory->auxdecor< float >( "MC_b_beforeFSR_pt" ) = b_beforeFSR.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_b_beforeFSR_phi" ) = b_beforeFSR.Phi(); - fillEtaBranch(tbbarPartonHistory,"MC_b_beforeFSR_eta", b_beforeFSR); - - tbbarPartonHistory->auxdecor< float >( "MC_b_afterFSR_m" ) = b_afterFSR.M(); - tbbarPartonHistory->auxdecor< float >( "MC_b_afterFSR_pt" ) = b_afterFSR.Pt(); - tbbarPartonHistory->auxdecor< float >( "MC_b_afterFSR_phi" ) = b_afterFSR.Phi(); - fillEtaBranch(tbbarPartonHistory,"MC_b_afterFSR_eta", b_afterFSR); - - }//if - +namespace top { + CalcTbbarPartonHistory::CalcTbbarPartonHistory(const std::string& name) : CalcTopPartonHistory(name) {} + + void CalcTbbarPartonHistory::tbbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* tbbarPartonHistory) { + tbbarPartonHistory->IniVarTbbar(); + + TLorentzVector t_before, t_after; + TLorentzVector Wp; + TLorentzVector b_from_top; + TLorentzVector WpDecay1; + TLorentzVector WpDecay2; + int WpDecay1_pdgId; + int WpDecay2_pdgId; + bool event_top = CalcTopPartonHistory::topWb(truthParticles, 6, t_before, t_after, Wp, b_from_top, WpDecay1, + WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId); + if (!event_top) event_top = CalcTopPartonHistory::topWb(truthParticles, -6, t_before, t_after, Wp, b_from_top, + WpDecay1, WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId); + + TLorentzVector b_beforeFSR; + TLorentzVector b_afterFSR; + bool event_b = CalcTopPartonHistory::b(truthParticles, b_beforeFSR, b_afterFSR); + + if (event_top && event_b) { + TLorentzVector temp = t_before + b_beforeFSR; + tbbarPartonHistory->auxdecor< float >("MC_tbbar_beforeFSR_m") = temp.M(); + tbbarPartonHistory->auxdecor< float >("MC_tbbar_beforeFSR_pt") = temp.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_tbbar_beforeFSR_phi") = temp.Phi(); + fillEtaBranch(tbbarPartonHistory, "MC_tbbar_beforeFSR_eta", temp); + + temp = WpDecay1 + WpDecay2 + b_from_top + b_afterFSR; + tbbarPartonHistory->auxdecor< float >("MC_tbbar_afterFSR_m") = temp.M(); + tbbarPartonHistory->auxdecor< float >("MC_tbbar_afterFSR_pt") = temp.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_tbbar_afterFSR_phi") = temp.Phi(); + fillEtaBranch(tbbarPartonHistory, "MC_tbbar_afterFSR_eta", temp); + }//if + if (event_top) { + tbbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_m") = t_before.M(); + tbbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_pt") = t_before.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_phi") = t_before.Phi(); + fillEtaBranch(tbbarPartonHistory, "MC_t_beforeFSR_eta", t_before); + + tbbarPartonHistory->auxdecor< float >("MC_W_from_t_m") = Wp.M(); + tbbarPartonHistory->auxdecor< float >("MC_W_from_t_pt") = Wp.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_W_from_t_phi") = Wp.Phi(); + fillEtaBranch(tbbarPartonHistory, "MC_W_from_t_eta", Wp); + + tbbarPartonHistory->auxdecor< float >("MC_b_from_t_m") = b_from_top.M(); + tbbarPartonHistory->auxdecor< float >("MC_b_from_t_pt") = b_from_top.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_b_from_t_phi") = b_from_top.Phi(); + fillEtaBranch(tbbarPartonHistory, "MC_b_from_t_eta", b_from_top); + + tbbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_m") = WpDecay1.M(); + tbbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_pt") = WpDecay1.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_phi") = WpDecay1.Phi(); + tbbarPartonHistory->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = WpDecay1_pdgId; + fillEtaBranch(tbbarPartonHistory, "MC_Wdecay1_from_t_eta", WpDecay1); + + tbbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_m") = WpDecay2.M(); + tbbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_pt") = WpDecay2.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_phi") = WpDecay2.Phi(); + tbbarPartonHistory->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = WpDecay2_pdgId; + fillEtaBranch(tbbarPartonHistory, "MC_Wdecay2_from_t_eta", WpDecay2); + }//if + if (event_b) { + tbbarPartonHistory->auxdecor< float >("MC_b_beforeFSR_m") = b_beforeFSR.M(); + tbbarPartonHistory->auxdecor< float >("MC_b_beforeFSR_pt") = b_beforeFSR.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_b_beforeFSR_phi") = b_beforeFSR.Phi(); + fillEtaBranch(tbbarPartonHistory, "MC_b_beforeFSR_eta", b_beforeFSR); + + tbbarPartonHistory->auxdecor< float >("MC_b_afterFSR_m") = b_afterFSR.M(); + tbbarPartonHistory->auxdecor< float >("MC_b_afterFSR_pt") = b_afterFSR.Pt(); + tbbarPartonHistory->auxdecor< float >("MC_b_afterFSR_phi") = b_afterFSR.Phi(); + fillEtaBranch(tbbarPartonHistory, "MC_b_afterFSR_eta", b_afterFSR); + }//if } - StatusCode CalcTbbarPartonHistory::execute() - { - // Get the Truth Particles - const xAOD::TruthParticleContainer* truthParticles(nullptr); - ATH_CHECK( evtStore()->retrieve( truthParticles , m_config->sgKeyMCParticle() ) ); - - // Create the partonHistory xAOD object - xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer{}; - xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer{}; - partonCont->setStore( partonAuxCont ); - - xAOD::PartonHistory* tbbarPartonHistory = new xAOD::PartonHistory{}; - partonCont->push_back( tbbarPartonHistory ); - - // Recover the parton history for tbbar events - tbbarHistorySaver(truthParticles, tbbarPartonHistory); - - // Save to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyTopPartonHistory(); - std::string outputSGKeyAux = outputSGKey + "Aux."; - - xAOD::TReturnCode save = evtStore()->tds()->record( partonCont , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( partonAuxCont , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } - - return StatusCode::SUCCESS; + StatusCode CalcTbbarPartonHistory::execute() { + // Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* tbbarPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(tbbarPartonHistory); + + // Recover the parton history for tbbar events + tbbarHistorySaver(truthParticles, tbbarPartonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcThqPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcThqPartonHistory.cxx new file mode 100644 index 000000000000..9b1a51ce9b14 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcThqPartonHistory.cxx @@ -0,0 +1,196 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopPartons/CalcThqPartonHistory.h" +#include "TopPartons/CalcTopPartonHistory.h" +#include "TopPartons/PartonHistoryUtils.h" +#include "TopConfiguration/TopConfig.h" + +namespace top { + CalcThqPartonHistory::CalcThqPartonHistory(const std::string& name) : CalcTopPartonHistory(name) {} + + bool CalcThqPartonHistory::HiggsAndDecay(const xAOD::TruthParticleContainer* truthParticles) { + + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle->pdgId() != 25 || particle->nChildren() != 2) { + continue; + } + tH.Higgs_p4 = particle->p4(); + + const top::PartonHistoryUtils::HiggsDecay& higgs = top::PartonHistoryUtils::AnalyzeHiggsDecay(particle); + + tH.decay1_p4 = higgs.decay1_vector; + tH.decay2_p4 = higgs.decay2_vector; + tH.decay1_pdgId = higgs.decay1_pdgId; + tH.decay2_pdgId = higgs.decay2_pdgId; + tH.tau_decay1_isHadronic = higgs.tau_decay1_isHadronic; + tH.tau_decay2_isHadronic = higgs.tau_decay2_isHadronic; + tH.decay1_from_decay1_p4 = higgs.decay1_from_decay1_vector; + tH.decay2_from_decay1_p4 = higgs.decay2_from_decay1_vector; + tH.decay1_from_decay1_pdgId = higgs.decay1_from_decay1_pdgId; + tH.decay2_from_decay1_pdgId = higgs.decay2_from_decay1_pdgId; + tH.decay1_from_decay2_p4 = higgs.decay1_from_decay2_vector; + tH.decay2_from_decay2_p4 = higgs.decay2_from_decay2_vector; + tH.decay1_from_decay2_pdgId = higgs.decay1_from_decay2_pdgId; + tH.decay2_from_decay2_pdgId = higgs.decay2_from_decay2_pdgId; + tH.tau_decay1_from_decay1_isHadronic = higgs.tau_decay1_from_decay1_isHadronic; + tH.tau_decay2_from_decay1_isHadronic = higgs.tau_decay2_from_decay1_isHadronic; + tH.tau_decay1_from_decay2_isHadronic = higgs.tau_decay1_from_decay2_isHadronic; + tH.tau_decay2_from_decay2_isHadronic = higgs.tau_decay2_from_decay2_isHadronic; + + return true; + } + return false; + } + + void CalcThqPartonHistory::THHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* ThqPartonHistory) { + ThqPartonHistory->IniVarThq(); + TLorentzVector t_before, t_after, t_after_SC; + TLorentzVector Wp; + TLorentzVector b; + TLorentzVector WpDecay1; + TLorentzVector WpDecay2; + int WpDecay1_pdgId; + int WpDecay2_pdgId; + + const bool event_top = CalcTopPartonHistory::topWb(truthParticles, 6, t_before, t_after, + Wp, b, WpDecay1, WpDecay1_pdgId, + WpDecay2, WpDecay2_pdgId); + const bool event_top_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, 6, t_after_SC); + const bool event_topbar = CalcTopPartonHistory::topWb(truthParticles, -6, t_before, t_after, + Wp, b, WpDecay1, + WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId); + const bool event_topbar_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, -6, t_after_SC); + const bool event_Higgs = CalcThqPartonHistory::HiggsAndDecay(truthParticles); + + if (event_Higgs) { + if (event_top || event_topbar) { + ThqPartonHistory->auxdecor< float >("MC_t_beforeFSR_m") = t_before.M(); + ThqPartonHistory->auxdecor< float >("MC_t_beforeFSR_pt") = t_before.Pt(); + ThqPartonHistory->auxdecor< float >("MC_t_beforeFSR_phi") = t_before.Phi(); + fillEtaBranch(ThqPartonHistory, "MC_t_beforeFSR_eta", t_before); + + ThqPartonHistory->auxdecor< float >("MC_t_afterFSR_m") = t_after.M(); + ThqPartonHistory->auxdecor< float >("MC_t_afterFSR_pt") = t_after.Pt(); + ThqPartonHistory->auxdecor< float >("MC_t_afterFSR_phi") = t_after.Phi(); + fillEtaBranch(ThqPartonHistory, "MC_t_afterFSR_eta", t_after); + + if (event_top_SC || event_topbar_SC) { + ThqPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_m") = t_after_SC.M(); + ThqPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_pt") = t_after_SC.Pt(); + ThqPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_phi") = t_after_SC.Phi(); + fillEtaBranch(ThqPartonHistory, "MC_t_afterFSR_SC_eta", t_after_SC); + } + + ThqPartonHistory->auxdecor< float >("MC_W_from_t_m") = Wp.M(); + ThqPartonHistory->auxdecor< float >("MC_W_from_t_pt") = Wp.Pt(); + ThqPartonHistory->auxdecor< float >("MC_W_from_t_phi") = Wp.Phi(); + fillEtaBranch(ThqPartonHistory, "MC_W_from_t_eta", Wp); + + ThqPartonHistory->auxdecor< float >("MC_b_from_t_m") = b.M(); + ThqPartonHistory->auxdecor< float >("MC_b_from_t_pt") = b.Pt(); + ThqPartonHistory->auxdecor< float >("MC_b_from_t_phi") = b.Phi(); + fillEtaBranch(ThqPartonHistory, "MC_b_from_t_eta", b); + + ThqPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_m") = WpDecay1.M(); + ThqPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_pt") = WpDecay1.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_phi") = WpDecay1.Phi(); + ThqPartonHistory->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = WpDecay1_pdgId; + fillEtaBranch(ThqPartonHistory, "MC_Wdecay1_from_t_eta", WpDecay1); + + ThqPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_m") = WpDecay2.M(); + ThqPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_pt") = WpDecay2.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_phi") = WpDecay2.Phi(); + ThqPartonHistory->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = WpDecay2_pdgId; + fillEtaBranch(ThqPartonHistory, "MC_Wdecay2_from_t_eta", WpDecay2); + + //Higgs-Variables + ThqPartonHistory->auxdecor< float >("MC_Higgs_m") = tH.Higgs_p4.M(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_pt") = tH.Higgs_p4.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_phi") = tH.Higgs_p4.Phi(); + fillEtaBranch(ThqPartonHistory, "MC_Higgs_eta", tH.Higgs_p4); + + //Higgs-decay1-Variables + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_m") = tH.decay1_p4.M(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_pt") = tH.decay1_p4.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_phi") = tH.decay1_p4.Phi(); + ThqPartonHistory->auxdecor< int >("MC_Higgs_decay1_pdgId") = tH.decay1_pdgId; + ThqPartonHistory->auxdecor< int >("MC_Higgs_tau_decay1_isHadronic") = tH.tau_decay1_isHadronic; + fillEtaBranch(ThqPartonHistory, "MC_Higgs_decay1_eta", tH.decay1_p4); + + //Higgs-decay2-Variables + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_m") = tH.decay2_p4.M(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_pt") = tH.decay2_p4.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_phi") = tH.decay2_p4.Phi(); + ThqPartonHistory->auxdecor< int >("MC_Higgs_decay2_pdgId") = tH.decay2_pdgId; + ThqPartonHistory->auxdecor< int >("MC_Higgs_tau_decay2_isHadronic") = tH.tau_decay1_isHadronic; + fillEtaBranch(ThqPartonHistory, "MC_Higgs_decay2_eta", tH.decay2_p4); + + //Higgs-decay1- from decay1-Variables + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_from_decay1_m") = tH.decay1_from_decay1_p4.M(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_from_decay1_pt") = tH.decay1_from_decay1_p4.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_from_decay1_phi") = tH.decay1_from_decay1_p4.Phi(); + ThqPartonHistory->auxdecor< int >("MC_Higgs_decay1_from_decay1_pdgId") = tH.decay1_from_decay1_pdgId; + ThqPartonHistory->auxdecor< int >("MC_Higgs_tau_decay1_from_decay1_isHadronic") = tH.tau_decay1_from_decay1_isHadronic; + fillEtaBranch(ThqPartonHistory, "MC_Higgs_decay1_from_decay1_eta", tH.decay1_from_decay1_p4); + + //Higgs-decay2- from decay1-Variables + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_from_decay1_m") = tH.decay2_from_decay1_p4.M(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_from_decay1_pt") = tH.decay2_from_decay1_p4.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_from_decay1_phi") = tH.decay2_from_decay1_p4.Phi(); + ThqPartonHistory->auxdecor< int >("MC_Higgs_decay2_from_decay1_pdgId") = tH.decay2_from_decay1_pdgId; + ThqPartonHistory->auxdecor< int >("MC_Higgs_tau_decay2_from_decay1_isHadronic") = tH.tau_decay2_from_decay1_isHadronic; + fillEtaBranch(ThqPartonHistory, "MC_Higgs_decay2_from_decay1_eta", tH.decay2_from_decay1_p4); + + //Higgs-decay1- from decay2-Variables + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_from_decay2_m") = tH.decay1_from_decay2_p4.M(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_from_decay2_pt") = tH.decay1_from_decay2_p4.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay1_from_decay2_phi") = tH.decay1_from_decay2_p4.Phi(); + ThqPartonHistory->auxdecor< int >("MC_Higgs_decay1_from_decay2_pdgId") = tH.decay1_from_decay2_pdgId; + ThqPartonHistory->auxdecor< int >("MC_Higgs_tau_decay1_from_decay2_isHadronic") = tH.tau_decay1_from_decay2_isHadronic; + fillEtaBranch(ThqPartonHistory, "MC_Higgs_decay1_from_decay2_eta", tH.decay1_from_decay2_p4); + + //Higgs-decay2- from decay2-Variables + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_from_decay2_m") = tH.decay2_from_decay2_p4.M(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_from_decay2_pt") = tH.decay2_from_decay2_p4.Pt(); + ThqPartonHistory->auxdecor< float >("MC_Higgs_decay2_from_decay2_phi") = tH.decay2_from_decay2_p4.Phi(); + ThqPartonHistory->auxdecor< int >("MC_Higgs_decay2_from_decay2_pdgId") = tH.decay2_from_decay2_pdgId; + ThqPartonHistory->auxdecor< int >("MC_Higgs_tau_decay2_from_decay2_isHadronic") = tH.tau_decay2_from_decay2_isHadronic; + fillEtaBranch(ThqPartonHistory, "MC_Higgs_decay2_from_decay2_eta", tH.decay2_from_decay2_p4); + + } + } + } + + StatusCode CalcThqPartonHistory::execute() { + //Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* ThqPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(ThqPartonHistory); + + // Recover the parton history for TH events + THHistorySaver(truthParticles, ThqPartonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTopPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTopPartonHistory.cxx index 9a1646a146a6..5b5b738f314a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTopPartonHistory.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTopPartonHistory.cxx @@ -1,28 +1,85 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ // $Id: CalcTopPartonHistory.cxx 800464 2017-03-13 18:06:24Z tpelzer $ #include "TopPartons/CalcTopPartonHistory.h" #include "TopPartons/PartonHistory.h" #include "TopConfiguration/TopConfig.h" #include "TopPartons/CalcTtbarPartonHistory.h" +#include "TopPartons/PartonHistoryUtils.h" #include "xAODTruth/TruthVertex.h" -namespace top{ +namespace top { + CalcTopPartonHistory::CalcTopPartonHistory(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr) { + declareProperty("config", m_config); + } + + StatusCode CalcTopPartonHistory::buildContainerFromMultipleCollections(const std::vector<std::string> &collections, const std::string& out_contName) + { + ConstDataVector<DataVector<xAOD::TruthParticle_v1> > *out_cont = new ConstDataVector<DataVector<xAOD::TruthParticle_v1> > (SG::VIEW_ELEMENTS); + + for(const std::string& collection : collections) + { + const xAOD::TruthParticleContainer* cont=nullptr; + ATH_CHECK(evtStore()->retrieve(cont,collection)); + for(const xAOD::TruthParticle* p : *cont) out_cont->push_back(p); + } + + //we give control of the container to the store, because in this way we are able to retrieve it as a const data vector, see https://twiki.cern.ch/twiki/bin/view/AtlasComputing/DataVector#ConstDataVector + xAOD::TReturnCode save = evtStore()->tds()->record(out_cont,out_contName); + if (!save) return StatusCode::FAILURE; + + return StatusCode::SUCCESS; + } - CalcTopPartonHistory::CalcTopPartonHistory( const std::string& name ) : - asg::AsgTool( name ), - m_config(nullptr) - { - declareProperty( "config" , m_config ); + StatusCode CalcTopPartonHistory::linkBosonCollections() + { + return decorateCollectionWithLinksToAnotherCollection("TruthBoson","TruthBosonsWithDecayParticles","AT_linkToTruthBosonsWithDecayParticles"); + } + StatusCode CalcTopPartonHistory::decorateCollectionWithLinksToAnotherCollection(const std::string &collectionToDecorate, const std::string &collectionToLink, const std::string &nameOfDecoration) + { + const xAOD::TruthParticleContainer* cont1(nullptr); + const xAOD::TruthParticleContainer* cont2(nullptr); + ATH_CHECK(evtStore()->retrieve(cont1,collectionToDecorate)); + ATH_CHECK(evtStore()->retrieve(cont2,collectionToLink)); + + for(const xAOD::TruthParticle *p : *cont1) + { + + const xAOD::TruthParticle* link =0; + for(const xAOD::TruthParticle *p2 : *cont2) + { + if(p->pdgId()==p2->pdgId() && p->barcode()==p2->barcode()) + { + link=p2; + break; + } + } + p->auxdecor<const xAOD::TruthParticle*>(nameOfDecoration)=link; + + } + return StatusCode::SUCCESS; } + const xAOD::TruthParticle* CalcTopPartonHistory::getTruthParticleLinkedFromDecoration(const xAOD::TruthParticle* part, const std::string &decorationName) + { + if(!part->isAvailable<const xAOD::TruthParticle*>(decorationName)) return part; + + const xAOD::TruthParticle* link=part->auxdecor<const xAOD::TruthParticle*>(decorationName); + if(link) return link; + + return part; + } + ///Store the four-momentum of the post-FSR top or anti-top found using statusCodes ///This would only work if there is at most one "true" top of each charge (i.e. won't work for SS tops or 4 tops) - ///This code was adapted from the 7TeV parton-level differential ttbar routine: https://svnweb.cern.ch/trac/atlasphys-top/browser/Physics/Top/Software/MCvalidation/Rivet/Rivet2.X/trunk/routines/ATLAS_2014_I1304289/ATLAS_2014_I1304289.cc - bool CalcTopPartonHistory::topAfterFSR_SC(const xAOD::TruthParticleContainer* truthParticles, int start, TLorentzVector& top_afterFSR_SC_p4){ - + ///This code was adapted from the 7TeV parton-level differential ttbar routine: + // https://svnweb.cern.ch/trac/atlasphys-top/browser/Physics/Top/Software/MCvalidation/Rivet/Rivet2.X/trunk/routines/ATLAS_2014_I1304289/ATLAS_2014_I1304289.cc + bool CalcTopPartonHistory::topAfterFSR_SC(const xAOD::TruthParticleContainer* truthParticles, int start, + TLorentzVector& top_afterFSR_SC_p4) { /// Step1: create vectors of particles of each status codes // Vectors to hold any status=3 (anti-)top quarks (Pythia 6) std::vector<const xAOD::TruthParticle*> v_status3_top; @@ -32,62 +89,59 @@ namespace top{ std::vector<const xAOD::TruthParticle*> v_status11_top; // Vectors to hold any status=22 (anti-)top quarks std::vector<const xAOD::TruthParticle*> v_statusOther_top; - + /// Step2: loop on the container of particles and fill the above created vectors for (const xAOD::TruthParticle* particle : *truthParticles) { if (particle->pdgId() != start) continue; // only keep particles of a given pdgID (e.g. 6 or -6) - - if (particle->status()==3) { + + if (particle->status() == 3) { v_status3_top.push_back(particle); - } - else if (particle->status()==155) { + } else if (particle->status() == 155) { v_status155_top.push_back(particle); - } - else if (particle->status()==11) {// for Herwig++: take only the tops that decay into Wb!!! + } else if (particle->status() == 11) {// for Herwig++: take only the tops that decay into Wb!!! if (!particle->hasDecayVtx()) continue; const xAOD::TruthVertex* vertex = particle->decayVtx(); if (vertex == nullptr) continue; if (vertex->nOutgoingParticles() == 2) v_status11_top.push_back(particle); - } - else { + } else { v_statusOther_top.push_back(particle); } } - + /// Step3: for some of the statuscodes, keep only the last of the vector // If there are more than 1 status 3 tops or anti-tops, only keep the last one put into the vector - if(v_status3_top.size()>1) { + if (v_status3_top.size() > 1) { v_status3_top = std::vector<const xAOD::TruthParticle*>(v_status3_top.end() - 1, v_status3_top.end()); } // If there are more than 1 status 11 tops or anti-tops, only keep the last one put into the vector - if(v_status11_top.size()>1) { + if (v_status11_top.size() > 1) { v_status11_top = std::vector<const xAOD::TruthParticle*>(v_status11_top.end() - 1, v_status11_top.end()); } // Rach: check for Pythia 8 as well // If there are more than 1 status 3 tops or anti-tops, only keep the last one put into the vector - if(v_statusOther_top.size()>1) { + if (v_statusOther_top.size() > 1) { v_statusOther_top = std::vector<const xAOD::TruthParticle*>(v_statusOther_top.end() - 1, v_statusOther_top.end()); } - + /// Step4: chose which statuscode to take according to what is found in the event const xAOD::TruthParticle* top = nullptr; // If there are status 3 tops and no status 155 tops this is probably a Pythia event, so used the status 3s. - if(v_status3_top.size() == 1 && v_status155_top.size() == 0) { + if (v_status3_top.size() == 1 && v_status155_top.size() == 0) { top = v_status3_top[0]; } // If there are status 155 tops this must be a Herwig event, so use the status 155s. - if( v_status155_top.size() == 1 && v_status3_top.size() == 0) { + if (v_status155_top.size() == 1 && v_status3_top.size() == 0) { top = v_status155_top[0]; } - // If there are tops with other status this must be a Pythia8 event, so use them. - if( v_statusOther_top.size() == 1 && v_status155_top.size() == 0 && v_status3_top.size()==0) { + // If there are tops with other status this must be a Pythia8 event, so use them. + if (v_statusOther_top.size() == 1 && v_status155_top.size() == 0 && v_status3_top.size() == 0) { top = v_statusOther_top[0]; } // If there are status 155 tops this must be a Herwig event, so use the status 155s. - if( v_status11_top.size() == 1 && v_status3_top.size() == 0) { + if (v_status11_top.size() == 1 && v_status3_top.size() == 0) { top = v_status11_top[0]; } - + /// Step5: if everything worked, set the 4-vector to its value and return true if (top != nullptr) { top_afterFSR_SC_p4 = top->p4(); @@ -95,210 +149,534 @@ namespace top{ } return false; } - - // for b coming from W'->tb - bool CalcTopPartonHistory::b( const xAOD::TruthParticleContainer* truthParticles, - TLorentzVector& b_beforeFSR, TLorentzVector& b_afterFSR){ + + // for b coming from W'->tb + bool CalcTopPartonHistory::b(const xAOD::TruthParticleContainer* truthParticles, + TLorentzVector& b_beforeFSR, TLorentzVector& b_afterFSR) { for (const xAOD::TruthParticle* particle : *truthParticles) { - - if (fabs(particle->pdgId()) != 5) continue; - - bool skipit(false); - for (size_t i=0; i< particle->nParents(); i++ ) { - const xAOD::TruthParticle* parent = particle->parent(i); - if (parent && (parent->isTop() || fabs(parent->pdgId())==5) ){ - skipit=true; - break; - }//if - }//for - - if( skipit) continue; - - b_beforeFSR = particle->p4(); - b_afterFSR = findAfterFSR(particle)->p4(); - - return true; - } - - - return false; + if (abs(particle->pdgId()) != 5) continue; + + bool skipit(false); + for (size_t i = 0; i < particle->nParents(); i++) { + const xAOD::TruthParticle* parent = particle->parent(i); + if (parent && (parent->isTop() || abs(parent->pdgId()) == 5)) { + skipit = true; + break; + }//if + }//for + + if (skipit) continue; + + b_beforeFSR = particle->p4(); + b_afterFSR = PartonHistoryUtils::findAfterFSR(particle)->p4(); + + return true; + } + + + return false; } - - - bool CalcTopPartonHistory::topWb( const xAOD::TruthParticleContainer* truthParticles, - int start, TLorentzVector& t_beforeFSR_p4, TLorentzVector& t_afterFSR_p4, TLorentzVector& W_p4, - TLorentzVector& b_p4, TLorentzVector& Wdecay1_p4, - int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId){ - - bool hasT = false; - bool hasW = false; - bool hasB = false; - bool hasWdecayProd1 = false; - bool hasWdecayProd2 = false; - + + bool CalcTopPartonHistory::topWb(const xAOD::TruthParticleContainer* truthParticles, + int start, TLorentzVector& t_beforeFSR_p4, TLorentzVector& t_afterFSR_p4, + TLorentzVector& W_p4, + TLorentzVector& b_p4, TLorentzVector& Wdecay1_p4, + int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId) { + bool hasT = false; + bool hasW = false; + bool hasB = false; + bool hasWdecayProd1 = false; + bool hasWdecayProd2 = false; + for (const xAOD::TruthParticle* particle : *truthParticles) { - - if (particle->pdgId() != start) continue; - - if (hasParticleIdenticalParent(particle)) continue; // kepping only top before FSR - - t_beforeFSR_p4 = particle->p4(); // top before FSR - hasT = true; - - // demanding the last tops after FSR - particle = findAfterFSR(particle); - t_afterFSR_p4 = particle->p4(); // top after FSR - - for (size_t k=0; k < particle->nChildren(); k++) { - const xAOD::TruthParticle* topChildren = particle->child(k); - - if (fabs(topChildren->pdgId()) == 24){ - - W_p4 = topChildren->p4(); // W boson after FSR - hasW = true; - - // demanding the last W after FSR - topChildren = findAfterFSR(topChildren); - - for (size_t q = 0; q < topChildren->nChildren(); ++q) { - const xAOD::TruthParticle* WChildren = topChildren->child(q); - if (fabs(WChildren->pdgId())<17){ - if (WChildren->pdgId()>0){ - Wdecay1_p4 = WChildren->p4(); - Wdecay1_pdgId = WChildren->pdgId(); - hasWdecayProd1 = true; - }else{ - Wdecay2_p4 = WChildren->p4(); - Wdecay2_pdgId = WChildren->pdgId(); - hasWdecayProd2 = true; - }//else - }//if - }//for - - } else if (fabs(topChildren->pdgId()) == 5) { - b_p4 = topChildren->p4(); - hasB = true; - } //else if - - } //for (size_t k=0; k < particle->nChildren(); k++) - if (hasT && hasW && hasB && hasWdecayProd1 && hasWdecayProd2) return true; + if (particle->pdgId() != start) continue; + + if (PartonHistoryUtils::hasParticleIdenticalParent(particle)) continue; // kepping only top before FSR + + t_beforeFSR_p4 = particle->p4(); // top before FSR + hasT = true; + + // demanding the last tops after FSR + particle = PartonHistoryUtils::findAfterFSR(particle); + t_afterFSR_p4 = particle->p4(); // top after FSR + + for (size_t k = 0; k < particle->nChildren(); k++) { + const xAOD::TruthParticle* topChildren = particle->child(k); + + if (abs(topChildren->pdgId()) == 24) { + W_p4 = topChildren->p4(); // W boson after FSR + hasW = true; + + // demanding the last W after FSR + topChildren = PartonHistoryUtils::findAfterFSR(topChildren); + + //for DAOD_PHYS we have to use a special procedure to associate W bosons linked from the top to those in the TruthBosonsWithDecayParticles collection, which have the correct links for their decay products + //this is better explained in the head; this will work only if the class calling this function has called linkBosonCollections() before + if(m_config->getDerivationStream() == "PHYS") topChildren=getTruthParticleLinkedFromDecoration(topChildren,"AT_linkToTruthBosonsWithDecayParticles"); + + for (size_t q = 0; q < topChildren->nChildren(); ++q) { + const xAOD::TruthParticle* WChildren = topChildren->child(q); + if (abs(WChildren->pdgId()) < 17) { + if (WChildren->pdgId() > 0) { + Wdecay1_p4 = WChildren->p4(); + Wdecay1_pdgId = WChildren->pdgId(); + hasWdecayProd1 = true; + } else { + Wdecay2_p4 = WChildren->p4(); + Wdecay2_pdgId = WChildren->pdgId(); + hasWdecayProd2 = true; + }//else + }//if + }//for + } else if (abs(topChildren->pdgId()) == 5) { + b_p4 = topChildren->p4(); + hasB = true; + } //else if + } //for (size_t k=0; k < particle->nChildren(); k++) + + if (hasT && hasW && hasB && hasWdecayProd1 && hasWdecayProd2) return true; + } //for (const xAOD::TruthParticle* particle : *truthParticles) - return false; - + return false; } - bool CalcTopPartonHistory::Wlv( const xAOD::TruthParticleContainer* truthParticles, - TLorentzVector& W_p4, - TLorentzVector& Wdecay1_p4, int& Wdecay1_pdgId, - TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId){ + bool CalcTopPartonHistory::topWq(const xAOD::TruthParticleContainer* truthParticles, + int start, TLorentzVector& t_beforeFSR_p4, TLorentzVector& t_afterFSR_p4, + TLorentzVector& W_p4, + TLorentzVector& q_p4, int& q_pdgId, TLorentzVector& Wdecay1_p4, + int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId) { + bool hasT = false; + bool hasW = false; + bool hasQ = false; + bool hasWdecayProd1 = false; + bool hasWdecayProd2 = false; - bool hasW = false; - bool hasWdecayProd1 = false; - bool hasWdecayProd2 = false; - for (const xAOD::TruthParticle* particle : *truthParticles) { - - - if (fabs(particle->pdgId()) != 24) continue; - //std::cout << "PDGID: " << particle->pdgId() << std::endl; - - // demanding the last W after FSR - particle = findAfterFSR(particle); - W_p4 = particle->p4(); // W boson after FSR - hasW = true; - - for (size_t k=0; k < particle->nChildren(); k++) { - const xAOD::TruthParticle* WChildren = particle->child(k); - if (fabs(WChildren->pdgId())<17){ - if (WChildren->pdgId()%2==1){ // charged lepton in the Wlv case - Wdecay1_p4 = WChildren->p4(); - Wdecay1_pdgId = WChildren->pdgId(); - hasWdecayProd1 = true; - }else{// neutral lepton in the Wlv case - Wdecay2_p4 = WChildren->p4(); - Wdecay2_pdgId = WChildren->pdgId(); - hasWdecayProd2 = true; - }//else - }//if - - } //for (size_t k=0; k < particle->nChildren(); k++) - - if (hasW && hasWdecayProd1 && hasWdecayProd2) return true; + if (particle->pdgId() != start) continue; + + if (PartonHistoryUtils::hasParticleIdenticalParent(particle)) continue; // kepping only top before FSR + + t_beforeFSR_p4 = particle->p4(); // top before FSR + hasT = true; + + // demanding the last tops after FSR + particle = PartonHistoryUtils::findAfterFSR(particle); + t_afterFSR_p4 = particle->p4(); // top after FSR + + for (size_t k = 0; k < particle->nChildren(); k++) { + const xAOD::TruthParticle* topChildren = particle->child(k); + + if (abs(topChildren->pdgId()) == 24) { + W_p4 = topChildren->p4(); // W boson after FSR + hasW = true; + + // demanding the last W after FSR + topChildren = PartonHistoryUtils::findAfterFSR(topChildren); + + for (size_t q = 0; q < topChildren->nChildren(); ++q) { + const xAOD::TruthParticle* WChildren = topChildren->child(q); + if (abs(WChildren->pdgId()) < 17) { + if (WChildren->pdgId() > 0) { + Wdecay1_p4 = WChildren->p4(); + Wdecay1_pdgId = WChildren->pdgId(); + hasWdecayProd1 = true; + } else { + Wdecay2_p4 = WChildren->p4(); + Wdecay2_pdgId = WChildren->pdgId(); + hasWdecayProd2 = true; + }//else + }//if + }//for + } else if (abs(topChildren->pdgId()) == 5 || abs(topChildren->pdgId()) == 3 || abs(topChildren->pdgId()) == 1) { + q_p4 = topChildren->p4(); + q_pdgId = topChildren->pdgId(); + hasQ = true; + } //else if + } //for (size_t k=0; k < particle->nChildren(); k++) + if (hasT && hasW && hasQ && hasWdecayProd1 && hasWdecayProd2) return true; } //for (const xAOD::TruthParticle* particle : *truthParticles) - - - return false; - + + return false; } - - const xAOD::TruthParticle* CalcTopPartonHistory::findAfterFSR(const xAOD::TruthParticle* particle) { - bool isAfterFSR(false); - const int particle_ID = particle->pdgId(); - int forLoop = 0; - while(!isAfterFSR){ - - forLoop = 0; - for (size_t j=0; j< particle->nChildren(); j++ ) { - const xAOD::TruthParticle* tmp_children = particle->child(j); - if (tmp_children && tmp_children->pdgId()==particle_ID){ - particle = particle->child(j); - forLoop++; - break; - }//if - }//for - - if (forLoop == 0) isAfterFSR = true; - }//while - return particle; + bool CalcTopPartonHistory::Wlv(const xAOD::TruthParticleContainer* truthParticles, + TLorentzVector& W_p4, + TLorentzVector& Wdecay1_p4, int& Wdecay1_pdgId, + TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId) { + bool hasW = false; + bool hasWdecayProd1 = false; + bool hasWdecayProd2 = false; + + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (abs(particle->pdgId()) != 24) continue; + //std::cout << "PDGID: " << particle->pdgId() << std::endl; + + // demanding the last W after FSR + particle = PartonHistoryUtils::findAfterFSR(particle); + W_p4 = particle->p4(); // W boson after FSR + hasW = true; + + for (size_t k = 0; k < particle->nChildren(); k++) { + const xAOD::TruthParticle* WChildren = particle->child(k); + if (abs(WChildren->pdgId()) < 17) { + if (WChildren->pdgId() % 2 == 1) { // charged lepton in the Wlv case + Wdecay1_p4 = WChildren->p4(); + Wdecay1_pdgId = WChildren->pdgId(); + hasWdecayProd1 = true; + } else {// neutral lepton in the Wlv case + Wdecay2_p4 = WChildren->p4(); + Wdecay2_pdgId = WChildren->pdgId(); + hasWdecayProd2 = true; + }//else + }//if + } //for (size_t k=0; k < particle->nChildren(); k++) + + if (hasW && hasWdecayProd1 && hasWdecayProd2) return true; + } //for (const xAOD::TruthParticle* particle : *truthParticles) + + + return false; } - bool CalcTopPartonHistory::hasParticleIdenticalParent(const xAOD::TruthParticle* particle) { - bool skipit(false); - for (size_t i=0; i< particle->nParents(); i++ ) { - const xAOD::TruthParticle* parent = particle->parent(i); - if (parent && parent->pdgId()==particle->pdgId()){ - skipit=true; - break; - }//if - }//for - return skipit; + // for Wt ST events, find W that is not from top + bool CalcTopPartonHistory::Wt_W(const xAOD::TruthParticleContainer* truthParticles, + TLorentzVector& W_p4, int& W_pdgId, TLorentzVector& Wdecay1_p4, + int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId) { + bool hasW = false; + bool hasWdecayProd1 = false; + bool hasWdecayProd2 = false; + + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle == nullptr) continue; + if (abs(particle->pdgId()) != 24) continue; // W boson + + // need to check if the W is from top + // identify the first in chain and check + // if that particle has top as parent + if (PartonHistoryUtils::hasParticleIdenticalParent(particle)) continue; // kepping only W before FSR + + bool isFromTop = false; + // now we should have only the first W in chain + for (size_t iparent = 0; iparent < particle->nParents(); ++iparent) { + if (particle->parent(iparent) == nullptr) continue; + if (abs(particle->parent(iparent)->pdgId()) == 6) { // has top as parent + isFromTop = true; + break; + } + } + + if (isFromTop) continue; + else { + particle = PartonHistoryUtils::findAfterFSR(particle); + W_p4 = particle->p4(); + W_pdgId = particle->pdgId(); + hasW = true; + } + + // check the decay products of the W + for (size_t q = 0; q < particle->nChildren(); ++q) { + const xAOD::TruthParticle* WChildren = particle->child(q); + if (WChildren == nullptr) continue; + if (abs(WChildren->pdgId()) < 17) { + if (WChildren->pdgId() > 0) { + Wdecay1_p4 = WChildren->p4(); + Wdecay1_pdgId = WChildren->pdgId(); + hasWdecayProd1 = true; + } else { + Wdecay2_p4 = WChildren->p4(); + Wdecay2_pdgId = WChildren->pdgId(); + hasWdecayProd2 = true; + }//else + }//if + }//for + + if (hasW && hasWdecayProd1 && hasWdecayProd2) return true; + } // loop over truth particles + + return false; } - - StatusCode CalcTopPartonHistory::execute() - { - // Get the Truth Particles - const xAOD::TruthParticleContainer* truthParticles(nullptr); - ATH_CHECK( evtStore()->retrieve( truthParticles , m_config->sgKeyMCParticle() ) ); - - // Create the partonHistory xAOD object - xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer{}; - xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer{}; - partonCont->setStore( partonAuxCont ); - - xAOD::PartonHistory* partonHistory = new xAOD::PartonHistory{}; - partonCont->push_back( partonHistory ); - - // Save to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyTopPartonHistory(); - std::string outputSGKeyAux = outputSGKey + "Aux."; - - xAOD::TReturnCode save = evtStore()->tds()->record( partonCont , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( partonAuxCont , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } - - return StatusCode::SUCCESS; - } - - void CalcTopPartonHistory::fillEtaBranch( xAOD::PartonHistory* partonHistory, std::string branchName, TLorentzVector &tlv){ - if (tlv.CosTheta()==1.) partonHistory->auxdecor< float >( branchName ) = 1000.; - else if (tlv.CosTheta()==-1.) partonHistory->auxdecor< float >( branchName ) = 1000.; - else partonHistory->auxdecor< float >( branchName ) = tlv.Eta(); - return; - - + + // for Wt ST events, find b that is not from top + bool CalcTopPartonHistory::Wt_b(const xAOD::TruthParticleContainer* truthParticles, + TLorentzVector& b_beforeFSR, TLorentzVector& b_afterFSR, + int& b_pdgId) { + bool hasB = false; + + // identify "other" b quark that is not from radiation but from ME (Wtb) + // logic is simple: search for b quark that doesn't have top, proton, or + // nullptr as parent + + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle == nullptr) continue; + if (abs(particle->pdgId()) != 5) continue; + + for (size_t iparent = 0; iparent < particle->nParents(); ++iparent) { + if (particle->parent(iparent) == nullptr) continue; + + // we dont want b-quarks that have b as parent + if (abs(particle->parent(iparent)->pdgId()) == 5) continue; + + // we dont want b-quarks that come from top + if (abs(particle->parent(iparent)->pdgId()) == 6) continue; + + // we dont want b-quarks that come from W + if (abs(particle->parent(iparent)->pdgId()) == 24) continue; + + // we dont want b-quarks that come from proton + if (abs(particle->parent(iparent)->pdgId()) == 2212) continue; + + hasB = true; + b_beforeFSR = particle->p4(); + b_pdgId = particle->pdgId(); + + // find after FSR + particle = PartonHistoryUtils::findAfterFSR(particle); + b_afterFSR = particle->p4(); + } + } + + + if (hasB) return true; + + return false; + } + + // for ttbar + photon events + bool CalcTopPartonHistory::topPhWb(const xAOD::TruthParticleContainer* truthParticles, int topId, + TLorentzVector& t_beforeFSR_p4, TLorentzVector& t_afterFSR_p4, + TLorentzVector& Ph_p4, TLorentzVector& W_p4, TLorentzVector& b_p4, + TLorentzVector& Wdecay1_p4, int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, + int& Wdecay2_pdgId, bool& has_ph, int& BranchType, int& IniPartonType, + bool& missingTop) { + bool hasT = false; + bool hasW = false; + bool hasAbsentW = false; + bool hasB = false; + + has_ph = false; + bool ph_W = false; + bool ph_Top = false; + bool ph_ISR = false; + bool ph_b = false; + bool hasWdecayProd1 = false; + bool hasWdecayProd2 = false; + missingTop = false; + + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle->pdgId() != topId) continue; + + if (PartonHistoryUtils::hasParticleIdenticalParent(particle)) continue; // kepping only top before FSR + BranchType = -1;// 10(50): leptonic(hadronic), 12(52):topRad, 14(54):Wrad, 15(55):ISR, 18(58):b + IniPartonType = -1; + + // finding siblings + for (size_t iparent = 0; iparent < particle->nParents(); iparent++) { + if (abs(particle->parent(iparent)->pdgId()) == 21) { + IniPartonType = 1; + } // gg fusion + else if (abs(particle->parent(iparent)->pdgId()) < 6) { + IniPartonType = 2; + } //qq annihilation + + for (size_t ichild = 0; ichild < particle->parent(iparent)->nChildren(); ichild++) { + if (particle->parent(iparent)->child(ichild)->pdgId() == 22) { + const xAOD::TruthParticle* photon = PartonHistoryUtils::findAfterFSR(particle->parent(iparent)->child(ichild)); + Ph_p4 = photon->p4(); + has_ph = true; + ph_ISR = true; + } + if (!missingTop && + (abs(particle->parent(iparent)->child(ichild)->pdgId()) == 5 || + abs(particle->parent(iparent)->child(ichild)->pdgId()) == 24)) { + missingTop = true; + } + } + } + + t_beforeFSR_p4 = particle->p4(); // top before FSR + hasT = true; + // demanding the last tops after FSR + particle = PartonHistoryUtils::findAfterFSR(particle); + t_afterFSR_p4 = particle->p4(); // top after FSR + + for (size_t k = 0; k < particle->nChildren(); k++) {// top children + const xAOD::TruthParticle* topChildren = particle->child(k); + + if (abs(topChildren->pdgId()) == 24) { + W_p4 = topChildren->p4(); // W boson before FSR + hasW = true; + + // demanding the last W after FSR + topChildren = PartonHistoryUtils::findAfterFSR(topChildren); + + for (size_t q = 0; q < topChildren->nChildren(); q++) {// W children + const xAOD::TruthParticle* WChildren = topChildren->child(q); + if (abs(WChildren->pdgId()) > 0 && abs(WChildren->pdgId()) < 17) { + if (abs(WChildren->pdgId()) < 7) { + BranchType = 50; + }// hadronic + else if (abs(WChildren->pdgId()) > 10 && abs(WChildren->pdgId()) < 17) { + BranchType = 10; + }// leptonic + if (WChildren->pdgId() > 0) { + WChildren = PartonHistoryUtils::findAfterFSR(WChildren); + Wdecay1_p4 = WChildren->p4(); + Wdecay1_pdgId = WChildren->pdgId(); + hasWdecayProd1 = true; + } else { + WChildren = PartonHistoryUtils::findAfterFSR(WChildren); + Wdecay2_p4 = WChildren->p4(); + Wdecay2_pdgId = WChildren->pdgId(); + hasWdecayProd2 = true; + }//else + } else if (abs(WChildren->pdgId()) == 22) {// photon + // JUST FOR EXTRA SAFETY (not necessary) + // check if there exists a photon already + // if it does, check the photon's Pt + // if found harder then consider, else do nothing + if (has_ph) { + if (WChildren->p4().Pt() > Ph_p4.Pt()) { + ph_W = true; + ph_ISR = false; + ph_Top = false; + ph_b = false; + WChildren = PartonHistoryUtils::findAfterFSR(WChildren); + Ph_p4 = WChildren->p4(); + } + } else { + has_ph = true; + ph_W = true; + WChildren = PartonHistoryUtils::findAfterFSR(WChildren); + Ph_p4 = WChildren->p4(); + } + } + }// W children + } else if (abs(topChildren->pdgId()) == 5) { // b + hasB = true; + topChildren = PartonHistoryUtils::findAfterFSR(topChildren);// b After FSR + b_p4 = topChildren->p4(); + // In MG5 generation of ttgamma it is not expected to have any b radiation 'recorded' + for (size_t b = 0; b < topChildren->nChildren(); b++) {// b Children + const xAOD::TruthParticle* bChildren = topChildren->child(b); + if (bChildren && bChildren->pdgId() == 22) { + // JUST FOR EXTRA SAFETY (not necessary) + if (has_ph) { + if (bChildren->p4().Pt() > Ph_p4.Pt()) { + ph_b = true; + ph_ISR = false; + ph_Top = false; + ph_W = false; + bChildren = PartonHistoryUtils::findAfterFSR(bChildren); + Ph_p4 = bChildren->p4(); + } + } else { + has_ph = true; + ph_b = true; + bChildren = PartonHistoryUtils::findAfterFSR(bChildren); + Ph_p4 = bChildren->p4(); + } + } + } + } else if (abs(topChildren->pdgId()) == 22) { + // JUST FOR EXTRA SAFETY (not necessary) + if (has_ph) { + if (topChildren->p4().Pt() > Ph_p4.Pt()) { + topChildren = PartonHistoryUtils::findAfterFSR(topChildren); + Ph_p4 = topChildren->p4(); + ph_Top = true; + } + } else { + topChildren = PartonHistoryUtils::findAfterFSR(topChildren); + Ph_p4 = topChildren->p4(); + has_ph = true; + ph_Top = true; + ph_W = false; + ph_ISR = false; + ph_b = false; + } + } + // sometimes the W is not recorded and the W products are recorded as top products + else if (abs(topChildren->pdgId()) <= 4 || (abs(topChildren->pdgId()) > 10 && abs(topChildren->pdgId()) < 17)) { + hasW = true; + hasAbsentW = true; + if (abs(topChildren->pdgId()) < 7) { + BranchType = 50; + }// hadronic + else if (abs(topChildren->pdgId()) > 10 && abs(topChildren->pdgId()) < 17) { + BranchType = 10; + }// leptonic + if (topChildren->pdgId() > 0) { + topChildren = PartonHistoryUtils::findAfterFSR(topChildren); + Wdecay1_p4 = topChildren->p4(); + Wdecay1_pdgId = topChildren->pdgId(); + hasWdecayProd1 = true; + } else { + topChildren = PartonHistoryUtils::findAfterFSR(topChildren); + Wdecay2_p4 = topChildren->p4(); + Wdecay2_pdgId = topChildren->pdgId(); + hasWdecayProd2 = true; + }//else + W_p4 = W_p4 + topChildren->p4(); + }// if top children + } // for top children + + // BranchType Determination if there is a photon + if (hasAbsentW && (ph_Top || ph_W)) { + BranchType = -1; + }// if the W is not recorded and still the photon is from the top, the source of the photon is then ambiguous + // among top and W. BranchType would be +1. Category would be 0. + if (has_ph && ph_Top) { + BranchType = BranchType + 2; + } + if (has_ph && ph_W) { + BranchType = BranchType + 4; + } + if (has_ph && ph_ISR) { + BranchType = BranchType + 5; + } + if (has_ph && ph_b) { + BranchType = BranchType + 8; + } + + if (hasT && hasW && hasB && hasWdecayProd1 && hasWdecayProd2 && BranchType != -1) return true; + }// particle + + return false; + } + + StatusCode CalcTopPartonHistory::execute() { + // Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* partonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(partonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } + + void CalcTopPartonHistory::fillEtaBranch(xAOD::PartonHistory* partonHistory, std::string branchName, + TLorentzVector& tlv) { + if (tlv.CosTheta() == 1.) partonHistory->auxdecor< float >(branchName) = 1000.; + else if (tlv.CosTheta() == -1.) partonHistory->auxdecor< float >(branchName) = 1000.; + else partonHistory->auxdecor< float >(branchName) = tlv.Eta(); + return; } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarGammaPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarGammaPartonHistory.cxx new file mode 100644 index 000000000000..dd36186154b3 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarGammaPartonHistory.cxx @@ -0,0 +1,400 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopPartons/CalcTtbarGammaPartonHistory.h" +#include "TopConfiguration/TopConfig.h" +#include "TopPartons/PartonHistoryUtils.h" + +namespace top { + CalcTtbarGammaPartonHistory::CalcTtbarGammaPartonHistory(const std::string& name) : CalcTopPartonHistory(name) {} + + void CalcTtbarGammaPartonHistory::ttbarGammaHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* ttbarGammaPartonHistory) { + ttbarGammaPartonHistory->IniVarTtGamma(); + TLorentzVector ph_t; + bool has_ph_t; + int branchtype_t = -1; + int branchtype_tbar = -1; + /// Definition of top-branch type: also applicable for branchtype_tbar + /// -1:undefined + /// 0: missing top + /// 1: missing W + /// 10: leptonic branch without photon + /// 12: leptonic branch with photon from top + /// 14: leptonic branch with photon from W + /// 15: leptonic branch with photon from ISR + /// 18: leptonic branch with photon from b + /// 50: hadronic branch without photon + /// 52: hadronic branch with photon from top + /// 54: hadronic branch with photon from W + /// 55: hadronic branch with photon from ISR + /// 58: hadronic branch with photon from b + int init_type = -1; + /// Initial parton definition: + /// -1:undefined + /// 0: missing top (only one of them) + /// 1: gg (gluon fusion) + /// 2: qq (quark annihilation) + TLorentzVector t_before, t_after; + TLorentzVector Wp; + TLorentzVector b; + TLorentzVector WpDecay1; + TLorentzVector WpDecay2; + int WpDecay1_pdgId; + int WpDecay2_pdgId; + bool missTop; + bool missTbar; + bool event_top = CalcTopPartonHistory::topPhWb(truthParticles, 6, t_before, t_after, ph_t, Wp, b, WpDecay1, + WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId, has_ph_t, branchtype_t, + init_type, missTbar); + + TLorentzVector ph_tbar; + bool has_ph_tbar; + TLorentzVector tbar_before, tbar_after; + TLorentzVector Wm; + TLorentzVector bbar; + TLorentzVector WmDecay1; + TLorentzVector WmDecay2; + int WmDecay1_pdgId; + int WmDecay2_pdgId; + bool event_topbar = CalcTopPartonHistory::topPhWb(truthParticles, -6, tbar_before, tbar_after, ph_tbar, Wm, bbar, + WmDecay1, WmDecay1_pdgId, WmDecay2, WmDecay2_pdgId, has_ph_tbar, + branchtype_tbar, init_type, missTop); + + if (event_top && missTbar && has_ph_t && branchtype_t != 10 && branchtype_t != 50 && branchtype_t != 15 && + branchtype_t != 55) { + bool Wonshell = false; + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle->barcode() != 3) continue; + for (size_t q = 0; q < particle->nChildren(); q++) { + if (particle->child(q) && particle->child(q)->pdgId() == -5) bbar =PartonHistoryUtils::findAfterFSR(particle->child( + q))-> + p4(); + if (particle->child(q) && particle->child(q)->pdgId() == -24) { + Wm = particle->child(q)->p4(); + Wonshell = true; + for (size_t Wc = 0; Wc < particle->child(q)->nChildren(); Wc++) { + if (particle->child(q)->child(Wc)->pdgId() > 0) { + WmDecay1 = PartonHistoryUtils::findAfterFSR(particle->child(q)->child(Wc))->p4(); + WmDecay1_pdgId = particle->child(q)->child(Wc)->pdgId(); + } + if (particle->child(q)->child(Wc)->pdgId() < 0) { + WmDecay2 = PartonHistoryUtils::findAfterFSR(particle->child(q)->child(Wc))->p4(); + WmDecay2_pdgId = particle->child(q)->child(Wc)->pdgId(); + } + } + } + if (!Wonshell) { + if (particle->child(q) && particle->child(q)->pdgId() != 6 && particle->child(q)->pdgId() != 22 && + particle->child(q)->pdgId() > 0) { + WmDecay1 = PartonHistoryUtils::findAfterFSR(particle->child(q))->p4(); + WmDecay1_pdgId = particle->child(q)->pdgId(); + } + if (particle->child(q) && particle->child(q)->pdgId() != -6 && particle->child(q)->pdgId() != 22 && + particle->child(q)->pdgId() < 0) { + WmDecay2 = PartonHistoryUtils::findAfterFSR(particle->child(q))->p4(); + WmDecay2_pdgId = particle->child(q)->pdgId(); + } + Wm = WmDecay1 + WmDecay2; + } + } + if (WmDecay1_pdgId >= 1 && WmDecay1_pdgId <= 4) branchtype_tbar = 50; + else if (WmDecay1_pdgId >= 11 && WmDecay1_pdgId <= 16) branchtype_tbar = 10; + + if (branchtype_tbar == 50 || branchtype_tbar == 10) { + event_topbar = true; + has_ph_tbar = false; + } + } + } else if (event_topbar && missTop && has_ph_tbar && branchtype_tbar != 10 && branchtype_tbar != 50 && + branchtype_tbar != 15 && branchtype_tbar != 55) { + bool Wonshell = false; + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle->barcode() != 3) continue; + for (size_t q = 0; q < particle->nChildren(); q++) { + if (particle->child(q) && particle->child(q)->pdgId() == 5) b = PartonHistoryUtils::findAfterFSR(particle->child( + q))->p4(); + + if (particle->child(q) && particle->child(q)->pdgId() == 24) { + Wp = particle->child(q)->p4(); + Wonshell = true; + for (size_t Wc = 0; Wc < particle->child(q)->nChildren(); Wc++) { + if (particle->child(q)->child(Wc)->pdgId() > 0) { + WmDecay1 = PartonHistoryUtils::findAfterFSR(particle->child(q)->child(Wc))->p4(); + WmDecay1_pdgId = particle->child(q)->child(Wc)->pdgId(); + } + if (particle->child(q)->child(Wc)->pdgId() < 0) { + WmDecay2 = PartonHistoryUtils::findAfterFSR(particle->child(q)->child(Wc))->p4(); + WmDecay2_pdgId = particle->child(q)->child(Wc)->pdgId(); + } + } + } + if (!Wonshell) { + if (particle->child(q) && particle->child(q)->pdgId() != 6 && particle->child(q)->pdgId() != 22 && + particle->child(q)->pdgId() > 0) { + WmDecay1 = PartonHistoryUtils::findAfterFSR(particle->child(q))->p4(); + WmDecay1_pdgId = particle->child(q)->pdgId(); + } + if (particle->child(q) && particle->child(q)->pdgId() != -6 && particle->child(q)->pdgId() != 22 && + particle->child(q)->pdgId() < 0) { + WmDecay2 = PartonHistoryUtils::findAfterFSR(particle->child(q))->p4(); + WmDecay2_pdgId = particle->child(q)->pdgId(); + } + Wp = WpDecay1 + WpDecay2; + } + } + if (abs(WmDecay1_pdgId) >= 1 && abs(WmDecay1_pdgId) <= 4) branchtype_t = 50; + else if (abs(WmDecay1_pdgId) >= 11 && abs(WmDecay1_pdgId) <= 16) branchtype_t = 10; + if (branchtype_t == 50 || branchtype_t == 10) { + event_top = true; + has_ph_t = false; + } + } + } + + TLorentzVector ph; + int ph_source = -1; + /// photon source definition: + /// -1:undefined + /// 0: ISR + /// 1: top + /// 2: antitop + /// 3: missing top (only one of them) + int category = -2; + /// event category: + /// -2: undefined + /// -1: missing W (only if the corresponding top radiates) + /// 0: missing top + /// 1: Single Lepton inital quark radiation + /// 2: Single Lepton virtual top radiation + /// 3: Single Lepton leptonic top radiation + /// 4: Single Lepton hadronic top radiation + /// 5: Single Lepton leptonic W radiation + /// 6: Single Lepton hadronic W radiation + /// 7: Single Lepton leptonic b radiation + /// 8: Single Lepton hadronic b radiation + /// 9: Dilepton quark radiation + /// 10: Dilepton virtual top radiation + /// 11: Dilepton top radiation + /// 12: Dilepton W radiation + /// 13: Dilepton b radiation + + if ((event_top && !event_topbar) || (!event_top && event_topbar) || (!event_top && !event_topbar)) {// missing top + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle->barcode() != 3) continue; + if (abs(particle->pdgId()) == 21) init_type = 1; //gg + else if (abs(particle->pdgId()) < 6) init_type = 2; //qq + } + category = 0; + ph_source = 3; + branchtype_t = 0; + branchtype_tbar = 0; + ttbarGammaPartonHistory->auxdecor< int >("MC_branchtype_t") = branchtype_t; + ttbarGammaPartonHistory->auxdecor< int >("MC_branchtype_tbar") = branchtype_tbar; + ttbarGammaPartonHistory->auxdecor< int >("MC_initial_parton") = init_type; + ttbarGammaPartonHistory->auxdecor< int >("MC_Event_Category") = category; + ttbarGammaPartonHistory->auxdecor< int >("MC_ph_from_t_tbar") = ph_source; + }// one of the top is virtual + else if (event_top && event_topbar) { // && (has_ph_t || has_ph_tbar) + if (has_ph_t && has_ph_tbar) {// isr should give the same photon to both tops + if (ph_t.Pt() > ph_tbar.Pt()) { + ph = ph_t; + }// FOR EXTRA SAFETY + else { + ph = ph_tbar; + } + ph_source = 0; // isr + } else if (has_ph_t) { + ph = ph_t; + ph_source = 1; + }// top + else if (has_ph_tbar) { + ph = ph_tbar; + ph_source = 2; + }// antitop + else if (!has_ph_t && !has_ph_tbar) { + ph_source = -1; + } + + // determination of event category + // ISR + if (ph_source == 0) { + if (init_type == 2) { + category = 1; + if (branchtype_t == 15 && branchtype_tbar == 15) { + category = 9; + } // ISR_qq_DL + } //ISR_qq + else if (init_type == 1) { + category = 2; + if (branchtype_t == 15 && branchtype_tbar == 15) { + category = 10; + } // ISR_gg_DL + } //ISR_gg/top + } else if (ph_source == 1 || ph_source == 2) { + if ((branchtype_t == 12 && branchtype_tbar == 50) || (branchtype_t == 50 && branchtype_tbar == 12)) { + category = 3; + }// top Radiation leptonic + else if ((branchtype_t == 52 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 52)) { + category = 4; + }// top Radiation hadronic + else if ((branchtype_t == 14 && branchtype_tbar == 50) || (branchtype_t == 50 && branchtype_tbar == 14)) { + category = 5; + }// W Radiation leptonic + else if ((branchtype_t == 54 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 54)) { + category = 6; + }// W Radiation hadronic + else if ((branchtype_t == 18 && branchtype_tbar == 50) || (branchtype_t == 50 && branchtype_tbar == 18)) { + category = 7; + }// b Radiation leptonic + else if ((branchtype_t == 58 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 58)) { + category = 8; + }// b Radiation hadronic + else if ((branchtype_t == 12 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 12)) { + category = 11; + }// Top Radiation dileptonic + else if ((branchtype_t == 14 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 14)) { + category = 12; + }// W Radiation dileptonic + else if ((branchtype_t == 18 && branchtype_tbar == 10) || (branchtype_t == 10 && branchtype_tbar == 18)) { + category = 13; + }// W Radiation dileptonic + else if (branchtype_t == 1 || branchtype_tbar == 1) { + category = -1; + }// missing W + else { + category = 0; + }// missing top + } else if (ph_source == -1) { + category = -2; + } // undefined + +//------------------------------------------------------------------------------------------ + ttbarGammaPartonHistory->auxdecor< float >("MC_ph_m") = ph.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_ph_pt") = ph.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_ph_phi") = ph.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_ph_eta", ph); + + ttbarGammaPartonHistory->auxdecor< int >("MC_branchtype_t") = branchtype_t; + ttbarGammaPartonHistory->auxdecor< int >("MC_branchtype_tbar") = branchtype_tbar; + ttbarGammaPartonHistory->auxdecor< int >("MC_initial_parton") = init_type; + ttbarGammaPartonHistory->auxdecor< int >("MC_ph_from_t_tbar") = ph_source; + ttbarGammaPartonHistory->auxdecor< int >("MC_Event_Category") = category; +//------------------------------------------------------------------------------------------ + + TLorentzVector temp = t_before + tbar_before; + ttbarGammaPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_m") = temp.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_pt") = temp.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_phi") = temp.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_ttbar_beforeFSR_eta", temp); + + temp = WmDecay1 + WmDecay2 + b + WpDecay1 + WpDecay2 + bbar + ph; + ttbarGammaPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_m") = temp.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_pt") = temp.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_phi") = temp.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_ttbar_afterFSR_eta", temp); + } + +//------------------------------------------------------------------------------------------ + if (event_top) { + ttbarGammaPartonHistory->auxdecor< float >("MC_t_beforeFSR_m") = t_before.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_t_beforeFSR_pt") = t_before.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_t_beforeFSR_phi") = t_before.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_t_beforeFSR_eta", t_before); + + ttbarGammaPartonHistory->auxdecor< float >("MC_t_afterFSR_m") = t_after.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_t_afterFSR_pt") = t_after.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_t_afterFSR_phi") = t_after.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_t_afterFSR_eta", t_after); + + ttbarGammaPartonHistory->auxdecor< float >("MC_W_from_t_m") = Wp.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_W_from_t_pt") = Wp.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_W_from_t_phi") = Wp.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_W_from_t_eta", Wp); + + ttbarGammaPartonHistory->auxdecor< float >("MC_b_from_t_m") = b.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_b_from_t_pt") = b.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_b_from_t_phi") = b.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_b_from_t_eta", b); + + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_m") = WpDecay1.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_pt") = WpDecay1.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_phi") = WpDecay1.Phi(); + ttbarGammaPartonHistory->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = WpDecay1_pdgId; + fillEtaBranch(ttbarGammaPartonHistory, "MC_Wdecay1_from_t_eta", WpDecay1); + + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_m") = WpDecay2.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_pt") = WpDecay2.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_phi") = WpDecay2.Phi(); + ttbarGammaPartonHistory->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = WpDecay2_pdgId; + fillEtaBranch(ttbarGammaPartonHistory, "MC_Wdecay2_from_t_eta", WpDecay2); + } + + +//------------------------------------------------------------------------------------------- + if (event_topbar) { + ttbarGammaPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_m") = tbar_before.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_pt") = tbar_before.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_phi") = tbar_before.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_tbar_beforeFSR_eta", tbar_before); + + ttbarGammaPartonHistory->auxdecor< float >("MC_tbar_afterFSR_m") = tbar_after.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_tbar_afterFSR_pt") = tbar_after.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_tbar_afterFSR_phi") = tbar_after.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_tbar_afterFSR_eta", tbar_after); + + ttbarGammaPartonHistory->auxdecor< float >("MC_W_from_tbar_m") = Wm.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_W_from_tbar_pt") = Wm.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_W_from_tbar_phi") = Wm.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_W_from_tbar_eta", Wm); + + ttbarGammaPartonHistory->auxdecor< float >("MC_b_from_tbar_m") = bbar.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_b_from_tbar_pt") = bbar.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_b_from_tbar_phi") = bbar.Phi(); + fillEtaBranch(ttbarGammaPartonHistory, "MC_b_from_tbar_eta", bbar); + + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_m") = WmDecay1.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_pt") = WmDecay1.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_phi") = WmDecay1.Phi(); + ttbarGammaPartonHistory->auxdecor< int >("MC_Wdecay1_from_tbar_pdgId") = WmDecay1_pdgId; + fillEtaBranch(ttbarGammaPartonHistory, "MC_Wdecay1_from_tbar_eta", WmDecay1); + + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_m") = WmDecay2.M(); + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_pt") = WmDecay2.Pt(); + ttbarGammaPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_phi") = WmDecay2.Phi(); + ttbarGammaPartonHistory->auxdecor< int >("MC_Wdecay2_from_tbar_pdgId") = WmDecay2_pdgId; + fillEtaBranch(ttbarGammaPartonHistory, "MC_Wdecay2_from_tbar_eta", WmDecay2); + } + } + + StatusCode CalcTtbarGammaPartonHistory::execute() { + // Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + std::unique_ptr<xAOD::PartonHistoryAuxContainer> partonAuxCont(new xAOD::PartonHistoryAuxContainer()); + std::unique_ptr<xAOD::PartonHistoryContainer> partonCont(new xAOD::PartonHistoryContainer()); + partonCont->setStore(partonAuxCont.release()); + + xAOD::PartonHistory* ttbarGammaPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(ttbarGammaPartonHistory); + + // Recover the parton history for ttbargamma events + ttbarGammaHistorySaver(truthParticles, ttbarGammaPartonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont.release(), outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont.release(), outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarLightPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarLightPartonHistory.cxx new file mode 100644 index 000000000000..5cb8f5e5ed75 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarLightPartonHistory.cxx @@ -0,0 +1,165 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopPartons/CalcTtbarLightPartonHistory.h" +#include "TopConfiguration/TopConfig.h" + +namespace top { + CalcTtbarLightPartonHistory::CalcTtbarLightPartonHistory(const std::string& name) : CalcTopPartonHistory(name) {} + + void CalcTtbarLightPartonHistory::ttbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* ttbarPartonHistory) { + ttbarPartonHistory->IniVarTtbarLight(); + + TLorentzVector t_before, t_after, t_after_SC; + TLorentzVector Wp; + TLorentzVector q; + int q_pdgId; + TLorentzVector WpDecay1; + TLorentzVector WpDecay2; + int WpDecay1_pdgId; + int WpDecay2_pdgId; + bool event_top = CalcTopPartonHistory::topWq(truthParticles, 6, t_before, t_after, Wp, q, q_pdgId, WpDecay1, + WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId); + bool event_top_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, 6, t_after_SC); + + TLorentzVector tbar_before, tbar_after, tbar_after_SC; + TLorentzVector Wm; + TLorentzVector qbar; + int qbar_pdgId; + TLorentzVector WmDecay1; + TLorentzVector WmDecay2; + int WmDecay1_pdgId; + int WmDecay2_pdgId; + bool event_topbar = CalcTopPartonHistory::topWq(truthParticles, -6, tbar_before, tbar_after, Wm, qbar, qbar_pdgId, + WmDecay1, WmDecay1_pdgId, WmDecay2, WmDecay2_pdgId); + bool event_topbar_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, -6, tbar_after_SC); + + if (event_top && event_topbar) { + TLorentzVector temp = t_before + tbar_before; + ttbarPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_m") = temp.M(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_pt") = temp.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_phi") = temp.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_ttbar_beforeFSR_eta", temp); + + temp = WmDecay1 + WmDecay2 + q + WpDecay1 + WpDecay2 + qbar; + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_m") = temp.M(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_pt") = temp.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_phi") = temp.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_ttbar_afterFSR_eta", temp); + }//if + if (event_top) { + ttbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_m") = t_before.M(); + ttbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_pt") = t_before.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_phi") = t_before.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_t_beforeFSR_eta", t_before); + + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_m") = t_after.M(); + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_pt") = t_after.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_phi") = t_after.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_t_afterFSR_eta", t_after); + + if (event_top_SC) { + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_m") = t_after_SC.M(); + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_pt") = t_after_SC.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_phi") = t_after_SC.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_t_afterFSR_SC_eta", t_after_SC); + } + + ttbarPartonHistory->auxdecor< float >("MC_W_from_t_m") = Wp.M(); + ttbarPartonHistory->auxdecor< float >("MC_W_from_t_pt") = Wp.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_W_from_t_phi") = Wp.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_W_from_t_eta", Wp); + + ttbarPartonHistory->auxdecor< float >("MC_q_from_t_m") = q.M(); + ttbarPartonHistory->auxdecor< float >("MC_q_from_t_pt") = q.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_q_from_t_phi") = q.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_q_from_t_pdgId") = q_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_q_from_t_eta", q); + + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_m") = WpDecay1.M(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_pt") = WpDecay1.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_phi") = WpDecay1.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = WpDecay1_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_Wdecay1_from_t_eta", WpDecay1); + + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_m") = WpDecay2.M(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_pt") = WpDecay2.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_phi") = WpDecay2.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = WpDecay2_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_Wdecay2_from_t_eta", WpDecay2); + }//if + if (event_topbar) { + ttbarPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_m") = tbar_before.M(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_pt") = tbar_before.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_phi") = tbar_before.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_tbar_beforeFSR_eta", tbar_before); + + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_m") = tbar_after.M(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_pt") = tbar_after.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_phi") = tbar_after.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_tbar_afterFSR_eta", tbar_after); + + if (event_topbar_SC) { + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_SC_m") = tbar_after_SC.M(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_SC_pt") = tbar_after_SC.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_SC_phi") = tbar_after_SC.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_tbar_afterFSR_SC_eta", tbar_after_SC); + } + + ttbarPartonHistory->auxdecor< float >("MC_W_from_tbar_m") = Wm.M(); + ttbarPartonHistory->auxdecor< float >("MC_W_from_tbar_pt") = Wm.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_W_from_tbar_phi") = Wm.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_W_from_tbar_eta", Wm); + + ttbarPartonHistory->auxdecor< float >("MC_q_from_tbar_m") = qbar.M(); + ttbarPartonHistory->auxdecor< float >("MC_q_from_tbar_pt") = qbar.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_q_from_tbar_phi") = qbar.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_q_from_tbar_pdgId") = qbar_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_q_from_tbar_eta", qbar); + + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_m") = WmDecay1.M(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_pt") = WmDecay1.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_phi") = WmDecay1.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Wdecay1_from_tbar_pdgId") = WmDecay1_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_Wdecay1_from_tbar_eta", WmDecay1); + + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_m") = WmDecay2.M(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_pt") = WmDecay2.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_phi") = WmDecay2.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Wdecay2_from_tbar_pdgId") = WmDecay2_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_Wdecay2_from_tbar_eta", WmDecay2); + }//if + } + + StatusCode CalcTtbarLightPartonHistory::execute() { + // Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* ttbarPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(ttbarPartonHistory); + + // Recover the parton history for ttbar events + ttbarHistorySaver(truthParticles, ttbarPartonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarPartonHistory.cxx index 4b269fa12e77..c2a2272abe6f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarPartonHistory.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTtbarPartonHistory.cxx @@ -1,162 +1,184 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopPartons/CalcTtbarPartonHistory.h" #include "TopConfiguration/TopConfig.h" -namespace top{ - - CalcTtbarPartonHistory::CalcTtbarPartonHistory(const std::string& name) : CalcTopPartonHistory( name ){} - - void CalcTtbarPartonHistory::ttbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* ttbarPartonHistory){ - - ttbarPartonHistory->IniVarTtbar(); - - TLorentzVector t_before, t_after, t_after_SC; - TLorentzVector Wp; - TLorentzVector b; - TLorentzVector WpDecay1; - TLorentzVector WpDecay2; - int WpDecay1_pdgId; - int WpDecay2_pdgId; - bool event_top = CalcTopPartonHistory::topWb(truthParticles, 6, t_before, t_after, Wp, b, WpDecay1, WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId); - bool event_top_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, 6, t_after_SC); - - TLorentzVector tbar_before, tbar_after, tbar_after_SC; - TLorentzVector Wm; - TLorentzVector bbar; - TLorentzVector WmDecay1; - TLorentzVector WmDecay2; - int WmDecay1_pdgId; - int WmDecay2_pdgId; - bool event_topbar = CalcTopPartonHistory::topWb(truthParticles, -6, tbar_before, tbar_after, Wm, bbar, WmDecay1, WmDecay1_pdgId, WmDecay2, WmDecay2_pdgId); - bool event_topbar_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, -6, tbar_after_SC); - - if (event_top && event_topbar){ - TLorentzVector temp = t_before+tbar_before; - ttbarPartonHistory->auxdecor< float >( "MC_ttbar_beforeFSR_m" ) = temp.M(); - ttbarPartonHistory->auxdecor< float >( "MC_ttbar_beforeFSR_pt" ) = temp.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_ttbar_beforeFSR_phi" ) = temp.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_ttbar_beforeFSR_eta", temp); - - temp = WmDecay1+WmDecay2+b + WpDecay1+WpDecay2+bbar; - ttbarPartonHistory->auxdecor< float >( "MC_ttbar_afterFSR_m" ) = temp.M(); - ttbarPartonHistory->auxdecor< float >( "MC_ttbar_afterFSR_pt" ) = temp.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_ttbar_afterFSR_phi" ) = temp .Phi(); - fillEtaBranch(ttbarPartonHistory, "MC_ttbar_afterFSR_eta", temp); - }//if - if (event_top){ - ttbarPartonHistory->auxdecor< float >( "MC_t_beforeFSR_m" ) = t_before.M(); - ttbarPartonHistory->auxdecor< float >( "MC_t_beforeFSR_pt" ) = t_before.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_t_beforeFSR_phi" ) = t_before.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_t_beforeFSR_eta", t_before); - - ttbarPartonHistory->auxdecor< float >( "MC_t_afterFSR_m" ) = t_after.M(); - ttbarPartonHistory->auxdecor< float >( "MC_t_afterFSR_pt" ) = t_after.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_t_afterFSR_phi" ) = t_after.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_t_afterFSR_eta", t_after); - - if (event_top_SC) { - ttbarPartonHistory->auxdecor< float >( "MC_t_afterFSR_SC_m" ) = t_after_SC.M(); - ttbarPartonHistory->auxdecor< float >( "MC_t_afterFSR_SC_pt" ) = t_after_SC.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_t_afterFSR_SC_phi" ) = t_after_SC.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_t_afterFSR_SC_eta", t_after_SC); - } - - ttbarPartonHistory->auxdecor< float >( "MC_W_from_t_m" ) = Wp.M(); - ttbarPartonHistory->auxdecor< float >( "MC_W_from_t_pt" ) = Wp.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_W_from_t_phi" ) = Wp.Phi(); - fillEtaBranch(ttbarPartonHistory, "MC_W_from_t_eta", Wp); - - ttbarPartonHistory->auxdecor< float >( "MC_b_from_t_m" ) = b.M(); - ttbarPartonHistory->auxdecor< float >( "MC_b_from_t_pt" ) = b.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_b_from_t_phi" ) = b.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_b_from_t_eta", b); - - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_t_m" ) = WpDecay1.M(); - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_t_pt" ) = WpDecay1.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_t_phi" ) = WpDecay1.Phi(); - ttbarPartonHistory->auxdecor< int >( "MC_Wdecay1_from_t_pdgId" ) = WpDecay1_pdgId; - fillEtaBranch(ttbarPartonHistory,"MC_Wdecay1_from_t_eta", WpDecay1); - - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_t_m" ) = WpDecay2.M(); - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_t_pt" ) = WpDecay2.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_t_phi" ) = WpDecay2.Phi(); - ttbarPartonHistory->auxdecor< int >( "MC_Wdecay2_from_t_pdgId" ) = WpDecay2_pdgId; - fillEtaBranch(ttbarPartonHistory,"MC_Wdecay2_from_t_eta", WpDecay2); - }//if - if (event_topbar){ - - ttbarPartonHistory->auxdecor< float >( "MC_tbar_beforeFSR_m" ) = tbar_before.M(); - ttbarPartonHistory->auxdecor< float >( "MC_tbar_beforeFSR_pt" ) = tbar_before.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_tbar_beforeFSR_phi" ) = tbar_before.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_tbar_beforeFSR_eta", tbar_before); - - ttbarPartonHistory->auxdecor< float >( "MC_tbar_afterFSR_m" ) = tbar_after.M(); - ttbarPartonHistory->auxdecor< float >( "MC_tbar_afterFSR_pt" ) = tbar_after.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_tbar_afterFSR_phi" ) = tbar_after.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_tbar_afterFSR_eta", tbar_after); - - if (event_topbar_SC) { - ttbarPartonHistory->auxdecor< float >( "MC_tbar_afterFSR_SC_m" ) = tbar_after_SC.M(); - ttbarPartonHistory->auxdecor< float >( "MC_tbar_afterFSR_SC_pt" ) = tbar_after_SC.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_tbar_afterFSR_SC_phi" ) = tbar_after_SC.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_tbar_afterFSR_SC_eta", tbar_after_SC); - } - - ttbarPartonHistory->auxdecor< float >( "MC_W_from_tbar_m" ) = Wm.M(); - ttbarPartonHistory->auxdecor< float >( "MC_W_from_tbar_pt" ) = Wm.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_W_from_tbar_phi" ) = Wm.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_W_from_tbar_eta", Wm); - - ttbarPartonHistory->auxdecor< float >( "MC_b_from_tbar_m" ) = bbar.M(); - ttbarPartonHistory->auxdecor< float >( "MC_b_from_tbar_pt" ) = bbar.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_b_from_tbar_phi" ) = bbar.Phi(); - fillEtaBranch(ttbarPartonHistory,"MC_b_from_tbar_eta", bbar); - - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_tbar_m" ) = WmDecay1.M(); - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_tbar_pt" ) = WmDecay1.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay1_from_tbar_phi" ) = WmDecay1.Phi(); - ttbarPartonHistory->auxdecor< int >( "MC_Wdecay1_from_tbar_pdgId" ) = WmDecay1_pdgId; - fillEtaBranch(ttbarPartonHistory,"MC_Wdecay1_from_tbar_eta", WmDecay1); - - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_tbar_m" ) = WmDecay2.M(); - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_tbar_pt" ) = WmDecay2.Pt(); - ttbarPartonHistory->auxdecor< float >( "MC_Wdecay2_from_tbar_phi" ) = WmDecay2.Phi(); - ttbarPartonHistory->auxdecor< int >( "MC_Wdecay2_from_tbar_pdgId" ) = WmDecay2_pdgId; - fillEtaBranch(ttbarPartonHistory,"MC_Wdecay2_from_tbar_eta", WmDecay2); - }//if - +namespace top { + CalcTtbarPartonHistory::CalcTtbarPartonHistory(const std::string& name) : CalcTopPartonHistory(name) {} + + void CalcTtbarPartonHistory::ttbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* ttbarPartonHistory) { + ttbarPartonHistory->IniVarTtbar(); + + TLorentzVector t_before, t_after, t_after_SC; + TLorentzVector Wp; + TLorentzVector b; + TLorentzVector WpDecay1; + TLorentzVector WpDecay2; + int WpDecay1_pdgId; + int WpDecay2_pdgId; + + bool event_top = CalcTopPartonHistory::topWb(truthParticles, 6, t_before, t_after, Wp, b, WpDecay1, WpDecay1_pdgId, + WpDecay2, WpDecay2_pdgId); + bool event_top_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, 6, t_after_SC); + + TLorentzVector tbar_before, tbar_after, tbar_after_SC; + TLorentzVector Wm; + TLorentzVector bbar; + TLorentzVector WmDecay1; + TLorentzVector WmDecay2; + int WmDecay1_pdgId; + int WmDecay2_pdgId; + + bool event_topbar = CalcTopPartonHistory::topWb(truthParticles, -6, tbar_before, tbar_after, Wm, bbar, WmDecay1, + WmDecay1_pdgId, WmDecay2, WmDecay2_pdgId); + bool event_topbar_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, -6, tbar_after_SC); + + if (event_top && event_topbar) { + TLorentzVector temp = t_before + tbar_before; + ttbarPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_m") = temp.M(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_pt") = temp.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_beforeFSR_phi") = temp.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_ttbar_beforeFSR_eta", temp); + + temp = t_after + tbar_after; + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_beforeDecay_m") = temp.M(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_beforeDecay_pt") = temp.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_beforeDecay_phi") = temp.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_ttbar_afterFSR_beforeDecay_eta", temp); + + temp = WmDecay1 + WmDecay2 + b + WpDecay1 + WpDecay2 + bbar; + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_m") = temp.M(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_pt") = temp.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_ttbar_afterFSR_phi") = temp.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_ttbar_afterFSR_eta", temp); + }//if + if (event_top) { + ttbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_m") = t_before.M(); + ttbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_pt") = t_before.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_t_beforeFSR_phi") = t_before.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_t_beforeFSR_eta", t_before); + + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_m") = t_after.M(); + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_pt") = t_after.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_phi") = t_after.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_t_afterFSR_eta", t_after); + + if (event_top_SC) { + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_m") = t_after_SC.M(); + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_pt") = t_after_SC.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_phi") = t_after_SC.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_t_afterFSR_SC_eta", t_after_SC); + } + + ttbarPartonHistory->auxdecor< float >("MC_W_from_t_m") = Wp.M(); + ttbarPartonHistory->auxdecor< float >("MC_W_from_t_pt") = Wp.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_W_from_t_phi") = Wp.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_W_from_t_eta", Wp); + + ttbarPartonHistory->auxdecor< float >("MC_b_from_t_m") = b.M(); + ttbarPartonHistory->auxdecor< float >("MC_b_from_t_pt") = b.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_b_from_t_phi") = b.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_b_from_t_eta", b); + + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_m") = WpDecay1.M(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_pt") = WpDecay1.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_phi") = WpDecay1.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = WpDecay1_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_Wdecay1_from_t_eta", WpDecay1); + + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_m") = WpDecay2.M(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_pt") = WpDecay2.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_phi") = WpDecay2.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = WpDecay2_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_Wdecay2_from_t_eta", WpDecay2); + }//if + if (event_topbar) { + ttbarPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_m") = tbar_before.M(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_pt") = tbar_before.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_beforeFSR_phi") = tbar_before.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_tbar_beforeFSR_eta", tbar_before); + + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_m") = tbar_after.M(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_pt") = tbar_after.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_phi") = tbar_after.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_tbar_afterFSR_eta", tbar_after); + + if (event_topbar_SC) { + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_SC_m") = tbar_after_SC.M(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_SC_pt") = tbar_after_SC.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_tbar_afterFSR_SC_phi") = tbar_after_SC.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_tbar_afterFSR_SC_eta", tbar_after_SC); + } + + ttbarPartonHistory->auxdecor< float >("MC_W_from_tbar_m") = Wm.M(); + ttbarPartonHistory->auxdecor< float >("MC_W_from_tbar_pt") = Wm.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_W_from_tbar_phi") = Wm.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_W_from_tbar_eta", Wm); + + ttbarPartonHistory->auxdecor< float >("MC_b_from_tbar_m") = bbar.M(); + ttbarPartonHistory->auxdecor< float >("MC_b_from_tbar_pt") = bbar.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_b_from_tbar_phi") = bbar.Phi(); + fillEtaBranch(ttbarPartonHistory, "MC_b_from_tbar_eta", bbar); + + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_m") = WmDecay1.M(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_pt") = WmDecay1.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay1_from_tbar_phi") = WmDecay1.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Wdecay1_from_tbar_pdgId") = WmDecay1_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_Wdecay1_from_tbar_eta", WmDecay1); + + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_m") = WmDecay2.M(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_pt") = WmDecay2.Pt(); + ttbarPartonHistory->auxdecor< float >("MC_Wdecay2_from_tbar_phi") = WmDecay2.Phi(); + ttbarPartonHistory->auxdecor< int >("MC_Wdecay2_from_tbar_pdgId") = WmDecay2_pdgId; + fillEtaBranch(ttbarPartonHistory, "MC_Wdecay2_from_tbar_eta", WmDecay2); + }//if } - StatusCode CalcTtbarPartonHistory::execute() - { - // Get the Truth Particles - const xAOD::TruthParticleContainer* truthParticles(nullptr); - ATH_CHECK( evtStore()->retrieve( truthParticles , m_config->sgKeyMCParticle() ) ); - - // Create the partonHistory xAOD object - xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer{}; - xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer{}; - partonCont->setStore( partonAuxCont ); - - xAOD::PartonHistory* ttbarPartonHistory = new xAOD::PartonHistory{}; - partonCont->push_back( ttbarPartonHistory ); - - // Recover the parton history for ttbar events - ttbarHistorySaver(truthParticles, ttbarPartonHistory); - - // Save to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyTopPartonHistory(); - std::string outputSGKeyAux = outputSGKey + "Aux."; + StatusCode CalcTtbarPartonHistory::execute() { + // Get the Truth Particles + + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + if(m_config->getDerivationStream() == "PHYS") //in DAOD_PHYS we don't have the truth particles container + { + //the functions ued in this class always start from the top, so it's enough to do the following + std::vector<std::string> collections = {"TruthTop"}; + ATH_CHECK(buildContainerFromMultipleCollections(collections,"AT_TTbarPartonHistory_TruthParticles")); + ATH_CHECK(evtStore()->retrieve(truthParticles, "AT_TTbarPartonHistory_TruthParticles")); - xAOD::TReturnCode save = evtStore()->tds()->record( partonCont , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( partonAuxCont , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } + //we need to be able to navigate from the Ws to their decayProducts, see CalcTopPartonHistory.h for details + ATH_CHECK(linkBosonCollections()); + + } + else //otherwise we retrieve the container as usual + { + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + } + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* ttbarPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(ttbarPartonHistory); + + // Recover the parton history for ttbar events + ttbarHistorySaver(truthParticles, ttbarPartonHistory); - return StatusCode::SUCCESS; - } + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTzqPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTzqPartonHistory.cxx new file mode 100644 index 000000000000..f5e8b8ca6582 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcTzqPartonHistory.cxx @@ -0,0 +1,208 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopPartons/CalcTzqPartonHistory.h" +#include "TopPartons/CalcTopPartonHistory.h" +#include "TopConfiguration/TopConfig.h" +#include <iostream> + + +namespace top { + CalcTzqPartonHistory::CalcTzqPartonHistory(const std::string& name) : CalcTopPartonHistory(name) {} + const xAOD::TruthParticle* CalcTzqPartonHistory::findAfterGamma(const xAOD::TruthParticle* particle) { + bool isAfterGamma(false); + const int particle_ID = particle->pdgId(); + int forLoop; + + while (!isAfterGamma) { + forLoop = 0; + for (size_t j = 0; j < particle->nChildren(); j++) { + const xAOD::TruthParticle* tmp_children = particle->child(j); + if (tmp_children && tmp_children->pdgId() == particle_ID && tmp_children->pdgId() != 22) { + particle = particle->child(j); + forLoop++; + break; + }//if + }//for + + if (forLoop == 0) isAfterGamma = true; + }//while + return particle; + } + + int CalcTzqPartonHistory::sign(int a) { + if (a < 0) { + return -1; + } else return 1; + } + + bool CalcTzqPartonHistory::bottom(const xAOD::TruthParticleContainer* truthParticles, int start) { + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle->pdgId() != start) { + continue; + } + tZ.b_p4 = particle->p4(); + tZ.b_pdgId = particle->pdgId(); + return true; + } + return false; + } + + bool CalcTzqPartonHistory::Zllqq(const xAOD::TruthParticleContainer* truthParticles, int start) { + + for (const xAOD::TruthParticle* particle : *truthParticles) { + if (particle->pdgId() != start || particle->nChildren() != 2) { + continue; + } + tZ.Z_p4 = particle->p4(); + + for (size_t k = 0; k < particle->nChildren(); k++) { + + const xAOD::TruthParticle* ZChildren = particle->child(k); + if (ZChildren->pdgId() > 0) { + tZ.Zdecay1_p4 = findAfterGamma(ZChildren)->p4(); + tZ.Zdecay1_pdgId = ZChildren->pdgId(); + tZ.Zdecay1_status = ZChildren->status(); + } else { + tZ.Zdecay2_p4 = findAfterGamma(ZChildren)->p4(); + tZ.Zdecay2_pdgId = ZChildren->pdgId(); + tZ.Zdecay1_status = ZChildren->status(); + } + } //for + // here we ask to return true if it identifies the particle and its children correctly. + return true; + } + return false; + } + + void CalcTzqPartonHistory::TZHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* TzqPartonHistory) { + TzqPartonHistory->IniVarTzq(); + TLorentzVector t_before, t_after, t_after_SC; + TLorentzVector Wp; + TLorentzVector b; + TLorentzVector WpDecay1; + TLorentzVector WpDecay2; + int WpDecay1_pdgId; + int WpDecay2_pdgId; + + bool event_top = CalcTopPartonHistory::topWb(truthParticles, 6, t_before, t_after, Wp, b, WpDecay1, WpDecay1_pdgId, + WpDecay2, WpDecay2_pdgId); + bool event_top_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, 6, t_after_SC); + bool event_topbar = CalcTopPartonHistory::topWb(truthParticles, -6, t_before, t_after, Wp, b, WpDecay1, + WpDecay1_pdgId, WpDecay2, WpDecay2_pdgId); + bool event_topbar_SC = CalcTopPartonHistory::topAfterFSR_SC(truthParticles, -6, t_after_SC); + bool event_Z = CalcTzqPartonHistory::Zllqq(truthParticles, 23); + bool event_bottom = CalcTzqPartonHistory::bottom(truthParticles, 5); + bool event_bottombar = CalcTzqPartonHistory::bottom(truthParticles, -5); + + + if (event_Z) { + if ((event_top && event_bottombar) || (event_topbar && event_bottom)) { + TzqPartonHistory->auxdecor< float >("MC_t_beforeFSR_m") = t_before.M(); + TzqPartonHistory->auxdecor< float >("MC_t_beforeFSR_pt") = t_before.Pt(); + TzqPartonHistory->auxdecor< float >("MC_t_beforeFSR_phi") = t_before.Phi(); + fillEtaBranch(TzqPartonHistory, "MC_t_beforeFSR_eta", t_before); + + TzqPartonHistory->auxdecor< float >("MC_t_afterFSR_m") = t_after.M(); + TzqPartonHistory->auxdecor< float >("MC_t_afterFSR_pt") = t_after.Pt(); + TzqPartonHistory->auxdecor< float >("MC_t_afterFSR_phi") = t_after.Phi(); + fillEtaBranch(TzqPartonHistory, "MC_t_afterFSR_eta", t_after); + + if (event_top_SC || event_topbar_SC) { + TzqPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_m") = t_after_SC.M(); + TzqPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_pt") = t_after_SC.Pt(); + TzqPartonHistory->auxdecor< float >("MC_t_afterFSR_SC_phi") = t_after_SC.Phi(); + fillEtaBranch(TzqPartonHistory, "MC_t_afterFSR_SC_eta", t_after_SC); + } + + TzqPartonHistory->auxdecor< float >("MC_W_from_t_m") = Wp.M(); + TzqPartonHistory->auxdecor< float >("MC_W_from_t_pt") = Wp.Pt(); + TzqPartonHistory->auxdecor< float >("MC_W_from_t_phi") = Wp.Phi(); + fillEtaBranch(TzqPartonHistory, "MC_W_from_t_eta", Wp); + + TzqPartonHistory->auxdecor< float >("MC_b_from_t_m") = b.M(); + TzqPartonHistory->auxdecor< float >("MC_b_from_t_pt") = b.Pt(); + TzqPartonHistory->auxdecor< float >("MC_b_from_t_phi") = b.Phi(); + fillEtaBranch(TzqPartonHistory, "MC_b_from_t_eta", b); + + TzqPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_m") = WpDecay1.M(); + TzqPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_pt") = WpDecay1.Pt(); + TzqPartonHistory->auxdecor< float >("MC_Wdecay1_from_t_phi") = WpDecay1.Phi(); + TzqPartonHistory->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = WpDecay1_pdgId; + fillEtaBranch(TzqPartonHistory, "MC_Wdecay1_from_t_eta", WpDecay1); + + TzqPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_m") = WpDecay2.M(); + TzqPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_pt") = WpDecay2.Pt(); + TzqPartonHistory->auxdecor< float >("MC_Wdecay2_from_t_phi") = WpDecay2.Phi(); + TzqPartonHistory->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = WpDecay2_pdgId; + fillEtaBranch(TzqPartonHistory, "MC_Wdecay2_from_t_eta", WpDecay2); + + //Z-Variables + TzqPartonHistory->auxdecor< float >("MC_Z_m") = tZ.Z_p4.M(); + TzqPartonHistory->auxdecor< float >("MC_Z_pt") = tZ.Z_p4.Pt(); + TzqPartonHistory->auxdecor< float >("MC_Z_phi") = tZ.Z_p4.Phi(); + fillEtaBranch(TzqPartonHistory, "MC_Z_eta", tZ.Z_p4); + + + //First Decay (Zdecay1) + TzqPartonHistory->auxdecor< float >("MC_Zdecay1_m") = tZ.Zdecay1_p4.M(); + TzqPartonHistory->auxdecor< float >("MC_Zdecay1_pt") = tZ.Zdecay1_p4.Pt(); + TzqPartonHistory->auxdecor< float >("MC_Zdecay1_phi") = tZ.Zdecay1_p4.Phi(); + TzqPartonHistory->auxdecor< int >("MC_Zdecay1_pdgId") = tZ.Zdecay1_pdgId; + TzqPartonHistory->auxdecor< int >("MC_Zdecay1_status") = tZ.Zdecay1_status; + fillEtaBranch(TzqPartonHistory, "MC_Zdecay1_eta", tZ.Zdecay1_p4); + + //Second Decay (Zdecay2) + TzqPartonHistory->auxdecor< float >("MC_Zdecay2_m") = tZ.Zdecay2_p4.M(); + TzqPartonHistory->auxdecor< float >("MC_Zdecay2_pt") = tZ.Zdecay2_p4.Pt(); + TzqPartonHistory->auxdecor< float >("MC_Zdecay2_phi") = tZ.Zdecay2_p4.Phi(); + TzqPartonHistory->auxdecor< int >("MC_Zdecay2_pdgId") = tZ.Zdecay2_pdgId; + TzqPartonHistory->auxdecor< int >("MC_Zdecay2_status") = tZ.Zdecay2_status; + fillEtaBranch(TzqPartonHistory, "MC_Zdecay2_eta", tZ.Zdecay2_p4); + + + + //b quark + TzqPartonHistory->auxdecor< float >("MC_b_m") = tZ.b_p4.M(); + TzqPartonHistory->auxdecor< float >("MC_b_pt") = tZ.b_p4.Pt(); + TzqPartonHistory->auxdecor< float >("MC_b_phi") = tZ.b_p4.Phi(); + TzqPartonHistory->auxdecor< int >("MC_b_pdgId") = tZ.b_pdgId; + fillEtaBranch(TzqPartonHistory, "MC_b_eta", tZ.b_p4); + + + } + } + } + + StatusCode CalcTzqPartonHistory::execute() { + //Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* TzqPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(TzqPartonHistory); + + // Recover the parton history for TZ events + TZHistorySaver(truthParticles, TzqPartonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcWlvPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcWlvPartonHistory.cxx index b99e3f04aa25..ba9ee65c9fe8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcWlvPartonHistory.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcWlvPartonHistory.cxx @@ -1,76 +1,73 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #include "TopPartons/CalcWlvPartonHistory.h" #include "TopConfiguration/TopConfig.h" -namespace top{ - - CalcWlvPartonHistory::CalcWlvPartonHistory(const std::string& name) : CalcTopPartonHistory( name ){} - - void CalcWlvPartonHistory::WlvHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* wlvPartonHistory){ - - wlvPartonHistory->IniVarWlv(); - - TLorentzVector W; - TLorentzVector WDecay1; - TLorentzVector WDecay2; - int WDecay1_pdgId; - int WDecay2_pdgId; - bool goodevent = CalcTopPartonHistory::Wlv(truthParticles, W, WDecay1, WDecay1_pdgId, WDecay2, WDecay2_pdgId); - - - if (goodevent){ - wlvPartonHistory->auxdecor< float >( "MC_W_m" ) = W.M(); - wlvPartonHistory->auxdecor< float >( "MC_W_pt" ) = W.Pt(); - wlvPartonHistory->auxdecor< float >( "MC_W_phi" ) = W.Phi(); - fillEtaBranch(wlvPartonHistory, "MC_W_eta", W); - - - wlvPartonHistory->auxdecor< float >( "MC_l_m" ) = WDecay1.M(); - wlvPartonHistory->auxdecor< float >( "MC_l_pt" ) = WDecay1.Pt(); - wlvPartonHistory->auxdecor< float >( "MC_l_phi" ) = WDecay1.Phi(); - wlvPartonHistory->auxdecor< int >( "MC_l_pdgId" ) = WDecay1_pdgId; - fillEtaBranch(wlvPartonHistory,"MC_l_eta", WDecay1); - - wlvPartonHistory->auxdecor< float >( "MC_v_m" ) = WDecay2.M(); - wlvPartonHistory->auxdecor< float >( "MC_v_pt" ) = WDecay2.Pt(); - wlvPartonHistory->auxdecor< float >( "MC_v_phi" ) = WDecay2.Phi(); - wlvPartonHistory->auxdecor< int >( "MC_v_pdgId" ) = WDecay2_pdgId; - fillEtaBranch(wlvPartonHistory,"MC_v_eta", WDecay2); - }//if - - +namespace top { + CalcWlvPartonHistory::CalcWlvPartonHistory(const std::string& name) : CalcTopPartonHistory(name) {} + + void CalcWlvPartonHistory::WlvHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* wlvPartonHistory) { + wlvPartonHistory->IniVarWlv(); + + TLorentzVector W; + TLorentzVector WDecay1; + TLorentzVector WDecay2; + int WDecay1_pdgId; + int WDecay2_pdgId; + bool goodevent = CalcTopPartonHistory::Wlv(truthParticles, W, WDecay1, WDecay1_pdgId, WDecay2, WDecay2_pdgId); + + + if (goodevent) { + wlvPartonHistory->auxdecor< float >("MC_W_m") = W.M(); + wlvPartonHistory->auxdecor< float >("MC_W_pt") = W.Pt(); + wlvPartonHistory->auxdecor< float >("MC_W_phi") = W.Phi(); + fillEtaBranch(wlvPartonHistory, "MC_W_eta", W); + + + wlvPartonHistory->auxdecor< float >("MC_l_m") = WDecay1.M(); + wlvPartonHistory->auxdecor< float >("MC_l_pt") = WDecay1.Pt(); + wlvPartonHistory->auxdecor< float >("MC_l_phi") = WDecay1.Phi(); + wlvPartonHistory->auxdecor< int >("MC_l_pdgId") = WDecay1_pdgId; + fillEtaBranch(wlvPartonHistory, "MC_l_eta", WDecay1); + + wlvPartonHistory->auxdecor< float >("MC_v_m") = WDecay2.M(); + wlvPartonHistory->auxdecor< float >("MC_v_pt") = WDecay2.Pt(); + wlvPartonHistory->auxdecor< float >("MC_v_phi") = WDecay2.Phi(); + wlvPartonHistory->auxdecor< int >("MC_v_pdgId") = WDecay2_pdgId; + fillEtaBranch(wlvPartonHistory, "MC_v_eta", WDecay2); + }//if } - StatusCode CalcWlvPartonHistory::execute() - { - // Get the Truth Particles - const xAOD::TruthParticleContainer* truthParticles(nullptr); - ATH_CHECK( evtStore()->retrieve( truthParticles , m_config->sgKeyMCParticle() ) ); - - // Create the partonHistory xAOD object - xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer{}; - xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer{}; - partonCont->setStore( partonAuxCont ); - - xAOD::PartonHistory* wlvPartonHistory = new xAOD::PartonHistory{}; - partonCont->push_back( wlvPartonHistory ); - - // Recover the parton history for wlv events - WlvHistorySaver(truthParticles, wlvPartonHistory); - - // Save to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyTopPartonHistory(); - std::string outputSGKeyAux = outputSGKey + "Aux."; - - xAOD::TReturnCode save = evtStore()->tds()->record( partonCont , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( partonAuxCont , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } - - return StatusCode::SUCCESS; + StatusCode CalcWlvPartonHistory::execute() { + // Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* wlvPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(wlvPartonHistory); + + // Recover the parton history for wlv events + WlvHistorySaver(truthParticles, wlvPartonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcWtbPartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcWtbPartonHistory.cxx new file mode 100644 index 000000000000..2b87b3cbf03c --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/CalcWtbPartonHistory.cxx @@ -0,0 +1,184 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopPartons/CalcWtbPartonHistory.h" +#include "TopConfiguration/TopConfig.h" + +namespace top { + CalcWtbPartonHistory::CalcWtbPartonHistory(const std::string& name) : CalcTopPartonHistory(name) {} + + void CalcWtbPartonHistory::wtbHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* wtbPartonHistory) { + wtbPartonHistory->IniVarWtb(); + + TLorentzVector t_before, t_after; + TLorentzVector antit_before, antit_after; + TLorentzVector WfromTop; + TLorentzVector bFromTop; + TLorentzVector WfromTopDecay1; + TLorentzVector WfromTopDecay2; + int WfromTopDecay1_pdgId; + int WfromTopDecay2_pdgId; + + bool event_top = CalcTopPartonHistory::topWb(truthParticles, 6, t_before, t_after, WfromTop, bFromTop, + WfromTopDecay1, WfromTopDecay1_pdgId, WfromTopDecay2, + WfromTopDecay2_pdgId); + + TLorentzVector WfromAntiTop; + TLorentzVector bFromAntiTop; + TLorentzVector WfromAntiTopDecay1; + TLorentzVector WfromAntiTopDecay2; + int WfromAntiTopDecay1_pdgId; + int WfromAntiTopDecay2_pdgId; + + bool event_antitop = CalcTopPartonHistory::topWb(truthParticles, -6, antit_before, antit_after, WfromAntiTop, + bFromAntiTop, WfromAntiTopDecay1, WfromAntiTopDecay1_pdgId, + WfromAntiTopDecay2, WfromAntiTopDecay2_pdgId); + + TLorentzVector WnotFromTop; + TLorentzVector WnotFromTopDecay1; + TLorentzVector WnotFromTopDecay2; + int WnotFromTop_pdgId; + int WnotFromTopDecay1_pdgId; + int WnotFromTopDecay2_pdgId; + + bool event_WnotTop = CalcTopPartonHistory::Wt_W(truthParticles, WnotFromTop, WnotFromTop_pdgId, WnotFromTopDecay1, + WnotFromTopDecay1_pdgId, WnotFromTopDecay2, + WnotFromTopDecay2_pdgId); + + TLorentzVector bNotFromTop_before; + TLorentzVector bNotFromTop_after; + int bNotFromTop_pdgId; + + bool event_b = CalcTopPartonHistory::Wt_b(truthParticles, bNotFromTop_before, bNotFromTop_after, bNotFromTop_pdgId); + + if (event_top && !event_antitop) { + wtbPartonHistory->auxdecor< float >("MC_top_beforeFSR_pt") = t_before.Pt(); + wtbPartonHistory->auxdecor< float >("MC_top_beforeFSR_eta") = t_before.Eta(); + wtbPartonHistory->auxdecor< float >("MC_top_beforeFSR_phi") = t_before.Phi(); + wtbPartonHistory->auxdecor< float >("MC_top_beforeFSR_m") = t_before.M(); + + wtbPartonHistory->auxdecor< float >("MC_top_afterFSR_pt") = t_after.Pt(); + wtbPartonHistory->auxdecor< float >("MC_top_afterFSR_eta") = t_after.Eta(); + wtbPartonHistory->auxdecor< float >("MC_top_afterFSR_phi") = t_after.Phi(); + wtbPartonHistory->auxdecor< float >("MC_top_afterFSR_m") = t_after.M(); + + wtbPartonHistory->auxdecor< float >("MC_b_from_top_pt") = bFromTop.Pt(); + wtbPartonHistory->auxdecor< float >("MC_b_from_top_eta") = bFromTop.Eta(); + wtbPartonHistory->auxdecor< float >("MC_b_from_top_phi") = bFromTop.Phi(); + wtbPartonHistory->auxdecor< float >("MC_b_from_top_m") = bFromTop.M(); + + wtbPartonHistory->auxdecor< float >("MC_W_from_top_pt") = WfromTop.Pt(); + wtbPartonHistory->auxdecor< float >("MC_W_from_top_eta") = WfromTop.Eta(); + wtbPartonHistory->auxdecor< float >("MC_W_from_top_phi") = WfromTop.Phi(); + wtbPartonHistory->auxdecor< float >("MC_W_from_top_m") = WfromTop.M(); + + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_from_top_pt") = WfromTopDecay1.Pt(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_from_top_eta") = WfromTopDecay1.Eta(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_from_top_phi") = WfromTopDecay1.Phi(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_from_top_m") = WfromTopDecay1.M(); + wtbPartonHistory->auxdecor< int >("MC_Wdecay1_from_top_pdgId") = WfromTopDecay1_pdgId; + + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_from_top_pt") = WfromTopDecay2.Pt(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_from_top_eta") = WfromTopDecay2.Eta(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_from_top_phi") = WfromTopDecay2.Phi(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_from_top_m") = WfromTopDecay2.M(); + wtbPartonHistory->auxdecor< int >("MC_Wdecay2_from_top_pdgId") = WfromTopDecay2_pdgId; + } else if (!event_top && event_antitop) { + wtbPartonHistory->auxdecor< float >("MC_top_beforeFSR_pt") = antit_before.Pt(); + wtbPartonHistory->auxdecor< float >("MC_top_beforeFSR_eta") = antit_before.Eta(); + wtbPartonHistory->auxdecor< float >("MC_top_beforeFSR_phi") = antit_before.Phi(); + wtbPartonHistory->auxdecor< float >("MC_top_beforeFSR_m") = antit_before.M(); + + wtbPartonHistory->auxdecor< float >("MC_top_afterFSR_pt") = antit_after.Pt(); + wtbPartonHistory->auxdecor< float >("MC_top_afterFSR_eta") = antit_after.Eta(); + wtbPartonHistory->auxdecor< float >("MC_top_afterFSR_phi") = antit_after.Phi(); + wtbPartonHistory->auxdecor< float >("MC_top_afterFSR_m") = antit_after.M(); + + wtbPartonHistory->auxdecor< float >("MC_b_from_top_pt") = bFromAntiTop.Pt(); + wtbPartonHistory->auxdecor< float >("MC_b_from_top_eta") = bFromAntiTop.Eta(); + wtbPartonHistory->auxdecor< float >("MC_b_from_top_phi") = bFromAntiTop.Phi(); + wtbPartonHistory->auxdecor< float >("MC_b_from_top_m") = bFromAntiTop.M(); + + wtbPartonHistory->auxdecor< float >("MC_W_from_top_pt") = WfromAntiTop.Pt(); + wtbPartonHistory->auxdecor< float >("MC_W_from_top_eta") = WfromAntiTop.Eta(); + wtbPartonHistory->auxdecor< float >("MC_W_from_top_phi") = WfromAntiTop.Phi(); + wtbPartonHistory->auxdecor< float >("MC_W_from_top_m") = WfromAntiTop.M(); + + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_from_top_pt") = WfromAntiTopDecay1.Pt(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_from_top_eta") = WfromAntiTopDecay1.Eta(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_from_top_phi") = WfromAntiTopDecay1.Phi(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_from_top_m") = WfromAntiTopDecay1.M(); + wtbPartonHistory->auxdecor< int >("MC_Wdecay1_from_top_pdgId") = WfromAntiTopDecay1_pdgId; + + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_from_top_pt") = WfromAntiTopDecay2.Pt(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_from_top_eta") = WfromAntiTopDecay2.Eta(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_from_top_phi") = WfromAntiTopDecay2.Phi(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_from_top_m") = WfromAntiTopDecay2.M(); + wtbPartonHistory->auxdecor< int >("MC_Wdecay2_from_top_pdgId") = WfromAntiTopDecay2_pdgId; + } + + if (((event_top && !event_antitop) || (!event_top && event_antitop)) && event_WnotTop) { + wtbPartonHistory->auxdecor< float >("MC_W_not_from_top_pt") = WnotFromTop.Pt(); + wtbPartonHistory->auxdecor< float >("MC_W_not_from_top_eta") = WnotFromTop.Eta(); + wtbPartonHistory->auxdecor< float >("MC_W_not_from_top_phi") = WnotFromTop.Phi(); + wtbPartonHistory->auxdecor< float >("MC_W_not_from_top_m") = WnotFromTop.M(); + + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_not_from_top_pt") = WnotFromTopDecay1.Pt(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_not_from_top_eta") = WnotFromTopDecay1.Eta(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_not_from_top_phi") = WnotFromTopDecay1.Phi(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay1_not_from_top_m") = WnotFromTopDecay1.M(); + wtbPartonHistory->auxdecor< int >("MC_Wdecay1_not_from_top_pdgId") = WnotFromTopDecay1_pdgId; + + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_not_from_top_pt") = WnotFromTopDecay2.Pt(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_not_from_top_eta") = WnotFromTopDecay2.Eta(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_not_from_top_phi") = WnotFromTopDecay2.Phi(); + wtbPartonHistory->auxdecor< float >("MC_Wdecay2_not_from_top_m") = WnotFromTopDecay2.M(); + wtbPartonHistory->auxdecor< int >("MC_Wdecay2_not_from_top_pdgId") = WnotFromTopDecay2_pdgId; + }//if + + if (((event_top && !event_antitop) || (!event_top && event_antitop)) && event_b) { + wtbPartonHistory->auxdecor< float >("MC_b_not_from_top_beforeFSR_pt") = bNotFromTop_before.Pt(); + wtbPartonHistory->auxdecor< float >("MC_b_not_from_top_beforeFSR_eta") = bNotFromTop_before.Eta(); + wtbPartonHistory->auxdecor< float >("MC_b_not_from_top_beforeFSR_phi") = bNotFromTop_before.Phi(); + wtbPartonHistory->auxdecor< float >("MC_b_not_from_top_beforeFSR_m") = bNotFromTop_before.M(); + wtbPartonHistory->auxdecor< int >("MC_b_not_from_top_pdgId") = bNotFromTop_pdgId; + + wtbPartonHistory->auxdecor< float >("MC_b_not_from_top_afterFSR_pt") = bNotFromTop_after.Pt(); + wtbPartonHistory->auxdecor< float >("MC_b_not_from_top_afterFSR_eta") = bNotFromTop_after.Eta(); + wtbPartonHistory->auxdecor< float >("MC_b_not_from_top_afterFSR_phi") = bNotFromTop_after.Phi(); + wtbPartonHistory->auxdecor< float >("MC_b_not_from_top_afterFSR_m") = bNotFromTop_after.M(); + } + } + + StatusCode CalcWtbPartonHistory::execute() { + // Get the Truth Particles + const xAOD::TruthParticleContainer* truthParticles(nullptr); + + ATH_CHECK(evtStore()->retrieve(truthParticles, m_config->sgKeyMCParticle())); + + // Create the partonHistory xAOD object + xAOD::PartonHistoryAuxContainer* partonAuxCont = new xAOD::PartonHistoryAuxContainer {}; + xAOD::PartonHistoryContainer* partonCont = new xAOD::PartonHistoryContainer {}; + partonCont->setStore(partonAuxCont); + + xAOD::PartonHistory* wtbPartonHistory = new xAOD::PartonHistory {}; + partonCont->push_back(wtbPartonHistory); + + // Recover the parton history for Wt SingleTop events + wtbHistorySaver(truthParticles, wtbPartonHistory); + + // Save to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyTopPartonHistory(); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(partonCont, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(partonAuxCont, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/LinkDef.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/LinkDef.h index c5ad90ea174f..aa61c603d751 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/LinkDef.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/LinkDef.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ #include "TopPartons/PartonHistory.h" diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/PartonHistory.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/PartonHistory.cxx index 89085e0bb9bd..5ffdcbc102b0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/PartonHistory.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/PartonHistory.cxx @@ -1,193 +1,622 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ // $Id: PartonHistory.cxx 800464 2017-03-13 18:06:24Z tpelzer $ #include "TopPartons/PartonHistory.h" #include "xAODCore/AddDVProxy.h" -namespace xAOD{ - /// Aux Container +namespace xAOD { + /// Aux Container PartonHistoryAuxContainer::PartonHistoryAuxContainer() : - AuxContainerBase() - { + AuxContainerBase() { } - + /// Interface class PartonHistory::PartonHistory() : - SG::AuxElement() - { + SG::AuxElement() { } //Initialize variables for ttbar events - void PartonHistory::IniVarTtbar(){ - - //ttbar variables - this->auxdecor< float >( "MC_ttbar_beforeFSR_m" ) = -1; - this->auxdecor< float >( "MC_ttbar_beforeFSR_pt") = -1; - this->auxdecor< float >( "MC_ttbar_beforeFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_ttbar_beforeFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_ttbar_afterFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_ttbar_afterFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_ttbar_afterFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_ttbar_afterFSR_phi" ) = -1000 ; - - //t variables - this->auxdecor< float >( "MC_t_beforeFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_t_beforeFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_t_beforeFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_t_beforeFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_t_afterFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_t_afterFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_t_afterFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_t_afterFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_t_afterFSR_SC_m" ) = -1 ; - this->auxdecor< float >( "MC_t_afterFSR_SC_pt" ) = -1 ; - this->auxdecor< float >( "MC_t_afterFSR_SC_eta" ) = -1000 ; - this->auxdecor< float >( "MC_t_afterFSR_SC_phi" ) = -1000 ; - - //tbar variables - this->auxdecor< float >( "MC_tbar_beforeFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_tbar_beforeFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_tbar_beforeFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_tbar_beforeFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_tbar_afterFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_tbar_afterFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_tbar_afterFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_tbar_afterFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_tbar_afterFSR_SC_m" ) = -1 ; - this->auxdecor< float >( "MC_tbar_afterFSR_SC_pt" ) = -1 ; - this->auxdecor< float >( "MC_tbar_afterFSR_SC_eta" ) = -1000 ; - this->auxdecor< float >( "MC_tbar_afterFSR_SC_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_W_from_t_m" ) = -1 ; - this->auxdecor< float >( "MC_W_from_t_pt" ) = -1 ; - this->auxdecor< float >( "MC_W_from_t_eta" ) = -1000 ; - this->auxdecor< float >( "MC_W_from_t_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_W_from_tbar_m" ) = -1 ; - this->auxdecor< float >( "MC_W_from_tbar_pt" ) = -1 ; - this->auxdecor< float >( "MC_W_from_tbar_eta" ) = -1000 ; - this->auxdecor< float >( "MC_W_from_tbar_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_b_from_t_m" ) = -1 ; - this->auxdecor< float >( "MC_b_from_t_pt" ) = -1 ; - this->auxdecor< float >( "MC_b_from_t_eta" ) = -1000 ; - this->auxdecor< float >( "MC_b_from_t_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_b_from_tbar_m" ) = -1 ; - this->auxdecor< float >( "MC_b_from_tbar_pt" ) = -1 ; - this->auxdecor< float >( "MC_b_from_tbar_eta" ) = -1000 ; - this->auxdecor< float >( "MC_b_from_tbar_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_Wdecay1_from_t_m" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay1_from_t_pt" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay1_from_t_eta" ) = -1000 ; - this->auxdecor< float >( "MC_Wdecay1_from_t_phi" ) = -1000 ; - this->auxdecor< int >( "MC_Wdecay1_from_t_pdgId") = 0 ; - - this->auxdecor< float >( "MC_Wdecay1_from_tbar_m" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay1_from_tbar_pt" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay1_from_tbar_eta" ) = -1000 ; - this->auxdecor< float >( "MC_Wdecay1_from_tbar_phi" ) = -1000 ; - this->auxdecor< int >( "MC_Wdecay1_from_tbar_pdgId") = 0 ; - - this->auxdecor< float >( "MC_Wdecay2_from_t_m" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay2_from_t_pt" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay2_from_t_eta" ) = -1000 ; - this->auxdecor< float >( "MC_Wdecay2_from_t_phi" ) = -1000 ; - this->auxdecor< int >( "MC_Wdecay2_from_t_pdgId") = 0 ; - - this->auxdecor< float >( "MC_Wdecay2_from_tbar_m" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay2_from_tbar_pt" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay2_from_tbar_eta" ) = -1000 ; - this->auxdecor< float >( "MC_Wdecay2_from_tbar_phi" ) = -1000 ; - this->auxdecor< int >( "MC_Wdecay2_from_tbar_pdgId") = 0 ; + void PartonHistory::IniVarTtbar() { + //ttbar variables + this->auxdecor< float >("MC_ttbar_beforeFSR_m") = -1; + this->auxdecor< float >("MC_ttbar_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_ttbar_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_ttbar_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_ttbar_afterFSR_m") = -1; + this->auxdecor< float >("MC_ttbar_afterFSR_pt") = -1; + this->auxdecor< float >("MC_ttbar_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_ttbar_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_ttbar_afterFSR_beforeDecay_m") = -1; + this->auxdecor< float >("MC_ttbar_afterFSR_beforeDecay_pt") = -1; + this->auxdecor< float >("MC_ttbar_afterFSR_beforeDecay_eta") = -1000; + this->auxdecor< float >("MC_ttbar_afterFSR_beforeDecay_phi") = -1000; + + //t variables + this->auxdecor< float >("MC_t_beforeFSR_m") = -1; + this->auxdecor< float >("MC_t_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_t_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_afterFSR_m") = -1; + this->auxdecor< float >("MC_t_afterFSR_pt") = -1; + this->auxdecor< float >("MC_t_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_t_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_afterFSR_SC_m") = -1; + this->auxdecor< float >("MC_t_afterFSR_SC_pt") = -1; + this->auxdecor< float >("MC_t_afterFSR_SC_eta") = -1000; + this->auxdecor< float >("MC_t_afterFSR_SC_phi") = -1000; + + //tbar variables + this->auxdecor< float >("MC_tbar_beforeFSR_m") = -1; + this->auxdecor< float >("MC_tbar_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_tbar_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_tbar_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_tbar_afterFSR_m") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_pt") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_tbar_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_tbar_afterFSR_SC_m") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_SC_pt") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_SC_eta") = -1000; + this->auxdecor< float >("MC_tbar_afterFSR_SC_phi") = -1000; + + this->auxdecor< float >("MC_W_from_t_m") = -1; + this->auxdecor< float >("MC_W_from_t_pt") = -1; + this->auxdecor< float >("MC_W_from_t_eta") = -1000; + this->auxdecor< float >("MC_W_from_t_phi") = -1000; + + this->auxdecor< float >("MC_W_from_tbar_m") = -1; + this->auxdecor< float >("MC_W_from_tbar_pt") = -1; + this->auxdecor< float >("MC_W_from_tbar_eta") = -1000; + this->auxdecor< float >("MC_W_from_tbar_phi") = -1000; + + this->auxdecor< float >("MC_b_from_t_m") = -1; + this->auxdecor< float >("MC_b_from_t_pt") = -1; + this->auxdecor< float >("MC_b_from_t_eta") = -1000; + this->auxdecor< float >("MC_b_from_t_phi") = -1000; + + this->auxdecor< float >("MC_b_from_tbar_m") = -1; + this->auxdecor< float >("MC_b_from_tbar_pt") = -1; + this->auxdecor< float >("MC_b_from_tbar_eta") = -1000; + this->auxdecor< float >("MC_b_from_tbar_phi") = -1000; + + this->auxdecor< float >("MC_Wdecay1_from_t_m") = -1; + this->auxdecor< float >("MC_Wdecay1_from_t_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay1_from_tbar_m") = -1; + this->auxdecor< float >("MC_Wdecay1_from_tbar_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_from_tbar_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_tbar_phi") = -1000; + this->auxdecor< int >("MC_Wdecay1_from_tbar_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay2_from_t_m") = -1; + this->auxdecor< float >("MC_Wdecay2_from_t_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay2_from_tbar_m") = -1; + this->auxdecor< float >("MC_Wdecay2_from_tbar_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_from_tbar_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_tbar_phi") = -1000; + this->auxdecor< int >("MC_Wdecay2_from_tbar_pdgId") = 0; + } + + //Initialize variables for ttbar events + void PartonHistory::IniVarTtbarLight() { + //ttbar variables + this->auxdecor< float >("MC_ttbar_beforeFSR_m") = -1; + this->auxdecor< float >("MC_ttbar_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_ttbar_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_ttbar_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_ttbar_afterFSR_m") = -1; + this->auxdecor< float >("MC_ttbar_afterFSR_pt") = -1; + this->auxdecor< float >("MC_ttbar_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_ttbar_afterFSR_phi") = -1000; + //t variables + this->auxdecor< float >("MC_t_beforeFSR_m") = -1; + this->auxdecor< float >("MC_t_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_t_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_afterFSR_m") = -1; + this->auxdecor< float >("MC_t_afterFSR_pt") = -1; + this->auxdecor< float >("MC_t_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_t_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_afterFSR_SC_m") = -1; + this->auxdecor< float >("MC_t_afterFSR_SC_pt") = -1; + this->auxdecor< float >("MC_t_afterFSR_SC_eta") = -1000; + this->auxdecor< float >("MC_t_afterFSR_SC_phi") = -1000; + + //tbar variables + this->auxdecor< float >("MC_tbar_beforeFSR_m") = -1; + this->auxdecor< float >("MC_tbar_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_tbar_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_tbar_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_tbar_afterFSR_m") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_pt") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_tbar_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_tbar_afterFSR_SC_m") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_SC_pt") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_SC_eta") = -1000; + this->auxdecor< float >("MC_tbar_afterFSR_SC_phi") = -1000; + + this->auxdecor< float >("MC_W_from_t_m") = -1; + this->auxdecor< float >("MC_W_from_t_pt") = -1; + this->auxdecor< float >("MC_W_from_t_eta") = -1000; + this->auxdecor< float >("MC_W_from_t_phi") = -1000; + + this->auxdecor< float >("MC_W_from_tbar_m") = -1; + this->auxdecor< float >("MC_W_from_tbar_pt") = -1; + this->auxdecor< float >("MC_W_from_tbar_eta") = -1000; + this->auxdecor< float >("MC_W_from_tbar_phi") = -1000; + + this->auxdecor< float >("MC_q_from_t_m") = -1; + this->auxdecor< float >("MC_q_from_t_pt") = -1; + this->auxdecor< float >("MC_q_from_t_eta") = -1000; + this->auxdecor< float >("MC_q_from_t_phi") = -1000; + this->auxdecor< int >("MC_q_from_t_pdgId") = 0; + + this->auxdecor< float >("MC_q_from_tbar_m") = -1; + this->auxdecor< float >("MC_q_from_tbar_pt") = -1; + this->auxdecor< float >("MC_q_from_tbar_eta") = -1000; + this->auxdecor< float >("MC_q_from_tbar_phi") = -1000; + this->auxdecor< int >("MC_q_from_tbar_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay1_from_t_m") = -1; + this->auxdecor< float >("MC_Wdecay1_from_t_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay1_from_tbar_m") = -1; + this->auxdecor< float >("MC_Wdecay1_from_tbar_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_from_tbar_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_tbar_phi") = -1000; + this->auxdecor< int >("MC_Wdecay1_from_tbar_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay2_from_t_m") = -1; + this->auxdecor< float >("MC_Wdecay2_from_t_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay2_from_tbar_m") = -1; + this->auxdecor< float >("MC_Wdecay2_from_tbar_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_from_tbar_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_tbar_phi") = -1000; + this->auxdecor< int >("MC_Wdecay2_from_tbar_pdgId") = 0; } //Initialize variables for tbbar events - void PartonHistory::IniVarTbbar(){ - - //ttbar variables - this->auxdecor< float >( "MC_tbbar_beforeFSR_m" ) = -1; - this->auxdecor< float >( "MC_tbbar_beforeFSR_pt") = -1; - this->auxdecor< float >( "MC_tbbar_beforeFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_tbbar_beforeFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_tbbar_afterFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_tbbar_afterFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_tbbar_afterFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_tbbar_afterFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_t_beforeFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_t_beforeFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_t_beforeFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_t_beforeFSR_phi" ) = -1000 ; - - //tbbar variables - this->auxdecor< float >( "MC_b_beforeFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_b_beforeFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_b_beforeFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_b_beforeFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_b_afterFSR_m" ) = -1 ; - this->auxdecor< float >( "MC_b_afterFSR_pt" ) = -1 ; - this->auxdecor< float >( "MC_b_afterFSR_eta" ) = -1000 ; - this->auxdecor< float >( "MC_b_afterFSR_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_W_from_t_m" ) = -1 ; - this->auxdecor< float >( "MC_W_from_t_pt" ) = -1 ; - this->auxdecor< float >( "MC_W_from_t_eta" ) = -1000 ; - this->auxdecor< float >( "MC_W_from_t_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_b_from_t_m" ) = -1 ; - this->auxdecor< float >( "MC_b_from_t_pt" ) = -1 ; - this->auxdecor< float >( "MC_b_from_t_eta" ) = -1000 ; - this->auxdecor< float >( "MC_b_from_t_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_Wdecay1_from_t_m" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay1_from_t_pt" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay1_from_t_eta" ) = -1000 ; - this->auxdecor< float >( "MC_Wdecay1_from_t_phi" ) = -1000 ; - this->auxdecor< int >( "MC_Wdecay1_from_t_pdgId") = 0 ; - - this->auxdecor< float >( "MC_Wdecay2_from_t_m" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay2_from_t_pt" ) = -1 ; - this->auxdecor< float >( "MC_Wdecay2_from_t_eta" ) = -1000 ; - this->auxdecor< float >( "MC_Wdecay2_from_t_phi" ) = -1000 ; - this->auxdecor< int >( "MC_Wdecay2_from_t_pdgId") = 0 ; + void PartonHistory::IniVarTbbar() { + //ttbar variables + this->auxdecor< float >("MC_tbbar_beforeFSR_m") = -1; + this->auxdecor< float >("MC_tbbar_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_tbbar_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_tbbar_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_tbbar_afterFSR_m") = -1; + this->auxdecor< float >("MC_tbbar_afterFSR_pt") = -1; + this->auxdecor< float >("MC_tbbar_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_tbbar_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_beforeFSR_m") = -1; + this->auxdecor< float >("MC_t_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_t_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_phi") = -1000; + + //tbbar variables + this->auxdecor< float >("MC_b_beforeFSR_m") = -1; + this->auxdecor< float >("MC_b_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_b_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_b_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_b_afterFSR_m") = -1; + this->auxdecor< float >("MC_b_afterFSR_pt") = -1; + this->auxdecor< float >("MC_b_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_b_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_W_from_t_m") = -1; + this->auxdecor< float >("MC_W_from_t_pt") = -1; + this->auxdecor< float >("MC_W_from_t_eta") = -1000; + this->auxdecor< float >("MC_W_from_t_phi") = -1000; + this->auxdecor< float >("MC_b_from_t_m") = -1; + this->auxdecor< float >("MC_b_from_t_pt") = -1; + this->auxdecor< float >("MC_b_from_t_eta") = -1000; + this->auxdecor< float >("MC_b_from_t_phi") = -1000; + + this->auxdecor< float >("MC_Wdecay1_from_t_m") = -1; + this->auxdecor< float >("MC_Wdecay1_from_t_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay2_from_t_m") = -1; + this->auxdecor< float >("MC_Wdecay2_from_t_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = 0; } - - //Initialize variables for Wlv events - void PartonHistory::IniVarWlv(){ - - // W - this->auxdecor< float >( "MC_W_m" ) = -1 ; - this->auxdecor< float >( "MC_W_pt" ) = -1 ; - this->auxdecor< float >( "MC_W_eta" ) = -1000 ; - this->auxdecor< float >( "MC_W_phi" ) = -1000 ; - - this->auxdecor< float >( "MC_l_m" ) = -1 ; - this->auxdecor< float >( "MC_l_pt" ) = -1 ; - this->auxdecor< float >( "MC_l_eta" ) = -1000 ; - this->auxdecor< float >( "MC_l_phi" ) = -1000 ; - this->auxdecor< int >( "MC_l_pdgId") = 0 ; - - this->auxdecor< float >( "MC_v_m" ) = -1 ; - this->auxdecor< float >( "MC_v_pt" ) = -1 ; - this->auxdecor< float >( "MC_v_eta" ) = -1000 ; - this->auxdecor< float >( "MC_v_phi" ) = -1000 ; - this->auxdecor< int >( "MC_v_pdgId") = 0 ; + //Initialize variables for Wlv events + void PartonHistory::IniVarWlv() { + // W + this->auxdecor< float >("MC_W_m") = -1; + this->auxdecor< float >("MC_W_pt") = -1; + this->auxdecor< float >("MC_W_eta") = -1000; + this->auxdecor< float >("MC_W_phi") = -1000; + + this->auxdecor< float >("MC_l_m") = -1; + this->auxdecor< float >("MC_l_pt") = -1; + this->auxdecor< float >("MC_l_eta") = -1000; + this->auxdecor< float >("MC_l_phi") = -1000; + this->auxdecor< int >("MC_l_pdgId") = 0; + + this->auxdecor< float >("MC_v_m") = -1; + this->auxdecor< float >("MC_v_pt") = -1; + this->auxdecor< float >("MC_v_eta") = -1000; + this->auxdecor< float >("MC_v_phi") = -1000; + this->auxdecor< int >("MC_v_pdgId") = 0; + } + + // Initialize variable for Wt ST events + void PartonHistory::IniVarWtb() { + // top or antitop + this->auxdecor< float >("MC_top_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_top_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_top_beforeFSR_phi") = -1000; + this->auxdecor< float >("MC_top_beforeFSR_m") = -1; + this->auxdecor< float >("MC_top_afterFSR_pt") = -1; + this->auxdecor< float >("MC_top_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_top_afterFSR_phi") = -1000; + this->auxdecor< float >("MC_top_afterFSR_m") = -1; + + // b from top + this->auxdecor< float >("MC_b_from_top_pt") = -1; + this->auxdecor< float >("MC_b_from_top_eta") = -1000; + this->auxdecor< float >("MC_b_from_top_phi") = -1000; + this->auxdecor< float >("MC_b_from_top_m") = -1; + + // W from top + this->auxdecor< float >("MC_W_from_top_pt") = -1; + this->auxdecor< float >("MC_W_from_top_eta") = -1000; + this->auxdecor< float >("MC_W_from_top_phi") = -1000; + this->auxdecor< float >("MC_W_from_top_m") = -1; + + // W from top decay product 1 + this->auxdecor< float >("MC_Wdecay1_from_top_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_from_top_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_top_phi") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_top_m") = -1; + this->auxdecor< int >("MC_Wdecay1_from_top_pdgId") = 0; + + // W from top decay product 2 + this->auxdecor< float >("MC_Wdecay2_from_top_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_from_top_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_top_phi") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_top_m") = -1; + this->auxdecor< int >("MC_Wdecay2_from_top_pdgId") = 0; + + // W NOT from top + this->auxdecor< float >("MC_W_not_from_top_pt") = -1; + this->auxdecor< float >("MC_W_not_from_top_eta") = -1000; + this->auxdecor< float >("MC_W_not_from_top_phi") = -1000; + this->auxdecor< float >("MC_W_not_from_top_m") = -1; + + // W NOT from top decay product 1 + this->auxdecor< float >("MC_Wdecay1_not_from_top_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_not_from_top_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_not_from_top_phi") = -1000; + this->auxdecor< float >("MC_Wdecay1_not_from_top_m") = -1; + this->auxdecor< int >("MC_Wdecay1_not_from_top_pdgId") = 0; + + // W NOT from top decay product 2 + this->auxdecor< float >("MC_Wdecay2_not_from_top_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_not_from_top_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_not_from_top_phi") = -1000; + this->auxdecor< float >("MC_Wdecay2_not_from_top_m") = -1; + this->auxdecor< int >("MC_Wdecay2_not_from_top_pdgId") = 0; + + // b not from top, for Wtb events + this->auxdecor< float >("MC_b_not_from_top_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_b_not_from_top_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_b_not_from_top_beforeFSR_phi") = -1000; + this->auxdecor< float >("MC_b_not_from_top_beforeFSR_m") = -1; + this->auxdecor< float >("MC_b_not_from_top_afterFSR_pt") = -1; + this->auxdecor< float >("MC_b_not_from_top_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_b_not_from_top_afterFSR_phi") = -1000; + this->auxdecor< float >("MC_b_not_from_top_afterFSR_m") = -1; + this->auxdecor< int >("MC_b_not_from_top_pdgId") = 0; + } + + // Initialize variables for an additional final-state Z. + void PartonHistory::IniVarZ() { + this->auxdecor< float >("MC_Z_m") = -1; + this->auxdecor< float >("MC_Z_pt") = -1; + this->auxdecor< float >("MC_Z_eta") = -1000; + this->auxdecor< float >("MC_Z_phi") = -1000; + + this->auxdecor< float >("MC_Zdecay1_m") = -1; + this->auxdecor< float >("MC_Zdecay1_pt") = -1; + this->auxdecor< float >("MC_Zdecay1_eta") = -1000; + this->auxdecor< float >("MC_Zdecay1_phi") = -1000; + this->auxdecor< int >("MC_Zdecay1_pdgId") = 0; + + this->auxdecor< float >("MC_Zdecay2_m") = -1; + this->auxdecor< float >("MC_Zdecay2_pt") = -1; + this->auxdecor< float >("MC_Zdecay2_eta") = -1000; + this->auxdecor< float >("MC_Zdecay2_phi") = -1000; + this->auxdecor< int >("MC_Zdecay2_pdgId") = 0; + + this->auxdecor< int >("MC_Z_AncestryCorrupted") = -1; + this->auxdecor< int >("MC_Z_IsOnShell") = -1; + } + + //Initialize variables for ttbargamma events + void PartonHistory::IniVarTtGamma() { + //ttbar variables + this->auxdecor< float >("MC_ttbar_beforeFSR_m") = -1; + this->auxdecor< float >("MC_ttbar_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_ttbar_beforeFSR_eta") = -10; + this->auxdecor< float >("MC_ttbar_beforeFSR_phi") = -10; + + this->auxdecor< float >("MC_ttbar_afterFSR_m") = -1; + this->auxdecor< float >("MC_ttbar_afterFSR_pt") = -1; + this->auxdecor< float >("MC_ttbar_afterFSR_eta") = -10; + this->auxdecor< float >("MC_ttbar_afterFSR_phi") = -10; + + //t variables + this->auxdecor< float >("MC_t_beforeFSR_m") = -1; + this->auxdecor< float >("MC_t_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_t_beforeFSR_eta") = -10; + this->auxdecor< float >("MC_t_beforeFSR_phi") = -10; + + this->auxdecor< float >("MC_t_afterFSR_m") = -1; + this->auxdecor< float >("MC_t_afterFSR_pt") = -1; + this->auxdecor< float >("MC_t_afterFSR_eta") = -10; + this->auxdecor< float >("MC_t_afterFSR_phi") = -10; + + //tbar variables + this->auxdecor< float >("MC_tbar_beforeFSR_m") = -1; + this->auxdecor< float >("MC_tbar_beforeFSR_pt") = -1; + this->auxdecor< float >("MC_tbar_beforeFSR_eta") = -10; + this->auxdecor< float >("MC_tbar_beforeFSR_phi") = -10; + + this->auxdecor< float >("MC_tbar_afterFSR_m") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_pt") = -1; + this->auxdecor< float >("MC_tbar_afterFSR_eta") = -10; + this->auxdecor< float >("MC_tbar_afterFSR_phi") = -10; + + //W variables + this->auxdecor< float >("MC_W_from_t_m") = -1; + this->auxdecor< float >("MC_W_from_t_pt") = -1; + this->auxdecor< float >("MC_W_from_t_eta") = -10; + this->auxdecor< float >("MC_W_from_t_phi") = -10; + + this->auxdecor< float >("MC_W_from_tbar_m") = -1; + this->auxdecor< float >("MC_W_from_tbar_pt") = -1; + this->auxdecor< float >("MC_W_from_tbar_eta") = -10; + this->auxdecor< float >("MC_W_from_tbar_phi") = -10; + + //b variables + this->auxdecor< float >("MC_b_from_t_m") = -1; + this->auxdecor< float >("MC_b_from_t_pt") = -1; + this->auxdecor< float >("MC_b_from_t_eta") = -10; + this->auxdecor< float >("MC_b_from_t_phi") = -10; + + this->auxdecor< float >("MC_b_from_tbar_m") = -1; + this->auxdecor< float >("MC_b_from_tbar_pt") = -1; + this->auxdecor< float >("MC_b_from_tbar_eta") = -10; + this->auxdecor< float >("MC_b_from_tbar_phi") = -10; + + //Wdecay1 variables + this->auxdecor< float >("MC_Wdecay1_from_t_m") = -1; + this->auxdecor< float >("MC_Wdecay1_from_t_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_from_t_eta") = -10; + this->auxdecor< float >("MC_Wdecay1_from_t_phi") = -10; + this->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay1_from_tbar_m") = -1; + this->auxdecor< float >("MC_Wdecay1_from_tbar_pt") = -1; + this->auxdecor< float >("MC_Wdecay1_from_tbar_eta") = -10; + this->auxdecor< float >("MC_Wdecay1_from_tbar_phi") = -10; + this->auxdecor< int >("MC_Wdecay1_from_tbar_pdgId") = 0; + + //Wdecay2 variables + this->auxdecor< float >("MC_Wdecay2_from_t_m") = -1; + this->auxdecor< float >("MC_Wdecay2_from_t_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_from_t_eta") = -10; + this->auxdecor< float >("MC_Wdecay2_from_t_phi") = -10; + this->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = 0; + + this->auxdecor< float >("MC_Wdecay2_from_tbar_m") = -1; + this->auxdecor< float >("MC_Wdecay2_from_tbar_pt") = -1; + this->auxdecor< float >("MC_Wdecay2_from_tbar_eta") = -10; + this->auxdecor< float >("MC_Wdecay2_from_tbar_phi") = -10; + this->auxdecor< int >("MC_Wdecay2_from_tbar_pdgId") = 0; + + //photon variables + this->auxdecor< float >("MC_ph_m") = -1; + this->auxdecor< float >("MC_ph_pt") = -1; + this->auxdecor< float >("MC_ph_eta") = -10; + this->auxdecor< float >("MC_ph_phi") = -10; + + this->auxdecor< int >("MC_branchtype_t") = -1; + this->auxdecor< int >("MC_branchtype_tbar") = -1; + this->auxdecor< int >("MC_initial_parton") = -1; + this->auxdecor< int >("MC_ph_from_t_tbar") = -1; + this->auxdecor< int >("MC_Event_Category") = -1; + } + + // Initialize variables for thqtautau events + void PartonHistory::IniVarThq() { + //t variables + this->auxdecor< float >("MC_t_beforeFSR_m") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_pt") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_afterFSR_m") = -1000; + this->auxdecor< float >("MC_t_afterFSR_pt") = -1000; + this->auxdecor< float >("MC_t_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_t_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_afterFSR_SC_m") = -1000; + this->auxdecor< float >("MC_t_afterFSR_SC_pt") = -1000; + this->auxdecor< float >("MC_t_afterFSR_SC_eta") = -1000; + this->auxdecor< float >("MC_t_afterFSR_SC_phi") = -1000; + + this->auxdecor< float >("MC_W_from_t_m") = -1000; + this->auxdecor< float >("MC_W_from_t_pt") = -1000; + this->auxdecor< float >("MC_W_from_t_eta") = -1000; + this->auxdecor< float >("MC_W_from_t_phi") = -1000; + + this->auxdecor< float >("MC_b_from_t_m") = -1000; + this->auxdecor< float >("MC_b_from_t_pt") = -1000; + this->auxdecor< float >("MC_b_from_t_eta") = -1000; + this->auxdecor< float >("MC_b_from_t_phi") = -1000; + + this->auxdecor< float >("MC_Wdecay1_from_t_m") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_pt") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = -9999; + + this->auxdecor< float >("MC_Wdecay2_from_t_m") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_pt") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = -9999; + + // Higgs variables + this->auxdecor< float >("MC_Higgs_m") = -1000; + this->auxdecor< float >("MC_Higgs_pt") = -1000; + this->auxdecor< float >("MC_Higgs_eta") = -1000; + this->auxdecor< float >("MC_Higgs_phi") = -1000; + + this->auxdecor< float >("MC_Higgs_decay1_m") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_pt") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_phi") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_eta") = -1000; + this->auxdecor< int >("MC_Higgs_tau_decay1_isHadronic") = -1000; + this->auxdecor< int >("MC_Higgs_decay1_pdgId") = -1000; + + this->auxdecor< float >("MC_Higgs_decay2_m") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_pt") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_phi") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_eta") = -1000; + this->auxdecor< int >("MC_Higgs_tau_decay2_isHadronic") = -1000; + this->auxdecor< int >("MC_Higgs_decay2_pdgId") = -1000; + + this->auxdecor< float >("MC_Higgs_decay1_from_decay1_m") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_from_decay1_pt") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_from_decay1_phi") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_from_decay1_eta") = -1000; + this->auxdecor< int >("MC_Higgs_tau_decay1_from_decay1_isHadronic") = -1000; + this->auxdecor< int >("MC_Higgs_decay1_from_decay1_pdgId") = -1000; + + this->auxdecor< float >("MC_Higgs_decay2_from_decay1_m") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_from_decay1_pt") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_from_decay1_phi") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_from_decay1_eta") = -1000; + this->auxdecor< int >("MC_Higgs_tau_decay2_from_decay1_isHadronic") = -1000; + this->auxdecor< int >("MC_Higgs_decay2_from_decay1_pdgId") = -1000; + + this->auxdecor< float >("MC_Higgs_decay1_from_decay2_m") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_from_decay2_pt") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_from_decay2_phi") = -1000; + this->auxdecor< float >("MC_Higgs_decay1_from_decay2_eta") = -1000; + this->auxdecor< int >("MC_Higgs_tau_decay1_from_decay2_isHadronic") = -1000; + this->auxdecor< int >("MC_Higgs_decay1_from_decay2_pdgId") = -1000; + + this->auxdecor< float >("MC_Higgs_decay2_from_decay2_m") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_from_decay2_pt") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_from_decay2_phi") = -1000; + this->auxdecor< float >("MC_Higgs_decay2_from_decay2_eta") = -1000; + this->auxdecor< int >("MC_Higgs_tau_decay2_from_decay2_isHadronic") = -1000; + this->auxdecor< int >("MC_Higgs_decay2_from_decay2_pdgId") = -1000; } + + // Initialize variables for tZq events + void PartonHistory::IniVarTzq() { + //t variables + this->auxdecor< float >("MC_t_beforeFSR_m") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_pt") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_eta") = -1000; + this->auxdecor< float >("MC_t_beforeFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_afterFSR_m") = -1000; + this->auxdecor< float >("MC_t_afterFSR_pt") = -1000; + this->auxdecor< float >("MC_t_afterFSR_eta") = -1000; + this->auxdecor< float >("MC_t_afterFSR_phi") = -1000; + + this->auxdecor< float >("MC_t_afterFSR_SC_m") = -1000; + this->auxdecor< float >("MC_t_afterFSR_SC_pt") = -1000; + this->auxdecor< float >("MC_t_afterFSR_SC_eta") = -1000; + this->auxdecor< float >("MC_t_afterFSR_SC_phi") = -1000; + this->auxdecor< float >("MC_W_from_t_m") = -1000; + this->auxdecor< float >("MC_W_from_t_pt") = -1000; + this->auxdecor< float >("MC_W_from_t_eta") = -1000; + this->auxdecor< float >("MC_W_from_t_phi") = -1000; + this->auxdecor< float >("MC_b_from_t_m") = -1000; + this->auxdecor< float >("MC_b_from_t_pt") = -1000; + this->auxdecor< float >("MC_b_from_t_eta") = -1000; + this->auxdecor< float >("MC_b_from_t_phi") = -1000; + + this->auxdecor< float >("MC_Wdecay1_from_t_m") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_pt") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay1_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay1_from_t_pdgId") = -9999; + + this->auxdecor< float >("MC_Wdecay2_from_t_m") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_pt") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_eta") = -1000; + this->auxdecor< float >("MC_Wdecay2_from_t_phi") = -1000; + this->auxdecor< int >("MC_Wdecay2_from_t_pdgId") = -9999; + + //Z variables + this->auxdecor< float >("MC_Z_m") = -1000; + this->auxdecor< float >("MC_Z_pt") = -1000; + this->auxdecor< float >("MC_Z_eta") = -1000; + this->auxdecor< float >("MC_Z_phi") = -1000; + + + this->auxdecor< float >("MC_Zdecay1_m") = -1000; + this->auxdecor< float >("MC_Zdecay1_pt") = -1000; + this->auxdecor< float >("MC_Zdecay1_eta") = -1000; + this->auxdecor< float >("MC_Zdecay1_phi") = -1000; + this->auxdecor< int >("MC_Zdecay1_pdgId") = -9999; + this->auxdecor< int >("MC_Zdecay1_status") = -9999; + + this->auxdecor< float >("MC_Zdecay2_m") = -1000; + this->auxdecor< float >("MC_Zdecay2_pt") = -1000; + this->auxdecor< float >("MC_Zdecay2_eta") = -1000; + this->auxdecor< float >("MC_Zdecay2_phi") = -1000; + this->auxdecor< int >("MC_Zdecay2_pdgId") = -9999; + this->auxdecor< int >("MC_Zdecay2_status") = -9999; + + + } } -ADD_NS_DV_PROXY( xAOD , PartonHistoryContainer ); +ADD_NS_DV_PROXY(xAOD, PartonHistoryContainer); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/PartonHistoryUtils.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/PartonHistoryUtils.cxx new file mode 100644 index 000000000000..9f28637d85b2 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/Root/PartonHistoryUtils.cxx @@ -0,0 +1,183 @@ +#include "TopPartons/PartonHistoryUtils.h" + +namespace top { +namespace PartonHistoryUtils { + + const xAOD::TruthParticle* findAfterFSR(const xAOD::TruthParticle* particle) { + bool isAfterFSR(false); + const int particle_ID = particle->pdgId(); + int forLoop = 0; + + while (!isAfterFSR) { + forLoop = 0; + for (size_t j = 0; j < particle->nChildren(); j++) { + const xAOD::TruthParticle* tmp_children = particle->child(j); + if (tmp_children && tmp_children->pdgId() == particle_ID) { + particle = particle->child(j); + forLoop++; + break; + }//if + }//for + if (forLoop == 0) isAfterFSR = true; + }//while + return particle; + } + + bool hasParticleIdenticalParent(const xAOD::TruthParticle* particle) { + bool skipit(false); + + for (size_t i = 0; i < particle->nParents(); i++) { + const xAOD::TruthParticle* parent = particle->parent(i); + if (parent && parent->pdgId() == particle->pdgId()) { + skipit = true; + break; + }//if + }//for + return skipit; + } + + HiggsDecay AnalyzeHiggsDecay(const xAOD::TruthParticle* higgs) { + + HiggsDecay result; + + if (higgs->pdgId() != 25) return result; + + /// identify after FSR higgs (just to be sure) + const xAOD::TruthParticle* higgs_fsr = findAfterFSR(higgs); + if (higgs_fsr->nChildren() != 2) return result; + + /// identify direct higgs decays + result.decay1_vector = higgs_fsr->child(0)->p4(); + result.decay2_vector = higgs_fsr->child(1)->p4(); + result.decay1_pdgId = higgs_fsr->child(0)->pdgId(); + result.decay2_pdgId = higgs_fsr->child(1)->pdgId(); + + /// check if higgs decays into tau, W or Z + const bool isZ = (result.decay1_pdgId == 23 || result.decay2_pdgId == 23) ? true : false; + const bool isW = (std::abs(result.decay1_pdgId) == 24 || std::abs(result.decay2_pdgId) == 24) ? true : false; + + /// Function to translate the result of the investigation into an integer status + /// status -1 = problem with the truth record + /// status 1 = tau decays hadronically + /// status 0 = tau decays leptonically + auto tauHadronicIndex = [&result](const xAOD::TruthParticle* particle) { + bool isOk(false); + const bool isHadronic = TauIsHadronic(particle, isOk); + if (!isOk) { + return -1; + } + + if (isHadronic) return 1; + + return 0; + }; + + if (std::abs(result.decay1_pdgId) == 15) { + result.tau_decay1_isHadronic = tauHadronicIndex(higgs_fsr->child(0)); + } + if (std::abs(result.decay2_pdgId) == 15) { + result.tau_decay2_isHadronic = tauHadronicIndex(higgs_fsr->child(1)); + } + + if (!isZ && !isW) return result; + + const xAOD::TruthParticle* decay1 = findAfterFSR(higgs->child(0)); + if (decay1->nChildren() != 2) return result; + const xAOD::TruthParticle* decay2 = findAfterFSR(higgs->child(1)); + if (decay2->nChildren() != 2) return result; + + /// decays of W/Z + result.decay1_from_decay1_vector = decay1->child(0)->p4(); + result.decay2_from_decay1_vector = decay1->child(1)->p4(); + result.decay1_from_decay1_pdgId = decay1->child(0)->pdgId(); + result.decay2_from_decay1_pdgId = decay1->child(1)->pdgId(); + + result.decay1_from_decay2_vector = decay2->child(0)->p4(); + result.decay2_from_decay2_vector = decay2->child(1)->p4(); + result.decay1_from_decay2_pdgId = decay2->child(0)->pdgId(); + result.decay2_from_decay2_pdgId = decay2->child(1)->pdgId(); + + if (std::abs(result.decay1_from_decay1_pdgId) == 15) { + result.tau_decay1_from_decay1_isHadronic = tauHadronicIndex(decay1->child(0)); + } + if (std::abs(result.decay2_from_decay1_pdgId) == 15) { + result.tau_decay2_from_decay1_isHadronic = tauHadronicIndex(decay1->child(1)); + } + if (std::abs(result.decay1_from_decay2_pdgId) == 15) { + result.tau_decay1_from_decay2_isHadronic = tauHadronicIndex(decay2->child(0)); + } + if (std::abs(result.decay2_from_decay2_pdgId) == 15) { + result.tau_decay2_from_decay2_isHadronic = tauHadronicIndex(decay2->child(1)); + } + + return result; + } + + bool TauIsHadronic(const xAOD::TruthParticle* tau, bool &isOk) { + + if (!tau) { + isOk = false; + return false; + } + + if (std::abs(tau->pdgId()) != 15) { + isOk = false; + return false; + } + + const xAOD::TruthParticle* afterFsr = findAfterFSR(tau); + + if (afterFsr->nChildren() != 2) { + isOk = false; + return false; + } + + const xAOD::TruthParticle* child1 = findAfterFSR(afterFsr->child(0)); + const xAOD::TruthParticle* child2 = findAfterFSR(afterFsr->child(1)); + + if (std::abs(child1->pdgId()) == 16) { + // it means the other particle ahs to be W + if (std::abs(child2->pdgId()) != 24) { + isOk = false; + return false; + } + + // child2 is W + if (child2->nChildren() != 2) { + isOk = false; + return false; + } + + isOk = true; + + // everything is fine, check if the W decays hadronically or leptonically + if (std::abs(child2->child(0)->pdgId()) < 16) { + return true; + } else { + return false; + } + } else { + // it means the other particle has to be nu + if (std::abs(child2->pdgId()) != 16) { + isOk = false; + return false; + } + + // child1 is W + if (child1->nChildren() != 2) { + isOk = false; + return false; + } + + isOk = true; + + // everything is fine, check if the W decays hadronically or leptonically + if (std::abs(child1->child(0)->pdgId()) < 16) { + return true; + } else { + return false; + } + } + } +} +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTTZPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTTZPartonHistory.h new file mode 100644 index 000000000000..ca5223d27234 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTTZPartonHistory.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPPARTONS_CALCTTZPARTONHISTORY_H +#define ANALYSISTOP_TOPPARTONS_CALCTTZPARTONHISTORY_H + +/** + * @author Knut Zoch <kzoch@cern.ch> + * @brief CalcTTZPartonHistory + * Class derived from CalcTopPartonHistory, used to store ttZ variables + * + * Class definition follows that of class CalcTtbarHistory. + **/ + + +// Framework include(s): +#include "TopPartons/CalcTtbarPartonHistory.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "TopPartons/PartonHistory.h" + +// forward declaration(s): +namespace top { + class TopConfig; +} + +namespace top { + class CalcTTZPartonHistory: public CalcTtbarPartonHistory { + public: + explicit CalcTTZPartonHistory(const std::string& name); + virtual ~CalcTTZPartonHistory() {} + + CalcTTZPartonHistory(const CalcTTZPartonHistory& rhs) = delete; + CalcTTZPartonHistory(CalcTTZPartonHistory&& rhs) = delete; + CalcTTZPartonHistory& operator = (const CalcTTZPartonHistory& rhs) = delete; + + void zHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* ttbarPartonHistory); + + virtual StatusCode execute(); + + const xAOD::TruthParticle* getFlavourSibling(const xAOD::TruthParticle* particle); + bool getZ(const xAOD::TruthParticleContainer* truthParticles, + TLorentzVector* Z, + TLorentzVector* ZDecay1, + int* ZDecay1_pdgId, + TLorentzVector* ZDecay2, + int* ZDecay2_pdgId, + bool* is_on_shell); + private: + bool m_ancestry_corrupted; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTbbarPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTbbarPartonHistory.h index 693903d0181f..980d4deede99 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTbbarPartonHistory.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTbbarPartonHistory.h @@ -1,22 +1,22 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOP_TOPPARTONS_CALCTBBARPARTONHISTORY_H #define ANALYSISTOP_TOPPARTONS_CALCTBBARPARTONHISTORY_H /** - * @author John Morris <john.morris@cern.ch> - * @author Silvestre Marino Romano <sromanos@cern.ch> - * @author Samuel Calvet <scalvet@cern.ch> - * - * @brief CalcTbbarPartonHistory - * Class derived from CalcTopPartonHistory, used to store tbbar variables - * - * $Revision: 777122 $ - * $Date: 2016-10-07 15:57:57 +0200 (Fri, 07 Oct 2016) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * @author Silvestre Marino Romano <sromanos@cern.ch> + * @author Samuel Calvet <scalvet@cern.ch> + * + * @brief CalcTbbarPartonHistory + * Class derived from CalcTopPartonHistory, used to store tbbar variables + * + * $Revision: 777122 $ + * $Date: 2016-10-07 14:57:57 +0100 (Fri, 07 Oct 2016) $ + * + **/ // Framework include(s): @@ -25,28 +25,25 @@ #include "TopPartons/PartonHistory.h" // forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class CalcTbbarPartonHistory : public CalcTopPartonHistory{ - public: - explicit CalcTbbarPartonHistory( const std::string& name ); - virtual ~CalcTbbarPartonHistory() {} - - //Storing parton history for tbbar resonance analysis - CalcTbbarPartonHistory(const CalcTbbarPartonHistory& rhs) = delete; - CalcTbbarPartonHistory(CalcTbbarPartonHistory&& rhs) = delete; - CalcTbbarPartonHistory& operator=(const CalcTbbarPartonHistory& rhs) = delete; - - void tbbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* tbbarPartonHistory); - - virtual StatusCode execute(); - +namespace top { + class CalcTbbarPartonHistory: public CalcTopPartonHistory { + public: + explicit CalcTbbarPartonHistory(const std::string& name); + virtual ~CalcTbbarPartonHistory() {} + + //Storing parton history for tbbar resonance analysis + CalcTbbarPartonHistory(const CalcTbbarPartonHistory& rhs) = delete; + CalcTbbarPartonHistory(CalcTbbarPartonHistory&& rhs) = delete; + CalcTbbarPartonHistory& operator = (const CalcTbbarPartonHistory& rhs) = delete; + + void tbbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* tbbarPartonHistory); + + virtual StatusCode execute(); }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcThqPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcThqPartonHistory.h new file mode 100644 index 000000000000..b68a76cd1a62 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcThqPartonHistory.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPPARTONS_CALCThqPARTONHISTORY_H +#define ANALYSISTOP_TOPPARTONS_CALCThqPARTONHISTORY_H + + +// Framework include(s): +#include "TopPartons/CalcTopPartonHistory.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "TopPartons/PartonHistory.h" + +// forward declaration(s): +namespace top { + class TopConfig; +} + +namespace top { + class CalcThqPartonHistory: public CalcTopPartonHistory { + public: + explicit CalcThqPartonHistory(const std::string& name); + virtual ~CalcThqPartonHistory() {} + + struct tH_values { + //Higgs + TLorentzVector Higgs_p4; + TLorentzVector decay1_p4; + TLorentzVector decay2_p4; + int decay1_pdgId; + int decay2_pdgId; + int tau_decay1_isHadronic; + int tau_decay2_isHadronic; + TLorentzVector decay1_from_decay1_p4; + TLorentzVector decay2_from_decay1_p4; + int decay1_from_decay1_pdgId; + int decay2_from_decay1_pdgId; + TLorentzVector decay1_from_decay2_p4; + TLorentzVector decay2_from_decay2_p4; + int decay1_from_decay2_pdgId; + int decay2_from_decay2_pdgId; + int tau_decay1_from_decay1_isHadronic; + int tau_decay2_from_decay1_isHadronic; + int tau_decay1_from_decay2_isHadronic; + int tau_decay2_from_decay2_isHadronic; + } tH; + //Storing parton history for ttbar resonance analysis + CalcThqPartonHistory(const CalcThqPartonHistory& rhs) = delete; + CalcThqPartonHistory(CalcThqPartonHistory&& rhs) = delete; + CalcThqPartonHistory& operator = (const CalcThqPartonHistory& rhs) = delete; + + void THHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* ThqPartonHistory); + + ///Store the four-momentum of several particles in the Higgs decay chain + bool HiggsAndDecay(const xAOD::TruthParticleContainer* truthParticles); + + virtual StatusCode execute(); + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTopPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTopPartonHistory.h index 859d7ae41d5d..4a9ae48a3718 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTopPartonHistory.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTopPartonHistory.h @@ -1,23 +1,23 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ // $Id: CalcTopPartonHistory.h 800464 2017-03-13 18:06:24Z tpelzer $ #ifndef ANALYSISTOP_TOPPARTONS_CALCTOPPARTONHISTORY_H #define ANALYSISTOP_TOPPARTONS_CALCTOPPARTONHISTORY_H /** - * @author John Morris <john.morris@cern.ch> - * @author Silvestre Marino Romano <sromanos@cern.ch> - * @author Samuel Calvet <scalvet@cern.ch> - * - * @brief CalcTopPartonHistory - * Determine the history of the top partons - * - * $Revision: 800464 $ - * $Date: 2017-03-13 19:06:24 +0100 (Mon, 13 Mar 2017) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * @author Silvestre Marino Romano <sromanos@cern.ch> + * @author Samuel Calvet <scalvet@cern.ch> + * + * @brief CalcTopPartonHistory + * Determine the history of the top partons + * + * $Revision: 800464 $ + * $Date: 2017-03-13 18:06:24 +0000 (Mon, 13 Mar 2017) $ + * + **/ // system include(s): #include <memory> @@ -31,48 +31,86 @@ #include "TopPartons/PartonHistory.h" // forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class CalcTopPartonHistory : public asg::AsgTool { - public: - explicit CalcTopPartonHistory( const std::string& name ); - virtual ~CalcTopPartonHistory() {} - - CalcTopPartonHistory(const CalcTopPartonHistory& rhs) = delete; - CalcTopPartonHistory(CalcTopPartonHistory&& rhs) = delete; - CalcTopPartonHistory& operator=(const CalcTopPartonHistory& rhs) = delete; - - ///Store the four-momentum of the post-FSR top or anti-top found using statusCodes - ///This would only work if there is at most one "true" top of each charge (i.e. won't work for SS tops or 4 tops) - ///This code was adapted from the 7TeV parton-level differential ttbar routine: https://svnweb.cern.ch/trac/atlasphys-top/browser/Physics/Top/Software/MCvalidation/Rivet/Rivet2.X/trunk/routines/ATLAS_2014_I1304289/ATLAS_2014_I1304289.cc - bool topAfterFSR_SC(const xAOD::TruthParticleContainer* truthParticles, int start, TLorentzVector& top_afterFSR_SC_p4); - - ///Store the four-momentum of several particles in the top decay chain - bool topWb(const xAOD::TruthParticleContainer* truthParticles, int start, TLorentzVector& t_beforeFSR_p4, TLorentzVector& t_afterFSR_p4, TLorentzVector& W_p4, TLorentzVector& b_p4, TLorentzVector& Wdecay1_p4, int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId); - - ///Store the four-momentum of b (not from tops_ before and after FSR - bool b(const xAOD::TruthParticleContainer* truthParticles, TLorentzVector& b_beforeFSR, TLorentzVector& b_afterFSR); - - ///Store the four-momentum of several particles in the W decay chain - bool Wlv(const xAOD::TruthParticleContainer* truthParticles, TLorentzVector& W_p4, TLorentzVector& Wdecay1_p4, int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId); - - ///Return particle after FSR (before the decay vertex) - const xAOD::TruthParticle* findAfterFSR(const xAOD::TruthParticle* particle); - - ///Return true when particle is a top before FSR - bool hasParticleIdenticalParent(const xAOD::TruthParticle* particle); - - virtual StatusCode execute(); - protected: - std::shared_ptr<top::TopConfig> m_config; - - void fillEtaBranch(xAOD::PartonHistory* partonHistory,std:: string branchName, TLorentzVector &tlv); - - }; +namespace top { + class CalcTopPartonHistory: public asg::AsgTool { + public: + explicit CalcTopPartonHistory(const std::string& name); + virtual ~CalcTopPartonHistory() {}; + + CalcTopPartonHistory(const CalcTopPartonHistory& rhs) = delete; + CalcTopPartonHistory(CalcTopPartonHistory&& rhs) = delete; + CalcTopPartonHistory& operator = (const CalcTopPartonHistory& rhs) = delete; + + /** Store the four-momentum of the post-FSR top or anti-top found using statusCodes + * This would only work if there is at most one "true" top of each charge (i.e. won't work for SS tops or 4 tops) + * This code was adapted from the 7TeV parton-level differential ttbar routine: + * https://svnweb.cern.ch/trac/atlasphys-top/browser/Physics/Top/Software/MCvalidation/Rivet/Rivet2.X/trunk/routines/ATLAS_2014_I1304289/ATLAS_2014_I1304289.cc + */ + bool topAfterFSR_SC(const xAOD::TruthParticleContainer* truthParticles, int start, + TLorentzVector& top_afterFSR_SC_p4); + + ///Store the four-momentum of several particles in the top decay chain + bool topWb(const xAOD::TruthParticleContainer* truthParticles, int start, TLorentzVector& t_beforeFSR_p4, + TLorentzVector& t_afterFSR_p4, TLorentzVector& W_p4, TLorentzVector& b_p4, TLorentzVector& Wdecay1_p4, + int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId); + bool topWq(const xAOD::TruthParticleContainer* truthParticles, int start, TLorentzVector& t_beforeFSR_p4, + TLorentzVector& t_afterFSR_p4, TLorentzVector& W_p4, TLorentzVector& q_p4, int& q_pdgId, + TLorentzVector& Wdecay1_p4, int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId); + + ///Store the four-momentum of b (not from tops_ before and after FSR + bool b(const xAOD::TruthParticleContainer* truthParticles, TLorentzVector& b_beforeFSR, TLorentzVector& b_afterFSR); + + ///Store the four-momentum of several particles in the W decay chain + bool Wlv(const xAOD::TruthParticleContainer* truthParticles, TLorentzVector& W_p4, TLorentzVector& Wdecay1_p4, + int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId); + + /// Store the four-momentum of several particles in W decay chain for W that is NOT from top in Wt ST events + bool Wt_W(const xAOD::TruthParticleContainer* truthParticles, TLorentzVector& W_p4, int& W_pdgId, + TLorentzVector& Wdecay1_p4, int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId); + + /// Store the four-momentum of b quark that is NOT from top in Wt(b) ST events + bool Wt_b(const xAOD::TruthParticleContainer* truthParticles, TLorentzVector& b_beforeFSR, + TLorentzVector& b_afterFSR, int& b_pdgId); + + /// Store the four-momentum of photon coming from virtual top in ttgamma events + bool topPhWb(const xAOD::TruthParticleContainer* truthParticles, int topId, TLorentzVector& t_beforeFSR_p4, + TLorentzVector& t_afterFSR_p4, TLorentzVector& Ph_p4, TLorentzVector& W_p4, TLorentzVector& b_p4, + TLorentzVector& Wdecay1_p4, int& Wdecay1_pdgId, TLorentzVector& Wdecay2_p4, int& Wdecay2_pdgId, + bool& has_ph, int& BranchType, int& IniPartonType, bool& missingTop); + + virtual StatusCode execute(); + protected: + std::shared_ptr<top::TopConfig> m_config; + + void fillEtaBranch(xAOD::PartonHistory* partonHistory, std:: string branchName, TLorentzVector& tlv); + + /** used to build container from multiple collections + * in DAOD_PHYS we don't have the TruthParticles collection, so we have to build a TruthParticleContainer (named out_contName) by merging several collections; this is stored in the evtStore + * this method has to use some tricks, like the helper m_tempParticles ConstDataVector, due to the desing of DataVector, see https://twiki.cern.ch/twiki/bin/view/AtlasComputing/DataVector + */ + StatusCode buildContainerFromMultipleCollections(const std::vector<std::string> &collections, const std::string& out_contName); + + /** currently in DAOD_PHYS TruthTop have links to Ws from the TruthBoson collection, which have no link to their decay products; + * we have therefore to associate the W from the TruthBoson collections to those in the TruthBosonsWithDecayParticles collection. + * This method will use the helper method decorateCollectionWithLinksToAnotherCollection to decorate bosons in the TruthBoson collection with + * "AT_linkToTruthBosonsWithDecayParticles", which is a link to the same bosons in the TruthBosonsWithDecayParticles collection + */ + StatusCode linkBosonCollections(); + + ///helper method to handle retriveing the truth particle linked in the decoration of another particle + const xAOD::TruthParticle* getTruthParticleLinkedFromDecoration(const xAOD::TruthParticle* part, const std::string &decorationName); + + private: + /**helper method currently used in DAOD_PHYS to link particles from a given collection to the same particles included in another collection; + * needed because particles may be duplicated in different collections, but their navigation links may only be there in some of them... + */ + StatusCode decorateCollectionWithLinksToAnotherCollection(const std::string &collectionToDecorate, const std::string &collectionToLink, const std::string &nameOfDecoration); + + }; } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarGammaPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarGammaPartonHistory.h new file mode 100644 index 000000000000..235f5c300805 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarGammaPartonHistory.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPPARTONS_CalcTtbarGammaPartonHistory_H +#define ANALYSISTOP_TOPPARTONS_CalcTtbarGammaPartonHistory_H + +/** + * @author John Morris <john.morris@cern.ch> + * @author Silvestre Marino Romano <sromanos@cern.ch> + * @author Samuel Calvet <scalvet@cern.ch> + * + * @brief CalcTtbarGammaPartonHistory + * Class derived from CalcTopPartonHistory, used to store ttbargamma variables + * + * $Revision: 658996 $ + * $Date: 2015-04-04 16:57:15 +0100 (Sat, 04 Apr 2015) $ + * + **/ + + +// Framework include(s): +#include "TopPartons/CalcTopPartonHistory.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "TopPartons/PartonHistory.h" + +// forward declaration(s): +namespace top { + class TopConfig; +} + +namespace top { + class CalcTtbarGammaPartonHistory: public CalcTopPartonHistory { + public: + explicit CalcTtbarGammaPartonHistory(const std::string& name); + virtual ~CalcTtbarGammaPartonHistory() {} + + //Storing parton history for ttbargamma analysis + CalcTtbarGammaPartonHistory(const CalcTtbarGammaPartonHistory& rhs) = delete; + CalcTtbarGammaPartonHistory(CalcTtbarGammaPartonHistory&& rhs) = delete; + CalcTtbarGammaPartonHistory& operator = (const CalcTtbarGammaPartonHistory& rhs) = delete; + + void ttbarGammaHistorySaver(const xAOD::TruthParticleContainer* truthParticles, + xAOD::PartonHistory* ttbarGammaPartonHistory); + + virtual StatusCode execute(); + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarLightPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarLightPartonHistory.h new file mode 100644 index 000000000000..2eed96151099 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarLightPartonHistory.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPPARTONS_CALCTTBARLIGHTPARTONHISTORY_H +#define ANALYSISTOP_TOPPARTONS_CALCTTBARLIGHTPARTONHISTORY_H + +/** + * @author John Morris <john.morris@cern.ch> + * @author Silvestre Marino Romano <sromanos@cern.ch> + * @author Samuel Calvet <scalvet@cern.ch> + * @author Sonja Zeissner <sonja.zeissner@cern.ch> + * + * @brief CalcTtbarLightPartonHistory + * Class derived from CalcTopPartonHistory, used to store ttbar variables + * + * + **/ + + +// Framework include(s): +#include "TopPartons/CalcTopPartonHistory.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "TopPartons/PartonHistory.h" + +// forward declaration(s): +namespace top { + class TopConfig; +} + +namespace top { + class CalcTtbarLightPartonHistory: public CalcTopPartonHistory { + public: + explicit CalcTtbarLightPartonHistory(const std::string& name); + virtual ~CalcTtbarLightPartonHistory() {} + + //Storing parton history for ttbar resonance analysis + CalcTtbarLightPartonHistory(const CalcTtbarLightPartonHistory& rhs) = delete; + CalcTtbarLightPartonHistory(CalcTtbarLightPartonHistory&& rhs) = delete; + CalcTtbarLightPartonHistory& operator = (const CalcTtbarLightPartonHistory& rhs) = delete; + + void ttbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* ttbarPartonHistory); + + virtual StatusCode execute(); + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarPartonHistory.h index 2b0e7cbac023..46f112cc91a9 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarPartonHistory.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTtbarPartonHistory.h @@ -1,22 +1,22 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOP_TOPPARTONS_CALCTTBARPARTONHISTORY_H #define ANALYSISTOP_TOPPARTONS_CALCTTBARPARTONHISTORY_H /** - * @author John Morris <john.morris@cern.ch> - * @author Silvestre Marino Romano <sromanos@cern.ch> - * @author Samuel Calvet <scalvet@cern.ch> - * - * @brief CalcTtbarPartonHistory - * Class derived from CalcTopPartonHistory, used to store ttbar variables - * - * $Revision: 658996 $ - * $Date: 2015-04-04 17:57:15 +0200 (Sat, 04 Apr 2015) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * @author Silvestre Marino Romano <sromanos@cern.ch> + * @author Samuel Calvet <scalvet@cern.ch> + * + * @brief CalcTtbarPartonHistory + * Class derived from CalcTopPartonHistory, used to store ttbar variables + * + * $Revision: 658996 $ + * $Date: 2015-04-04 16:57:15 +0100 (Sat, 04 Apr 2015) $ + * + **/ // Framework include(s): @@ -25,28 +25,25 @@ #include "TopPartons/PartonHistory.h" // forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class CalcTtbarPartonHistory : public CalcTopPartonHistory{ - public: - explicit CalcTtbarPartonHistory( const std::string& name ); - virtual ~CalcTtbarPartonHistory() {} - - //Storing parton history for ttbar resonance analysis - CalcTtbarPartonHistory(const CalcTtbarPartonHistory& rhs) = delete; - CalcTtbarPartonHistory(CalcTtbarPartonHistory&& rhs) = delete; - CalcTtbarPartonHistory& operator=(const CalcTtbarPartonHistory& rhs) = delete; - - void ttbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* ttbarPartonHistory); - - virtual StatusCode execute(); - +namespace top { + class CalcTtbarPartonHistory: public CalcTopPartonHistory { + public: + explicit CalcTtbarPartonHistory(const std::string& name); + virtual ~CalcTtbarPartonHistory() {} + + //Storing parton history for ttbar resonance analysis + CalcTtbarPartonHistory(const CalcTtbarPartonHistory& rhs) = delete; + CalcTtbarPartonHistory(CalcTtbarPartonHistory&& rhs) = delete; + CalcTtbarPartonHistory& operator = (const CalcTtbarPartonHistory& rhs) = delete; + + void ttbarHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* ttbarPartonHistory); + + virtual StatusCode execute(); }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTzqPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTzqPartonHistory.h new file mode 100644 index 000000000000..5a480851276e --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcTzqPartonHistory.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPPARTONS_CALCTzqPARTONHISTORY_H +#define ANALYSISTOP_TOPPARTONS_CALCTzqPARTONHISTORY_H + + +// Framework include(s): +#include "TopPartons/CalcTopPartonHistory.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "TopPartons/PartonHistory.h" + +// forward declaration(s): +namespace top { + class TopConfig; +} + +namespace top { + class CalcTzqPartonHistory: public CalcTopPartonHistory { + public: + explicit CalcTzqPartonHistory(const std::string& name); + virtual ~CalcTzqPartonHistory() {} + + struct tZ_values { + //Z boson + TLorentzVector Z_p4; + TLorentzVector Zdecay1_p4; + int Zdecay1_pdgId; + int Zdecay1_status; + TLorentzVector Zdecay2_p4; + int Zdecay2_pdgId; + int Zdecay2_status; + + + + + //b + TLorentzVector b_p4; + int b_pdgId; + } tZ; + //Storing parton history for ttbar resonance analysis + CalcTzqPartonHistory(const CalcTzqPartonHistory& rhs) = delete; + CalcTzqPartonHistory(CalcTzqPartonHistory&& rhs) = delete; + CalcTzqPartonHistory& operator = (const CalcTzqPartonHistory& rhs) = delete; + + void TZHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* TzqPartonHistory); + + //handle gamma radiation of taus + const xAOD::TruthParticle* findAfterGamma(const xAOD::TruthParticle* particle); + + ///Store the four-momentum of several particles in the Z decay chain + bool Zllqq(const xAOD::TruthParticleContainer* truthParticles, int start); + + //Store four-momentum of bottom quark + bool bottom(const xAOD::TruthParticleContainer* truthParticles, int start); + + int sign(int a); + + virtual StatusCode execute(); + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcWlvPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcWlvPartonHistory.h index 2946584d035c..4c3bffb873da 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcWlvPartonHistory.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcWlvPartonHistory.h @@ -1,22 +1,22 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ #ifndef ANALYSISTOP_TOPPARTONS_CALCWLVPARTONHISTORY_H #define ANALYSISTOP_TOPPARTONS_CALCWLVPARTONHISTORY_H /** - * @author John Morris <john.morris@cern.ch> - * @author Silvestre Marino Romano <sromanos@cern.ch> - * @author Samuel Calvet <scalvet@cern.ch> - * - * @brief CalcWlvPartonHistory - * Class derived from CalcTopPartonHistory, used to store ttbar variables - * - * $Revision: 782353 $ - * $Date: 2016-11-04 13:11:17 +0100 (Fri, 04 Nov 2016) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * @author Silvestre Marino Romano <sromanos@cern.ch> + * @author Samuel Calvet <scalvet@cern.ch> + * + * @brief CalcWlvPartonHistory + * Class derived from CalcTopPartonHistory, used to store ttbar variables + * + * $Revision: 782353 $ + * $Date: 2016-11-04 12:11:17 +0000 (Fri, 04 Nov 2016) $ + * + **/ // Framework include(s): @@ -25,28 +25,25 @@ #include "TopPartons/PartonHistory.h" // forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class CalcWlvPartonHistory : public CalcTopPartonHistory{ - public: - explicit CalcWlvPartonHistory( const std::string& name ); - virtual ~CalcWlvPartonHistory() {} - - //Storing parton history for ttbar resonance analysis - CalcWlvPartonHistory(const CalcWlvPartonHistory& rhs) = delete; - CalcWlvPartonHistory(CalcWlvPartonHistory&& rhs) = delete; - CalcWlvPartonHistory& operator=(const CalcWlvPartonHistory& rhs) = delete; - - void WlvHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* wlvPartonHistory); - - virtual StatusCode execute(); - +namespace top { + class CalcWlvPartonHistory: public CalcTopPartonHistory { + public: + explicit CalcWlvPartonHistory(const std::string& name); + virtual ~CalcWlvPartonHistory() {} + + //Storing parton history for ttbar resonance analysis + CalcWlvPartonHistory(const CalcWlvPartonHistory& rhs) = delete; + CalcWlvPartonHistory(CalcWlvPartonHistory&& rhs) = delete; + CalcWlvPartonHistory& operator = (const CalcWlvPartonHistory& rhs) = delete; + + void WlvHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* wlvPartonHistory); + + virtual StatusCode execute(); }; - } #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcWtbPartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcWtbPartonHistory.h new file mode 100644 index 000000000000..c26d0fd4889e --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/CalcWtbPartonHistory.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPPARTONS_CALCWTBPARTONHISTORY_H +#define ANALYSISTOP_TOPPARTONS_CALCWTBPARTONHISTORY_H + +/** + * @author Tomas Dado <tomas.dado@cern.ch> + * + * @brief CalcWtbPartonHistory + * Class derived from CalcTopPartonHistory, used to store Wt SingleTop variables + * + * $Revision: 658996 $ + * $Date: 2015-04-04 16:57:15 +0100 (Sat, 04 Apr 2015) $ + * + **/ + + +// Framework include(s): +#include "TopPartons/CalcTopPartonHistory.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "TopPartons/PartonHistory.h" + +// forward declaration(s): +namespace top { + class TopConfig; +} + +namespace top { + class CalcWtbPartonHistory: public CalcTopPartonHistory { + public: + explicit CalcWtbPartonHistory(const std::string& name); + + //Storing parton history for Wtb SingleTop analysis + CalcWtbPartonHistory(const CalcWtbPartonHistory& rhs) = delete; + CalcWtbPartonHistory(CalcWtbPartonHistory&& rhs) = delete; + CalcWtbPartonHistory& operator = (const CalcWtbPartonHistory& rhs) = delete; + + void wtbHistorySaver(const xAOD::TruthParticleContainer* truthParticles, xAOD::PartonHistory* wtSTPartonHistory); + + virtual StatusCode execute() override; + }; +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/PartonHistory.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/PartonHistory.h index 5bbfdb28caed..796e8fca2b21 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/PartonHistory.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/PartonHistory.h @@ -1,33 +1,33 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ // $Id: PartonHistory.h 782353 2016-11-04 12:11:17Z scalvet $ #ifndef ANALYSISTOP_TOPPARTONS_PARTONHISORTY_H #define ANALYSISTOP_TOPPARTONS_PARTONHISORTY_H /** - * @author John Morris <john.morris@cern.ch> - * @author Silvestre Marino Romano <sromanos@cern.ch> - * @author Samuel Calvet <scalvet@cern.ch> - * - * @brief PartonHistory - * A simple xAOD class which we can persist into a mini-xAOD - * The xAOD EDM is way too complex, so let's simplify it - * It's not like ROOT can do schema evolution...... - * - * In order for this object to be used by any - * PartonHistory factory, it contains no AuxElements - * Everything should be done via decoration - * - * This really should be an AuxInfoBase type of xAOD object - * But John can't figure out how to copy these to the - * output mini-xAOD.....yet - * - * $Revision: 782353 $ - * $Date: 2016-11-04 13:11:17 +0100 (Fri, 04 Nov 2016) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * @author Silvestre Marino Romano <sromanos@cern.ch> + * @author Samuel Calvet <scalvet@cern.ch> + * + * @brief PartonHistory + * A simple xAOD class which we can persist into a mini-xAOD + * The xAOD EDM is way too complex, so let's simplify it + * It's not like ROOT can do schema evolution...... + * + * In order for this object to be used by any + * PartonHistory factory, it contains no AuxElements + * Everything should be done via decoration + * + * This really should be an AuxInfoBase type of xAOD object + * But John can't figure out how to copy these to the + * output mini-xAOD.....yet + * + * $Revision: 782353 $ + * $Date: 2016-11-04 12:11:17 +0000 (Fri, 04 Nov 2016) $ + * + **/ // EDM include(s): #include "AthContainers/DataVector.h" @@ -36,34 +36,38 @@ #include "xAODCore/CLASS_DEF.h" #include <vector> -namespace xAOD{ - - /// Aux Container - class PartonHistoryAuxContainer : public AuxContainerBase { - public: - /// Default constructor - PartonHistoryAuxContainer(); +namespace xAOD { + /// Aux Container + class PartonHistoryAuxContainer: public AuxContainerBase { + public: + /// Default constructor + PartonHistoryAuxContainer(); }; // end Aux container - + /// Interface class - class PartonHistory : public SG::AuxElement { - public: - /// Default constructor - PartonHistory(); - /// Default desturctor - virtual ~PartonHistory(){} + class PartonHistory: public SG::AuxElement { + public: + /// Default constructor + PartonHistory(); + /// Default desturctor + virtual ~PartonHistory() {} - void IniVarTtbar(); - void IniVarTbbar(); - void IniVarWlv(); - - }; - typedef DataVector < xAOD::PartonHistory > PartonHistoryContainer; + void IniVarTtbar(); + void IniVarTzq(); + void IniVarTtbarLight(); + void IniVarTbbar(); + void IniVarWlv(); + void IniVarWtb(); + void IniVarZ(); + void IniVarTtGamma(); + void IniVarThq(); + }; + typedef DataVector < xAOD::PartonHistory > PartonHistoryContainer; } // Dictonaries -CLASS_DEF( xAOD::PartonHistory , 135846343 , 1 ) -CLASS_DEF( xAOD::PartonHistoryContainer , 1219079565 , 1 ) -CLASS_DEF( xAOD::PartonHistoryAuxContainer , 1244378748 , 1 ) +CLASS_DEF(xAOD::PartonHistory, 135846343, 1) +CLASS_DEF(xAOD::PartonHistoryContainer, 1219079565, 1) +CLASS_DEF(xAOD::PartonHistoryAuxContainer, 1244378748, 1) #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/PartonHistoryUtils.h b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/PartonHistoryUtils.h new file mode 100644 index 000000000000..d9a35340a8f1 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/TopPartons/PartonHistoryUtils.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPPARTONS_TOPPARTONUTILS_H +#define ANALYSISTOP_TOPPARTONS_TOPPARTONUTILS_H + +#include "xAODTruth/TruthParticleContainer.h" + +#include "TLorentzVector.h" + +namespace top { +namespace PartonHistoryUtils { + + struct HiggsDecay { + /// direct higgs decay + TLorentzVector decay1_vector; + int decay1_pdgId; + TLorentzVector decay2_vector; + int decay2_pdgId; + int tau_decay1_isHadronic; + int tau_decay2_isHadronic; + + /// subsequent decays of W/Z + TLorentzVector decay1_from_decay1_vector; + int decay1_from_decay1_pdgId; + TLorentzVector decay2_from_decay1_vector; + int decay2_from_decay1_pdgId; + TLorentzVector decay1_from_decay2_vector; + int decay1_from_decay2_pdgId; + TLorentzVector decay2_from_decay2_vector; + int decay2_from_decay2_pdgId; + int tau_decay1_from_decay1_isHadronic; + int tau_decay2_from_decay1_isHadronic; + int tau_decay1_from_decay2_isHadronic; + int tau_decay2_from_decay2_isHadronic; + }; + + ///Return particle after FSR (before the decay vertex) + const xAOD::TruthParticle* findAfterFSR(const xAOD::TruthParticle* particle); + + ///Return true when particle is a top before FSR + bool hasParticleIdenticalParent(const xAOD::TruthParticle* particle); + + ///handle gamma radiation of taus + const xAOD::TruthParticle* findAfterGamma(const xAOD::TruthParticle* particle); + + /// Store higgs decay information + HiggsDecay AnalyzeHiggsDecay(const xAOD::TruthParticle* higgs); + + /// Check if tau decays hadronically or not + bool TauIsHadronic(const xAOD::TruthParticle* tau, bool &isOk); +} +} + +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt index 1f3581b88c2f..e89acc744f35 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt @@ -13,11 +13,10 @@ atlas_depends_on_subdirs( PUBLIC xAODEgamma xAODMuon xAODJet + xAODTracking ElectronPhotonFourMomentumCorrection ElectronPhotonSelectorTools ElectronPhotonShowerShapeFudgeTool - MuonMomentumCorrections - MuonSelectorTools TauAnalysisTools JetCalibTools JetCPInterfaces @@ -30,8 +29,11 @@ atlas_depends_on_subdirs( PUBLIC TopConfiguration TopEvent TopJetSubstructure - xAODTracking - InDetTrackSystematicsTools ) + TopParticleLevel + InDetTrackSystematicsTools + MuonAnalysisInterfaces + MuonMomentumCorrections + FTagAnalysisInterfaces) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) @@ -55,12 +57,10 @@ atlas_add_library( TopSystematicObjectMaker Root/*.cxx Root/*.h Root/*.icc ElectronPhotonFourMomentumCorrectionLib ElectronPhotonSelectorToolsLib ElectronPhotonShowerShapeFudgeToolLib - MuonMomentumCorrectionsLib - MuonSelectorToolsLib TauAnalysisToolsLib JetCalibToolsLib JetCPInterfaces - JetResolutionLib + #JetResolutionLib JetInterface METInterface METUtilitiesLib @@ -69,8 +69,13 @@ atlas_add_library( TopSystematicObjectMaker Root/*.cxx Root/*.h Root/*.icc TopConfiguration TopEvent TopJetSubstructure + TopParticleLevel xAODTracking InDetTrackSystematicsToolsLib + MuonAnalysisInterfacesLib + MuonMomentumCorrectionsLib + FTagAnalysisInterfacesLib + #BoostedJetTaggersLib ${ROOT_LIBRARIES} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/EgammaObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/EgammaObjectCollectionMaker.cxx index f4a2bb435957..d681bd8f1597 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/EgammaObjectCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/EgammaObjectCollectionMaker.cxx @@ -1,12 +1,14 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ -// $Id: EgammaObjectCollectionMaker.cxx 802735 2017-04-11 16:38:01Z tpelzer $ +// $Id: EgammaObjectCollectionMaker.cxx 811374 2017-10-24 13:04:52Z iconnell $ #include "TopSystematicObjectMaker/EgammaObjectCollectionMaker.h" #include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/TreeFilter.h" #include "TopEvent/EventTools.h" +#include "AthContainers/AuxElement.h" #include "xAODEventInfo/EventInfo.h" #include "xAODEgamma/ElectronContainer.h" #include "xAODEgamma/ElectronAuxContainer.h" @@ -19,143 +21,225 @@ #include <list> -namespace top{ - - EgammaObjectCollectionMaker::EgammaObjectCollectionMaker( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + EgammaObjectCollectionMaker::EgammaObjectCollectionMaker(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), - + m_specifiedSystematicsPhotons(), m_specifiedSystematicsElectrons(), + m_specifiedSystematicsFwdElectrons(), m_recommendedSystematicsPhotons(), m_recommendedSystematicsElectrons(), + m_recommendedSystematicsFwdElectrons(), m_calibrationTool("CP::EgammaCalibrationAndSmearingTool"), m_photonFudgeTool("PhotonFudgeTool"), - + m_isolationTool_LooseTrackOnly("CP::IsolationTool_LooseTrackOnly"), m_isolationTool_Loose("CP::IsolationTool_Loose"), + m_isolationTool_PflowLoose("CP::IsolationTool_PflowLoose"), + m_isolationTool_Tight("CP::IsolationTool_Tight"), + m_isolationTool_PflowTight("CP::IsolationTool_PflowTight"), m_isolationTool_Gradient("CP::IsolationTool_Gradient"), m_isolationTool_GradientLoose("CP::IsolationTool_GradientLoose"), m_isolationTool_FixedCutTight("CP::IsolationTool_FixedCutTight"), m_isolationTool_FixedCutTightTrackOnly("CP::IsolationTool_FixedCutTightTrackOnly"), + m_isolationTool_TightTrackOnly("CP::IsolationTool_TightTrackOnly"), + m_isolationTool_TightTrackOnly_FixedRad("CP::IsolationTool_TightTrackOnly_FixedRad"), m_isolationTool_FixedCutTightCaloOnly("CP::IsolationTool_FixedCutTightCaloOnly"), + m_isolationTool_TightCaloOnly("CP::IsolationTool_TightCaloOnly"), m_isolationTool_FixedCutLoose("CP::IsolationTool_FixedCutLoose"), - m_isolationCorr("CP::IsolationCorrectionTool") - { - declareProperty( "config" , m_config ); - - declareProperty( "EgammaCalibrationAndSmearingTool" , m_calibrationTool ); - - declareProperty( "IsolationTool_LooseTrackOnly" , m_isolationTool_LooseTrackOnly ); - declareProperty( "IsolationTool_Loose" , m_isolationTool_Loose ); - declareProperty( "IsolationTool_Gradient" , m_isolationTool_Gradient ); - declareProperty( "IsolationTool_GradientLoose" , m_isolationTool_GradientLoose ); - declareProperty( "IsolationTool_FixedCutTight" , m_isolationTool_FixedCutTight ); - declareProperty( "IsolationTool_FixedCutTightTrackOnly" , m_isolationTool_FixedCutTightTrackOnly ); - declareProperty( "IsolationTool_FixedCutTightCaloOnly" , m_isolationTool_FixedCutTightCaloOnly ); - declareProperty( "IsolationTool_FixedCutLoose" , m_isolationTool_FixedCutLoose ); - declareProperty( "IsolationCorrectionTool", m_isolationCorr ); - } - - StatusCode EgammaObjectCollectionMaker::initialize() - { - ATH_MSG_INFO(" top::EgammaObjectCollectionMaker initialize" ); - - top::check( m_calibrationTool.retrieve() , "Failed to retrieve egamma calibration tool" ); - + m_isolationTool_FixedCutHighPtCaloOnly("CP::IsolationTool_FixedCutHighPtCaloOnly"), + m_isolationTool_FCHighPtCaloOnly("CP::IsolationTool_FCHighPtCaloOnly"), + m_isolationTool_HighPtCaloOnly("CP::IsolationTool_HighPtCaloOnly"), + m_isolationTool_FCTight("CP::IsolationTool_FCTight"), + m_isolationTool_FCLoose("CP::IsolationTool_FCLoose"), + m_isolationTool_PLVTight("CP::IsolationTool_PLVTight"), + m_isolationTool_PLVLoose("CP::IsolationTool_PLVLoose"), +// m_isolationTool_LowPtPLV("CP::IsolationTool_LowPtPLV"), + m_isolationCorr("CP::IsolationCorrectionTool") { + declareProperty("config", m_config); + + declareProperty("EgammaCalibrationAndSmearingTool", m_calibrationTool); + + declareProperty("IsolationTool_LooseTrackOnly", m_isolationTool_LooseTrackOnly); + declareProperty("IsolationTool_Loose", m_isolationTool_Loose); + declareProperty("IsolationTool_PflowLoose", m_isolationTool_PflowLoose); + declareProperty("IsolationTool_Tight", m_isolationTool_Tight); + declareProperty("IsolationTool_PflowTight", m_isolationTool_PflowTight); + declareProperty("IsolationTool_Gradient", m_isolationTool_Gradient); + declareProperty("IsolationTool_GradientLoose", m_isolationTool_GradientLoose); + declareProperty("IsolationTool_FixedCutTight", m_isolationTool_FixedCutTight); + declareProperty("IsolationTool_FixedCutTightTrackOnly", m_isolationTool_FixedCutTightTrackOnly); + declareProperty("IsolationTool_TightTrackOnly", m_isolationTool_TightTrackOnly); + declareProperty("IsolationTool_TightTrackOnly_FixedRad", m_isolationTool_TightTrackOnly_FixedRad); + declareProperty("IsolationTool_FixedCutTightCaloOnly", m_isolationTool_FixedCutTightCaloOnly); + declareProperty("IsolationTool_TightCaloOnly", m_isolationTool_TightCaloOnly); + declareProperty("IsolationTool_FixedCutLoose", m_isolationTool_FixedCutLoose); + declareProperty("IsolationTool_FixedCutHighPtCaloOnly", m_isolationTool_FixedCutHighPtCaloOnly); + declareProperty("IsolationTool_FCHighPtCaloOnly", m_isolationTool_FCHighPtCaloOnly); + declareProperty("IsolationTool_HighPtCaloOnly", m_isolationTool_HighPtCaloOnly); + declareProperty("IsolationTool_FCTight", m_isolationTool_FCTight); + declareProperty("IsolationTool_FCLoose", m_isolationTool_FCLoose); + declareProperty("IsolationTool_PLVTight", m_isolationTool_PLVTight); + declareProperty("IsolationTool_PLVLoose", m_isolationTool_PLVLoose); +// declareProperty("IsolationTool_LowPtPLV", m_isolationTool_LowPtPLV); + declareProperty("IsolationCorrectionTool", m_isolationCorr); + } + + StatusCode EgammaObjectCollectionMaker::initialize() { + ATH_MSG_INFO(" top::EgammaObjectCollectionMaker initialize"); + + top::check(m_calibrationTool.retrieve(), "Failed to retrieve egamma calibration tool"); + + // These flags were for early R21 when we were asked not to calibrate egamma objects + calibrateElectrons = true; + calibrateFwdElectrons = true; + calibratePhotons = true; + if (m_config->usePhotons()) { top::check(m_isolationTool_FixedCutTight.retrieve(), - "Failed to retrieve Isolation Tool" ); + "Failed to retrieve Isolation Tool"); top::check(m_isolationTool_FixedCutTightCaloOnly.retrieve(), "Failed to retrieve Isolation Tool"); top::check(m_isolationTool_FixedCutLoose.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_Tight.retrieve(), + "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_TightCaloOnly.retrieve(), + "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_Loose.retrieve(), + "Failed to retrieve Isolation Tool"); top::check(m_photonFudgeTool.retrieve(), "Failed to retrieve photon shower shape fudge tool"); } if (m_config->useElectrons()) { - top::check( m_isolationTool_LooseTrackOnly.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_Loose.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_Gradient.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_GradientLoose.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_FixedCutTight.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_FixedCutTightTrackOnly.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_FixedCutLoose.retrieve() , "Failed to retrieve Isolation Tool" ); + top::check(m_isolationTool_Gradient.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FCTight.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FCLoose.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FCHighPtCaloOnly.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_HighPtCaloOnly.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_Loose.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_Tight.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_TightTrackOnly.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_TightTrackOnly_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PflowLoose.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PflowTight.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PLVTight.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PLVLoose.retrieve(), "Failed to retrieve Isolation Tool"); +// top::check(m_isolationTool_LowPtPLV.retrieve(), "Failed to retrieve Isolation Tool"); } - - top::check( m_isolationCorr.retrieve() , "Failed to retrieve Isolation Correction Tool" ); + + top::check(m_isolationCorr.retrieve(), "Failed to retrieve Isolation Correction Tool"); std::set<std::string> systPhoton; - std::set<std::string> systElectron; + std::set<std::string> systElectron; + std::set<std::string> systFwdElectron; const std:: string& syststr = m_config->systematics(); - std::set<std::string> syst; + std::set<std::string> syst; - if( !m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr) ){ + if (!m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)) { bool ok = m_config->getSystematicsList(syststr, syst); - if(!ok){ - ATH_MSG_ERROR(" top::EgammaObjectCollectionMaker could not determine systematic list" ); - return StatusCode::FAILURE; + if (!ok) { + ATH_MSG_ERROR(" top::EgammaObjectCollectionMaker could not determine systematic list"); + return StatusCode::FAILURE; } - if(!m_config->contains(syst, "AllElectrons")){ - systElectron=syst; + //here the idea is that if the user specifies AllXXX, we leave syst as an empty string, so that all recommended CP + // systematics are then used + if (!m_config->contains(syst, "AllElectrons")) { + systElectron = syst; } - if(!m_config->contains(syst, "AllPhotons")){ - systPhoton=syst; + if (!m_config->contains(syst, "AllPhotons")) { + systPhoton = syst; + } + if (!m_config->contains(syst, "AllFwdElectrons")) { + systFwdElectron = syst; } } - specifiedSystematicsPhotons( systPhoton ); - specifiedSystematicsElectrons( systElectron ); - + specifiedSystematicsPhotons(systPhoton); + specifiedSystematicsElectrons(systElectron); + specifiedSystematicsFwdElectrons(systFwdElectron); + if (m_config->usePhotons()) { - m_config->systematicsPhotons( specifiedSystematicsPhotons() ); + m_config->systematicsPhotons(specifiedSystematicsPhotons()); } if (m_config->useElectrons()) { - m_config->systematicsElectrons( specifiedSystematicsElectrons() ); + m_config->systematicsElectrons(specifiedSystematicsElectrons()); + } + if (m_config->useFwdElectrons()) { + m_config->systematicsFwdElectrons(specifiedSystematicsFwdElectrons()); } + // bool to decide whether to use certain Egamma tools + m_recomputePhotonFudge = m_config->recomputeCPvars(); + return StatusCode::SUCCESS; } - - StatusCode EgammaObjectCollectionMaker::executePhotons() - { + + StatusCode EgammaObjectCollectionMaker::executePhotons(bool executeNominal) { ///-- Get base photons from xAOD --/// const xAOD::PhotonContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyPhotons() ) , "Failed to retrieve Photons" ); + + top::check(evtStore()->retrieve(xaod, m_config->sgKeyPhotons()), "Failed to retrieve Photons"); ///-- Loop over all systematics --/// - for( auto systematic : m_specifiedSystematicsPhotons ){ - + for (auto systematic : m_specifiedSystematicsPhotons) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + ///-- Tell tool which systematic to use --/// - top::check( m_calibrationTool->applySystematicVariation( systematic ) , "Failed to applySystematicVariation" ); - + top::check(m_calibrationTool->applySystematicVariation(systematic), "Failed to applySystematicVariation"); + ///-- Shallow copy of the xAOD --/// - std::pair< xAOD::PhotonContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *xaod ); - + std::pair< xAOD::PhotonContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( + *xaod); + ///-- Loop over the xAOD Container and apply corrections--/// - for( auto photon : *(shallow_xaod_copy.first) ){ - + for (auto photon : *(shallow_xaod_copy.first)) { ///-- Apply correction to object --/// - // Needs a calo cluster so carry on if no cluster - if (!photon->caloCluster()) continue; - top::check( m_calibrationTool->applyCorrection( *photon ) , "Failed to applyCorrection" ); - - top::check(m_isolationCorr->applyCorrection(*photon), - "Failed to apply photon isolation leakage correction"); - - // Only apply shower shape fudging on full simulation MC - if (m_config->isMC() && !m_config->isAFII()) { - top::check(m_photonFudgeTool->applyCorrection(*photon), - "Failed to apply photon shower shape fudge tool"); + // Needs a calo cluster so carry on if no cluster + if (!photon->caloCluster()) continue; + + if (calibratePhotons) { + top::check(m_calibrationTool->applyCorrection(*photon), + "Failed to applyCorrection"); + top::check(m_isolationCorr->applyCorrection(*photon), + "Failed to apply photon isolation leakage correction"); + + // Only apply shower shape fudging on full simulation MC + if (m_config->isMC() && !m_config->isAFII() && m_recomputePhotonFudge && m_config->getDerivationStream() != "PHYS") { + if (m_photonFudgeTool->applyCorrection(*photon) == 0) { // 0: error, 1: OutOfRange (not possible), 2: OK + // ElectronPhotonShowerShapeFudgeTool::applyCorrection can return an error for 3 reasons + // 1) shower shapes not all found, 2) bad cluster, 3) shower shapes not all set. + // 1 & 3 are most likely due to the smart slimming (no PhotonsDetailedCPContent), whereas 2 is an actual + // issue. + // Check for case 2 now: + if (photon->caloCluster() == nullptr) { + ATH_MSG_ERROR("Photon " << photon << " had no calo cluster - this is bad!"); + return StatusCode::FAILURE; + } else { + // We're now in case 1 or 3 + ATH_MSG_WARNING( + " Didn't find the necessary photon shower shapes variables for the ElectronPhotonShowerShapeFudgeTool! (but don't worry, you're still getting correctly ID'd photons)"); + // Keep going, but don't try to use the tool anymore + m_recomputePhotonFudge = false; + } + } + } } - ///-- Isolation selection --/// + static const SG::AuxElement::ConstAccessor<float> ptcone20_TightTTVA_pt1000("ptcone20_TightTTVA_pt1000"); char passIsol_FixedCutTight(0); char passIsol_FixedCutTightCaloOnly(0); char passIsol_FixedCutLoose(0); + char passIsol_Tight(0); + char passIsol_TightCaloOnly(0); + char passIsol_Loose(0); if (m_isolationTool_FixedCutTight->accept(*photon)) { passIsol_FixedCutTight = 1; } @@ -165,220 +249,415 @@ namespace top{ if (m_isolationTool_FixedCutLoose->accept(*photon)) { passIsol_FixedCutLoose = 1; } + if (m_isolationTool_TightCaloOnly->accept(*photon)) { + passIsol_TightCaloOnly = 1; + } + if (ptcone20_TightTTVA_pt1000.isAvailable(*photon)) { + if (m_isolationTool_Tight->accept(*photon)) { + passIsol_Tight = 1; + } + if (m_isolationTool_Loose->accept(*photon)) { + passIsol_Loose = 1; + } + } photon->auxdecor<char>("AnalysisTop_Isol_FixedCutTight") = passIsol_FixedCutTight; photon->auxdecor<char>("AnalysisTop_Isol_FixedCutTightCaloOnly") = passIsol_FixedCutTightCaloOnly; photon->auxdecor<char>("AnalysisTop_Isol_FixedCutLoose") = passIsol_FixedCutLoose; + photon->auxdecor<char>("AnalysisTop_Isol_Tight") = passIsol_Tight; + photon->auxdecor<char>("AnalysisTop_Isol_TightCaloOnly") = passIsol_TightCaloOnly; + photon->auxdecor<char>("AnalysisTop_Isol_Loose") = passIsol_Loose; } ///-- set links to original objects- needed for MET calculation --/// - bool setLinks = xAOD::setOriginalObjectLink( *xaod, *shallow_xaod_copy.first ); - if (!setLinks) - ATH_MSG_ERROR(" Cannot set original object links for photons, MET recalculation may struggle" ); - + bool setLinks = xAOD::setOriginalObjectLink(*xaod, *shallow_xaod_copy.first); + if (!setLinks) ATH_MSG_ERROR(" Cannot set original object links for photons, MET recalculation may struggle"); + ///-- Save corrected xAOD Container to StoreGate / TStore --/// - std::string outputSGKey = m_config->sgKeyPhotons( systematic.hash() ); + std::string outputSGKey = m_config->sgKeyPhotons(systematic.hash()); std::string outputSGKeyAux = outputSGKey + "Aux."; - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_xaod_copy.first , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_xaod_copy.second , outputSGKeyAux ); - if( !save || !saveAux ){ + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + + if (!save || !saveAux) { return StatusCode::FAILURE; } - } // Loop over all systematics - + } // Loop over all systematics return StatusCode::SUCCESS; - } - - StatusCode EgammaObjectCollectionMaker::executeElectrons() - { + } + + StatusCode EgammaObjectCollectionMaker::executeElectrons(bool executeNominal) { + static const SG::AuxElement::ConstAccessor<float> ptcone20_TightTTVALooseCone_pt1000("ptcone20_TightTTVALooseCone_pt1000"); + static const SG::AuxElement::ConstAccessor<float> ptvarcone20_TightTTVA_pt1000("ptvarcone20_TightTTVA_pt1000"); + static const SG::AuxElement::ConstAccessor<float> ptvarcone30_TightTTVALooseCone_pt1000("ptvarcone30_TightTTVALooseCone_pt1000"); + static const SG::AuxElement::ConstAccessor<float> ptvarcone30_TightTTVALooseCone_pt500("ptvarcone30_TightTTVALooseCone_pt500"); + static const SG::AuxElement::ConstAccessor<float> neflowisol20("neflowisol20"); + static const SG::AuxElement::ConstAccessor<short> PLV_TrackJetNTrack("PromptLeptonInput_TrackJetNTrack"); + static const SG::AuxElement::ConstAccessor<float> PLV_DRlj("PromptLeptonInput_DRlj"); + static const SG::AuxElement::ConstAccessor<float> PLV_PtRel("PromptLeptonInput_PtRel"); + static const SG::AuxElement::ConstAccessor<float> PLV_PtFrac("PromptLeptonInput_PtFrac"); + static const SG::AuxElement::ConstAccessor<float> PLV_PromptLeptonVeto("PromptLeptonVeto"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_FCTight("AnalysisTop_Isol_FCTight"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_FCLoose("AnalysisTop_Isol_FCLoose"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_Tight("AnalysisTop_Isol_Tight"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_Loose("AnalysisTop_Isol_Loose"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_TightTrackOnly("AnalysisTop_Isol_TightTrackOnly"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_TightTrackOnly_FixedRad("AnalysisTop_Isol_TightTrackOnly_FixedRad"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_PflowTight("AnalysisTop_Isol_PflowTight"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_PflowLoose("AnalysisTop_Isol_PflowLoose"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_PLVTight("AnalysisTop_Isol_PLVTight"); + static SG::AuxElement::Accessor<char> AnalysisTop_Isol_PLVLoose("AnalysisTop_Isol_PLVLoose"); +// static SG::AuxElement::Decorator<float> byhand_LowPtPLV("LowPtPLV"); const xAOD::EventInfo* eventInfo(nullptr); - top::check( evtStore()->retrieve( eventInfo, m_config->sgKeyEventInfo() ), "Failed to retrieve EventInfo"); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); float beam_pos_sigma_x = eventInfo->beamPosSigmaX(); float beam_pos_sigma_y = eventInfo->beamPosSigmaY(); float beam_pos_sigma_xy = eventInfo->beamPosSigmaXY(); - + ///-- Get base electrons from xAOD --/// const xAOD::ElectronContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyElectrons() ) , "Failed to retrieve Electrons" ); - + top::check(evtStore()->retrieve(xaod, m_config->sgKeyElectrons()), "Failed to retrieve Electrons"); + ///-- Loop over all systematics --/// - for( auto systematic : m_specifiedSystematicsElectrons ){ - + for (auto systematic : m_specifiedSystematicsElectrons) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + ///-- Tell tool which systematic to use -/// - top::check( m_calibrationTool->applySystematicVariation( systematic ) , "Failed to applySystematicVariation" ); - + top::check(m_calibrationTool->applySystematicVariation(systematic), "Failed to applySystematicVariation"); + ///-- Shallow copy of the xAOD --/// - std::pair< xAOD::ElectronContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *xaod ); - + std::pair< xAOD::ElectronContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( + *xaod); + ///-- Loop over the xAOD Container --/// - for( auto electron : *(shallow_xaod_copy.first) ){ - - // Apply correction to object + for (auto electron : *(shallow_xaod_copy.first)) { + // Apply correction to object // should not affect derivations if there is no CC or track thinning - if (electron->caloCluster() != nullptr && electron->trackParticle() != nullptr) { // derivations might remove CC and tracks for low pt electrons - top::check( m_calibrationTool->applyCorrection( *electron ) , "Failed to applyCorrection" ); - - top::check( m_isolationCorr->applyCorrection( *electron ), "Failed to apply leakage correction" ); - - double d0sig = xAOD::TrackingHelpers::d0significance( electron->trackParticle(), - beam_pos_sigma_x, - beam_pos_sigma_y, - beam_pos_sigma_xy ); - electron->auxdecor<float>("d0sig") = d0sig; - - if( eventInfo->isAvailable<float>("AnalysisTop_PRIVTX_z_position") ){ - float vtx_z = eventInfo->auxdata<float>("AnalysisTop_PRIVTX_z_position"); - float delta_z0 = electron->trackParticle()->z0() + electron->trackParticle()->vz() - vtx_z; - electron->auxdecor<float>("delta_z0") = delta_z0; - electron->auxdecor<float>("delta_z0_sintheta") = delta_z0*std::sin( electron->trackParticle()->theta() ); - - } - } - + if (electron->caloCluster() != nullptr && electron->trackParticle() != nullptr) { // derivations might remove CC + // and tracks for low pt + // electrons + if (calibrateElectrons) { + top::check(m_calibrationTool->applyCorrection(*electron), "Failed to applyCorrection"); + top::check(m_isolationCorr->applyCorrection(*electron), "Failed to apply leakage correction"); + } + + double d0sig = xAOD::TrackingHelpers::d0significance(electron->trackParticle(), + beam_pos_sigma_x, + beam_pos_sigma_y, + beam_pos_sigma_xy); + electron->auxdecor<float>("d0sig") = d0sig; + + if (eventInfo->isAvailable<float>("AnalysisTop_PRIVTX_z_position")) { + float vtx_z = eventInfo->auxdata<float>("AnalysisTop_PRIVTX_z_position"); + float delta_z0 = electron->trackParticle()->z0() + electron->trackParticle()->vz() - vtx_z; + electron->auxdecor<float>("delta_z0") = delta_z0; + electron->auxdecor<float>("delta_z0_sintheta") = delta_z0 * std::sin(electron->trackParticle()->theta()); + } + } + ///-- Isolation selection --/// - char passIsol_LooseTrackOnly(0),passIsol_Loose(0),passIsol_FixedCutTight(0),passIsol_FixedCutTightTrackOnly(0),passIsol_FixedCutLoose(0); - char passIsol_Gradient(0),passIsol_GradientLoose(0); - if (m_isolationTool_LooseTrackOnly->accept( *electron )) {passIsol_LooseTrackOnly = 1;} - if (m_isolationTool_Loose->accept( *electron )) {passIsol_Loose = 1;} - if (m_isolationTool_Gradient->accept( *electron )) {passIsol_Gradient = 1;} - if (m_isolationTool_GradientLoose->accept( *electron )) {passIsol_GradientLoose = 1;} - if (m_isolationTool_FixedCutTight->accept( *electron )) {passIsol_FixedCutTight = 1;} - if (m_isolationTool_FixedCutTightTrackOnly->accept( *electron )) {passIsol_FixedCutTightTrackOnly = 1;} - if (m_isolationTool_FixedCutLoose->accept( *electron )) {passIsol_FixedCutLoose = 1;} - - electron->auxdecor<char>("AnalysisTop_Isol_LooseTrackOnly") = passIsol_LooseTrackOnly; - electron->auxdecor<char>("AnalysisTop_Isol_Loose") = passIsol_Loose; + char passIsol_Gradient(0); + char passIsol_FCHighPtCaloOnly(0); + char passIsol_HighPtCaloOnly(0); + if (m_isolationTool_Gradient->accept(*electron)) { + passIsol_Gradient = 1; + } + if (m_isolationTool_FCHighPtCaloOnly->accept(*electron)) { + passIsol_FCHighPtCaloOnly = 1; + } + if (m_isolationTool_HighPtCaloOnly->accept(*electron)) { + passIsol_HighPtCaloOnly = 1; + } + electron->auxdecor<char>("AnalysisTop_Isol_Gradient") = passIsol_Gradient; - electron->auxdecor<char>("AnalysisTop_Isol_GradientLoose") = passIsol_GradientLoose; - electron->auxdecor<char>("AnalysisTop_Isol_FixedCutTight") = passIsol_FixedCutTight; - electron->auxdecor<char>("AnalysisTop_Isol_FixedCutTightTrackOnly") = passIsol_FixedCutTightTrackOnly; - electron->auxdecor<char>("AnalysisTop_Isol_FixedCutLoose") = passIsol_FixedCutLoose; - + electron->auxdecor<char>("AnalysisTop_Isol_FCHighPtCaloOnly") = passIsol_FCHighPtCaloOnly; + electron->auxdecor<char>("AnalysisTop_Isol_HighPtCaloOnly") = passIsol_HighPtCaloOnly; + if (ptvarcone20_TightTTVA_pt1000.isAvailable(*electron)) { + AnalysisTop_Isol_FCTight(*electron) = (m_isolationTool_FCTight->accept(*electron) ? 1 : 0); + AnalysisTop_Isol_FCLoose(*electron) = (m_isolationTool_FCLoose->accept(*electron) ? 1 : 0); + } + if (ptvarcone30_TightTTVALooseCone_pt1000.isAvailable(*electron)) { + AnalysisTop_Isol_Tight(*electron) = (m_isolationTool_Tight->accept(*electron) ? 1 : 0); + AnalysisTop_Isol_Loose(*electron) = (m_isolationTool_Loose->accept(*electron) ? 1 : 0); + AnalysisTop_Isol_TightTrackOnly(*electron) = (m_isolationTool_TightTrackOnly->accept(*electron) ? 1 : 0); + if (ptcone20_TightTTVALooseCone_pt1000.isAvailable(*electron)) { + AnalysisTop_Isol_TightTrackOnly_FixedRad(*electron) = (m_isolationTool_TightTrackOnly_FixedRad->accept(*electron) ? 1 : 0); + } + } + if (ptvarcone30_TightTTVALooseCone_pt500.isAvailable(*electron) && neflowisol20.isAvailable(*electron)) { + AnalysisTop_Isol_PflowTight(*electron) = (m_isolationTool_PflowTight->accept(*electron) ? 1 : 0); + AnalysisTop_Isol_PflowLoose(*electron) = (m_isolationTool_PflowLoose->accept(*electron) ? 1 : 0); + } + // Prompt Electron Tagging (PLV): https://twiki.cern.ch/twiki/bin/view/AtlasProtected/PromptLeptonTagging + // This is not recommended, purely experimental! (no plans for electron SFs from e/gamma any time soon, unless + // strong motivation from analyses) + // The r20.7 BDT is called "Iso", the r21 one is "Veto". The cut on the BDT weight is <-0.5, with the + // FixedCutLoose WP. But this WP is no longer + // supported by e/gamma, so here let's just decorate that check, and we'll let the user access the BDT weights + // themselves if needed. + if (electron->isAvailable<float>("PromptLeptonIso")) // r20.7 + electron->auxdecor<char>("AnalysisTop_Isol_PromptLeptonIso") = + (electron->auxdata<float>("PromptLeptonIso") < -0.5) ? 1 : 0; + if (electron->isAvailable<float>("PromptLeptonVeto")) // r21 + electron->auxdecor<char>("AnalysisTop_Isol_PromptLeptonVeto") = + (electron->auxdata<float>("PromptLeptonVeto") < -0.5) ? 1 : 0; + + // New PLV: https://twiki.cern.ch/twiki/bin/view/AtlasProtected/PromptLeptonTaggerIFF + // For PLV isolation, we need to compute additional variables in the low-pT regime (<12 GeV) +//if ( PLV_TrackJetNTrack.isAvailable(*electron) && +// PLV_DRlj.isAvailable(*electron) && +// PLV_PtRel.isAvailable(*electron) && +// PLV_PtFrac.isAvailable(*electron) ) +// top::check(m_isolationTool_LowPtPLV->augmentPLV(*electron), "Failed to augment electron with LowPtPLV decorations"); +// else +// byhand_LowPtPLV(*electron) = 1.1; // decorate the electron ourselves following IFF default + if ( PLV_PromptLeptonVeto.isAvailable(*electron) && + ptvarcone30_TightTTVALooseCone_pt1000.isAvailable(*electron) ) { + AnalysisTop_Isol_PLVTight(*electron) = (m_isolationTool_PLVTight->accept(*electron) ? 1 : 0); + AnalysisTop_Isol_PLVLoose(*electron) = (m_isolationTool_PLVLoose->accept(*electron) ? 1 : 0); + } + else { + // decorate with special character to indicate failure to retrieve necessary variables + AnalysisTop_Isol_PLVTight(*electron) = 'n'; + AnalysisTop_Isol_PLVLoose(*electron) = 'n'; + } } - + ///-- set links to original objects- needed for MET calculation --/// - bool setLinks = xAOD::setOriginalObjectLink( *xaod, *shallow_xaod_copy.first ); - if (!setLinks) - ATH_MSG_ERROR(" Cannot set original object links for electrons, MET recalculation may struggle" ); - + bool setLinks = xAOD::setOriginalObjectLink(*xaod, *shallow_xaod_copy.first); + if (!setLinks) ATH_MSG_ERROR(" Cannot set original object links for electrons, MET recalculation may struggle"); + // Save corrected xAOD Container to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyElectronsStandAlone( systematic.hash() ); + std::string outputSGKey = m_config->sgKeyElectronsStandAlone(systematic.hash()); std::string outputSGKeyAux = outputSGKey + "Aux."; - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_xaod_copy.first , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_xaod_copy.second , outputSGKeyAux ); - if( !save || !saveAux ){ + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + + if (!save || !saveAux) { return StatusCode::FAILURE; } - } // Loop over all systematics - + } // Loop over all systematics + return StatusCode::SUCCESS; } - - StatusCode EgammaObjectCollectionMaker::printoutPhotons() - { - // Loop over all systematics - for( auto s : m_specifiedSystematicsPhotons ){ + + StatusCode EgammaObjectCollectionMaker::executeFwdElectrons(bool executeNominal) { + const xAOD::EventInfo* eventInfo(nullptr); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); + + ///-- Get base electrons from xAOD --/// + const xAOD::ElectronContainer* xaod(nullptr); + top::check(evtStore()->retrieve(xaod, m_config->sgKeyFwdElectrons()), "Failed to retrieve Fwd Electrons"); + + ///-- Loop over all systematics --/// + for (auto systematic : m_specifiedSystematicsFwdElectrons) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + + ///-- Tell tool which systematic to use -/// + top::check(m_calibrationTool->applySystematicVariation(systematic), "Failed to applySystematicVariation"); + + ///-- Shallow copy of the xAOD --/// + std::pair< xAOD::ElectronContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( + *xaod); + + ///-- Loop over the xAOD Container --/// + for (auto electron : *(shallow_xaod_copy.first)) { + // Apply correction to object + // should not affect derivations if there is no CC or track thinning + if (electron->caloCluster() != nullptr) { // derivations might remove CC for low pt electrons + if (calibrateFwdElectrons) { + top::check(m_calibrationTool->applyCorrection(*electron), "Failed to applyCorrection to fwd electrons"); + } + } + }//end of loop on electrons + + ///-- set links to original objects- needed for MET calculation --/// + bool setLinks = xAOD::setOriginalObjectLink(*xaod, *shallow_xaod_copy.first); + if (!setLinks) ATH_MSG_ERROR(" Cannot set original object links for fwd electrons"); + + // Save corrected xAOD Container to StoreGate / TStore + std::string outputSGKey = m_config->sgKeyFwdElectronsStandAlone(systematic.hash()); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + } // Loop over all systematics + + return StatusCode::SUCCESS; + } + + StatusCode EgammaObjectCollectionMaker::printoutPhotons() { + // Loop over all systematics + for (auto s : m_specifiedSystematicsPhotons) { const xAOD::PhotonContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyPhotons( s.hash() ) ) , "Failed to retrieve Photons" ); - - ATH_MSG_INFO(" Photons with sgKey = "<<m_config->sgKeyPhotons( s.hash() ) ); - for( auto x : *xaod ){ + top::check(evtStore()->retrieve(xaod, m_config->sgKeyPhotons(s.hash())), "Failed to retrieve Photons"); + + ATH_MSG_INFO(" Photons with sgKey = " << m_config->sgKeyPhotons(s.hash())); + for (auto x : *xaod) { float ptcone30(0.); - x->isolationValue( ptcone30 , xAOD::Iso::ptcone30 ); - ATH_MSG_INFO(" ph pT , eta , ptcone30 = "<<x->pt()<<" , "<<x->eta()<<" , "<<ptcone30 ); + x->isolationValue(ptcone30, xAOD::Iso::ptcone30); + ATH_MSG_INFO(" ph pT , eta , ptcone30 = " << x->pt() << " , " << x->eta() << " , " << ptcone30); } } - - return StatusCode::SUCCESS; - } - - - StatusCode EgammaObjectCollectionMaker::printoutElectrons() - { - // Loop over all systematics - for( auto s : m_specifiedSystematicsElectrons ){ + + return StatusCode::SUCCESS; + } + + StatusCode EgammaObjectCollectionMaker::printoutElectrons() { + // Loop over all systematics + for (auto s : m_specifiedSystematicsElectrons) { const xAOD::ElectronContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyElectronsStandAlone( s.hash() ) ), "Failed to retrieve Electrons" ); - - ATH_MSG_INFO(" Electrons with sgKey = "<<m_config->sgKeyElectronsStandAlone( s.hash() ) ); - for( auto x : *xaod ){ + top::check(evtStore()->retrieve(xaod, m_config->sgKeyElectronsStandAlone( + s.hash())), "Failed to retrieve Electrons"); + + ATH_MSG_INFO(" Electrons with sgKey = " << m_config->sgKeyElectronsStandAlone(s.hash())); + for (auto x : *xaod) { float ptcone30(0.); - x->isolationValue( ptcone30 , xAOD::Iso::ptcone30 ); - ATH_MSG_INFO(" El pT , eta , ptcone30 = "<<x->pt()<<" , "<<x->eta()<<" , "<<ptcone30 ); + x->isolationValue(ptcone30, xAOD::Iso::ptcone30); + ATH_MSG_INFO(" El pT , eta , ptcone30 = " << x->pt() << " , " << x->eta() << " , " << ptcone30); } } - - return StatusCode::SUCCESS; + + return StatusCode::SUCCESS; } - - void EgammaObjectCollectionMaker::specifiedSystematicsPhotons ( const std::set<std::string>& specifiedSystematics ) - { + + StatusCode EgammaObjectCollectionMaker::printoutFwdElectrons() { + // Loop over all systematics + for (auto s : m_specifiedSystematicsFwdElectrons) { + const xAOD::ElectronContainer* xaod(nullptr); + top::check(evtStore()->retrieve(xaod, m_config->sgKeyFwdElectronsStandAlone( + s.hash())), "Failed to retrieve Fwd Electrons"); + + ATH_MSG_INFO(" Fwd Electrons with sgKey = " << m_config->sgKeyFwdElectronsStandAlone(s.hash())); + for (auto x : *xaod) { + ATH_MSG_INFO(" El pT , eta = " << x->pt() << " , " << x->eta()); + } + } + + return StatusCode::SUCCESS; + } + + void EgammaObjectCollectionMaker::specifiedSystematicsPhotons(const std::set<std::string>& specifiedSystematics) { ///-- Get the recommended systematics from the tool, in std::vector format --/// - const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( m_calibrationTool->recommendedSystematics() ); - + const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( + m_calibrationTool->recommendedSystematics()); + for (auto s : systList) { + + if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter m_recommendedSystematicsPhotons.push_back(s); if (s.name() == "") { m_specifiedSystematicsPhotons.push_back(s); } - + ///-- MC only --/// if (m_config->isMC()) { ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// - if (!m_config->isSystNominal( m_config->systematics() )) { + if (!m_config->isSystNominal(m_config->systematics())) { if (specifiedSystematics.size() == 0) { m_specifiedSystematicsPhotons.push_back(s); } - if (specifiedSystematics.size() > 0) { + if (specifiedSystematics.size() > 0) { for (auto i : specifiedSystematics) { - if ( i == s.name() ) { - m_specifiedSystematicsPhotons.push_back(s); + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematicsPhotons.push_back(s); } } } } } - } - m_recommendedSystematicsPhotons.sort(); + } + m_recommendedSystematicsPhotons.sort(); m_recommendedSystematicsPhotons.unique(); m_specifiedSystematicsPhotons.sort(); - m_specifiedSystematicsPhotons.unique(); + m_specifiedSystematicsPhotons.unique(); } - - void EgammaObjectCollectionMaker::specifiedSystematicsElectrons( const std::set<std::string>& specifiedSystematics ) - { + + void EgammaObjectCollectionMaker::specifiedSystematicsElectrons(const std::set<std::string>& specifiedSystematics) { ///-- Get the recommended systematics from the tool, in std::vector format --/// - const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( m_calibrationTool->recommendedSystematics() ); - + const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( + m_calibrationTool->recommendedSystematics()); + for (auto s : systList) { + + if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter m_recommendedSystematicsElectrons.push_back(s); if (s.name() == "") { m_specifiedSystematicsElectrons.push_back(s); } - + ///-- MC only --/// if (m_config->isMC()) { ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// - if (!m_config->isSystNominal( m_config->systematics() )) { + if (!m_config->isSystNominal(m_config->systematics())) { if (specifiedSystematics.size() == 0) { m_specifiedSystematicsElectrons.push_back(s); } - if (specifiedSystematics.size() > 0) { + if (specifiedSystematics.size() > 0) { for (auto i : specifiedSystematics) { - if ( i == s.name() ) { - m_specifiedSystematicsElectrons.push_back(s); + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematicsElectrons.push_back(s); } } } } } - } - m_recommendedSystematicsElectrons.sort(); + } + m_recommendedSystematicsElectrons.sort(); m_recommendedSystematicsElectrons.unique(); m_specifiedSystematicsElectrons.sort(); m_specifiedSystematicsElectrons.unique(); } - + + void EgammaObjectCollectionMaker::specifiedSystematicsFwdElectrons(const std::set<std::string>& specifiedSystematics) + { + ///-- Get the recommended systematics from the tool, in std::vector format --/// + const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( + m_calibrationTool->recommendedSystematics()); + + for (auto s : systList) { + + if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter + m_recommendedSystematicsFwdElectrons.push_back(s); + if (s.name() == "") { + m_specifiedSystematicsFwdElectrons.push_back(s); + } + + ///-- MC only --/// + if (m_config->isMC()) { + ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// + if (!m_config->isSystNominal(m_config->systematics())) { + if (specifiedSystematics.size() == 0) { + m_specifiedSystematicsFwdElectrons.push_back(s); + } + if (specifiedSystematics.size() > 0) { + for (auto i : specifiedSystematics) { + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematicsFwdElectrons.push_back(s); + } + } + } + } + } + } + m_recommendedSystematicsFwdElectrons.sort(); + m_recommendedSystematicsFwdElectrons.unique(); + m_specifiedSystematicsFwdElectrons.sort(); + m_specifiedSystematicsFwdElectrons.unique(); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/ElectronInJetSubtractionCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/ElectronInJetSubtractionCollectionMaker.cxx index 00a827c1153d..4eb0fdae80ec 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/ElectronInJetSubtractionCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/ElectronInJetSubtractionCollectionMaker.cxx @@ -1,8 +1,8 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -// $Id: ElectronInJetSubtractionCollectionMaker.cxx 680332 2015-07-04 01:25:47Z morrisj $ +// $Id: ElectronInJetSubtractionCollectionMaker.cxx 806051 2017-06-07 00:32:41Z tpelzer $ #include "TopSystematicObjectMaker/ElectronInJetSubtractionCollectionMaker.h" #include "TopConfiguration/TopConfig.h" #include "TopEvent/EventTools.h" @@ -11,107 +11,107 @@ #include "xAODJet/JetAuxContainer.h" #include "xAODCore/ShallowCopy.h" -namespace top{ - - ElectronInJetSubtractionCollectionMaker::ElectronInJetSubtractionCollectionMaker( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + ElectronInJetSubtractionCollectionMaker::ElectronInJetSubtractionCollectionMaker(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), - m_doLooseCuts(false) - { - declareProperty( "config" , m_config ); + m_doLooseCuts(false) { + declareProperty("config", m_config); } - - StatusCode ElectronInJetSubtractionCollectionMaker::initialize() - { - if (!m_config->isMC()) - m_doLooseCuts = true; - - if (m_config->doOverlapRemovalOnLooseLeptonDef()) - m_doLooseCuts = true; - - if (m_config->doLooseEvents()) - m_doLooseCuts = true; - - return StatusCode::SUCCESS; + + StatusCode ElectronInJetSubtractionCollectionMaker::initialize() { + if (!m_config->isMC()) m_doLooseCuts = true; + + if (m_config->doOverlapRemovalOnLooseLeptonDef()) m_doLooseCuts = true; + + if (m_config->doLooseEvents()) m_doLooseCuts = true; + + return StatusCode::SUCCESS; } - - StatusCode ElectronInJetSubtractionCollectionMaker::execute() - { + + StatusCode ElectronInJetSubtractionCollectionMaker::execute(bool executeNominal) { // Loop over nominal, all electron syst and all jet syst // For each: - // Create a shallow electron and a shallow jet collection + // Create a shallow electron and a shallow jet collection // Run the subtraction algorithm: // - Modify some jet 4-momentum // - Veto some electrons // Place modified shallow collections into TStore - + for (auto currentSystematic : *m_config->systHashElectronInJetSubtraction()) { - + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(currentSystematic))) continue; + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(currentSystematic))) continue; + // Get the Electrons const xAOD::ElectronContainer* electrons(nullptr); - top::check(evtStore()->retrieve(electrons, m_config->sgKeyElectronsStandAlone( currentSystematic ) ) , "ElectronInJetSubtractionCollectionMaker::execute() Failed to retrieve electrons" ); - - // Get the Jets + top::check(evtStore()->retrieve(electrons, m_config->sgKeyElectronsStandAlone( + currentSystematic)), + "ElectronInJetSubtractionCollectionMaker::execute() Failed to retrieve electrons"); + + // Get the Jets const xAOD::JetContainer* jets(nullptr); - top::check(evtStore()->retrieve(jets, m_config->sgKeyJetsStandAlone( currentSystematic ) ) , "ElectronInJetSubtractionCollectionMaker::execute() Failed to retrieve jets" ); - + top::check(evtStore()->retrieve(jets, m_config->sgKeyJetsStandAlone( + currentSystematic)), + "ElectronInJetSubtractionCollectionMaker::execute() Failed to retrieve jets"); + // Shallow copy the electrons - std::pair< xAOD::ElectronContainer*, xAOD::ShallowAuxContainer* > shallow_electrons = xAOD::shallowCopyContainer( *electrons ); + std::pair< xAOD::ElectronContainer*, xAOD::ShallowAuxContainer* > shallow_electrons = xAOD::shallowCopyContainer( + *electrons); // Shallow copy the jets - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jets = xAOD::shallowCopyContainer( *jets ); - + std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jets = xAOD::shallowCopyContainer(*jets); + // Apply the Electron In Jet Subtraction // The actual calculation is performed in another package - m_subtractionAlgorithm.apply( shallow_electrons.first , shallow_jets.first ); - + m_subtractionAlgorithm.apply(shallow_electrons.first, shallow_jets.first); + // Save the modified electrons to TStore - std::string outputElectronsSGKey = m_config->sgKeyElectrons( currentSystematic ); + std::string outputElectronsSGKey = m_config->sgKeyElectrons(currentSystematic); std::string outputElectronsSGKeyAux = outputElectronsSGKey + "Aux."; - - xAOD::TReturnCode saveElectrons = evtStore()->tds()->record( shallow_electrons.first , outputElectronsSGKey ); - xAOD::TReturnCode saveElectronsAux = evtStore()->tds()->record( shallow_electrons.second , outputElectronsSGKeyAux ); - if( !saveElectrons || !saveElectronsAux ){ + + xAOD::TReturnCode saveElectrons = evtStore()->tds()->record(shallow_electrons.first, outputElectronsSGKey); + xAOD::TReturnCode saveElectronsAux = evtStore()->tds()->record(shallow_electrons.second, outputElectronsSGKeyAux); + if (!saveElectrons || !saveElectronsAux) { return StatusCode::FAILURE; - } - + } + // Save the modified jets to TStore - std::string outputJetsSGKey = m_config->sgKeyJets( currentSystematic , false ); + std::string outputJetsSGKey = m_config->sgKeyJets(currentSystematic, false); std::string outputJetsSGKeyAux = outputJetsSGKey + "Aux."; - - xAOD::TReturnCode saveJets = evtStore()->tds()->record( shallow_jets.first , outputJetsSGKey ); - xAOD::TReturnCode saveJetsAux = evtStore()->tds()->record( shallow_jets.second , outputJetsSGKeyAux ); - if( !saveJets || !saveJetsAux ){ + + xAOD::TReturnCode saveJets = evtStore()->tds()->record(shallow_jets.first, outputJetsSGKey); + xAOD::TReturnCode saveJetsAux = evtStore()->tds()->record(shallow_jets.second, outputJetsSGKeyAux); + if (!saveJets || !saveJetsAux) { return StatusCode::FAILURE; } - - + + // If we are using loose lepton definitions anywhere, we'd better make more jet colelctions // We subtract loose leptons from these jets - // We now have loose jets! fun fun fun, we all love combinatorics - + // We now have loose jets! fun fun fun, we all love combinatorics + if (m_doLooseCuts) { // Shallow copy the jets - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jetsLoose = xAOD::shallowCopyContainer( *jets ); - + std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_jetsLoose = xAOD::shallowCopyContainer( + *jets); + // Apply the Electron In Jet Subtraction // The actual calculation is performed in another package - m_subtractionAlgorithm.apply( shallow_electrons.first , shallow_jetsLoose.first , m_doLooseCuts ); + m_subtractionAlgorithm.apply(shallow_electrons.first, shallow_jetsLoose.first, m_doLooseCuts); // Save the modified jets to TStore - std::string outputJetsLooseSGKey = m_config->sgKeyJets( currentSystematic , m_doLooseCuts ); + std::string outputJetsLooseSGKey = m_config->sgKeyJets(currentSystematic, m_doLooseCuts); std::string outputJetsLooseSGKeyAux = outputJetsLooseSGKey + "Aux."; - - xAOD::TReturnCode saveJetsLoose = evtStore()->tds()->record( shallow_jetsLoose.first , outputJetsLooseSGKey ); - xAOD::TReturnCode saveJetsLooseAux = evtStore()->tds()->record( shallow_jetsLoose.second , outputJetsLooseSGKeyAux ); - if( !saveJetsLoose || !saveJetsLooseAux ){ + + xAOD::TReturnCode saveJetsLoose = evtStore()->tds()->record(shallow_jetsLoose.first, outputJetsLooseSGKey); + xAOD::TReturnCode saveJetsLooseAux = + evtStore()->tds()->record(shallow_jetsLoose.second, outputJetsLooseSGKeyAux); + if (!saveJetsLoose || !saveJetsLooseAux) { return StatusCode::FAILURE; - } + } } - - } - - return StatusCode::SUCCESS; + + return StatusCode::SUCCESS; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/GhostTrackSystematicsMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/GhostTrackSystematicsMaker.cxx index 6391f63cb8d6..91ad9e93e508 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/GhostTrackSystematicsMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/GhostTrackSystematicsMaker.cxx @@ -1,20 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Filename: GhostTrackSystematicsMaker.cxx -// Description: -// Author: Fabian Wilk -// Created: Mon Oct 24 16:59:28 2016 -// -// (c) by Fabian Wilk <mail@fabianwilk.de> -// The ATLAS Collaboration -// -// This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 -// International License. -// -// You should have received a copy of the license along with this work. -// If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ #include "TopSystematicObjectMaker/GhostTrackSystematicsMaker.h" @@ -31,6 +17,7 @@ #include "TopEvent/EventTools.h" #include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/TreeFilter.h" #include "InDetTrackSystematicsTools/InDetTrackSystematics.h" #include "InDetTrackSystematicsTools/InDetTrackSmearingTool.h" @@ -40,475 +27,552 @@ #include "InDetTrackSystematicsTools/JetTrackFilterTool.h" namespace top { - - /* explicit */ GhostTrackSystematicsMaker::GhostTrackSystematicsMaker(const std::string & name) - : ::asg::AsgTool(name), - m_config(nullptr), - m_runPeriods(), - m_specifiedSystematics(), - m_recommendedSystematics(), - m_nominalSystematicSet(), - m_tools() { - - declareProperty("config" , m_config); + /* explicit */ + GhostTrackSystematicsMaker::GhostTrackSystematicsMaker(const std::string& name) + : ::asg::AsgTool(name), + m_config(nullptr), + m_jetPtCut(0.), + m_jetEtaCut(0.), + m_runPeriods(), + m_specifiedSystematics(), + m_recommendedSystematics(), + m_nominalSystematicSet(), + m_tools() { + declareProperty("config", m_config); + } + + /* virtual */ GhostTrackSystematicsMaker::~GhostTrackSystematicsMaker() { + } + + StatusCode GhostTrackSystematicsMaker::initialize() { + ATH_MSG_INFO(" top::GhostTrackSystematicsMaker initialize"); + + ATH_MSG_WARNING("Usage of ghost tracks in AnalysisTop is purely EXPERIMENTAL!\n"); + + m_runPeriods = m_config->runPeriodsJetGhostTrack(); + + // Retrieve the systematics tools. Each individual function will cause + // program abortion upon failure. This is intended as there's no + // meaningful method of recovery. + // These tools are setup and initialised in the TopCPTools package, and we just retrieve them here. + top::check(retrieveGhostTrackCPTool(), + "Failed to retrieve the ghost track CP tools"); + + // Setup the recommended systematics. This utilises the tools that were + // setup before. + const std:: string& syststr = m_config->systematics(); + + if (m_config->isSystNominal(syststr)) { + specifiedSystematics({}); + } else if (m_config->isSystAll(syststr)) { + specifiedSystematics({"AllGhostTrack"}); + } else { + std::set<std::string> syst; + bool ok = m_config->getSystematicsList(syststr, syst); + if (!ok) { + ATH_MSG_ERROR(" top::GhostTrackSystematicsMaker could not determine systematic list"); + return StatusCode::FAILURE; + } + + // No need to manually handle the AllGhostTrack case in here. + specifiedSystematics(syst); } - /* virtual */ GhostTrackSystematicsMaker::~GhostTrackSystematicsMaker(){ + // Pass the systematics list back to the top::TopConfig object. + m_config->systematicsJetGhostTrack(specifiedSystematics()); - } - StatusCode GhostTrackSystematicsMaker::initialize(){ - ATH_MSG_INFO(" top::GhostTrackSystematicsMaker initialize" ); - - m_runPeriods = m_config->runPeriodsJetGhostTrack(); - - // Retrieve the systematics tools. Each individual function will cause - // program abortion upon failure. This is intended as there's no - // meaningful method of recovery. - // These tools are setup and initialised in the TopCPTools package, and we just retrieve them here. - top::check(retrieveGhostTrackCPTool(), - "Failed to retrieve the ghost track CP tools"); - - // Setup the recommended systematics. This utilises the tools that were - // setup before. - const std:: string & syststr = m_config->systematics(); - - if (m_config->isSystNominal(syststr)){ - specifiedSystematics({}); - } else if (m_config->isSystAll(syststr)){ - specifiedSystematics({"AllGhostTrack"}); - } else { - std::set<std::string> syst; - bool ok = m_config->getSystematicsList(syststr, syst); - if (not ok) { - ATH_MSG_ERROR(" top::GhostTrackSystematicsMaker could not determine systematic list" ); - return StatusCode::FAILURE; - } + m_jetPtCut = m_config->jetPtGhostTracks(); + m_jetEtaCut = m_config->jetEtaGhostTracks(); - // No need to manually handle the AllGhostTrack case in here. - specifiedSystematics(syst); - } + ATH_MSG_INFO( + " top::GhostTrackSystematicsMaker: Systematic variations of ghost tracks will be done only for jets with pt >= " << m_jetPtCut << " MeV and eta <= " << m_jetEtaCut << + "."); - // Pass the systematics list back to the top::TopConfig object. - m_config->systematicsJetGhostTrack(specifiedSystematics()); + ATH_MSG_INFO(" top::GhostTrackSystematicsMaker completed initialize"); + return StatusCode::SUCCESS; + } - ATH_MSG_INFO(" top::GhostTrackSystematicsMaker completed initialize" ); - return StatusCode::SUCCESS; - } + StatusCode GhostTrackSystematicsMaker::applyNoOpSystematic(xAOD::JetContainer* nominal, + const CP::SystematicSet& syst) const { + ///-- Loop over the xAOD Container --/// + + static int warningCounter=0; + const int warningLimit=20; + + for (const auto& jet : *nominal) { + if ((jet->pt() < m_jetPtCut) || (std::abs(jet->eta()) > m_jetEtaCut)) continue; + // Copy nominal ghost track container into the systematic variation. - StatusCode GhostTrackSystematicsMaker::applyNoOpSystematic(xAOD::JetContainer * nominal, - const CP::SystematicSet & syst) const { - ///-- Loop over the xAOD Container --/// - for(const auto & jet : * nominal ){ - // Copy nominal ghost track container into the systematic variation. - const auto & nominalGhostTracks = - jet->getAssociatedObjects<xAOD::IParticle>(m_config->decoKeyJetGhostTrack()); - jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), - nominalGhostTracks); - } + const auto& ghostTracks = + jet->getAssociatedObjects<xAOD::IParticle>(m_config->decoKeyJetGhostTrack()); + std::vector<const xAOD::IParticle*> newGhosts; - return StatusCode::SUCCESS; - } + for (std::size_t iGhost = 0; iGhost < ghostTracks.size(); ++iGhost) { + if (ghostTracks[iGhost] == nullptr) continue; - StatusCode GhostTrackSystematicsMaker::applyTruthFilterSystematic(xAOD::JetContainer * nominal, - InDet::InDetTrackTruthFilterTool * tool, - const CP::SystematicSet & syst) const { - ///-- Inform the tool --/// - top::check(tool->applySystematicVariation(syst), - "Failed to configure tool for systematic variation"); - - ///-- Loop over the xAOD Container --/// - for(const auto & jet : * nominal ){ - const auto & ghostTracks = - jet->getAssociatedObjects<xAOD::IParticle>(m_config->decoKeyJetGhostTrack()); - std::vector<const xAOD::IParticle *> newGhosts; - - for (std::size_t iGhost=0; iGhost<ghostTracks.size(); ++iGhost){ - const xAOD::TrackParticle * - tp{dynamic_cast<const xAOD::TrackParticle*>(ghostTracks[iGhost])}; - top::check(tp, "Failed to convert xAOD::IParticle to xAOD::TrackParticle for ghost track"); - - if (not tool->accept(tp)){ - continue; - } - - // We can re-use the existing xAOD::IParticle. - newGhosts.push_back(ghostTracks[iGhost]); - } + // We can re-use the existing xAOD::IParticle. + newGhosts.push_back(ghostTracks[iGhost]); + } - jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), newGhosts); - } + if (newGhosts.size() == 0 && warningCounter<warningLimit) { + ATH_MSG_WARNING( + "in GhostTrackSystematicsMaker: All ghost tracks are null pointers. There may be something wrong with your configuration or derivation. Jet pt: " << jet->pt() << " Jet eta: " << + jet->eta()); + warningCounter++; + } - return StatusCode::SUCCESS; + jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), + newGhosts); } - StatusCode GhostTrackSystematicsMaker::applyJetTrackFilterSystematic(xAOD::JetContainer * nominal, - InDet::JetTrackFilterTool * tool, - const CP::SystematicSet & syst) const { - ///-- Inform the tool --/// - top::check(tool->applySystematicVariation(syst), - "Failed to configure tool for systematic variation"); - - ///-- Loop over the xAOD Container --/// - for(const auto & jet : * nominal ){ - const auto & ghostTracks = jet->getAssociatedObjects<xAOD::IParticle>(m_config->decoKeyJetGhostTrack()); - std::vector<const xAOD::IParticle *> newGhosts; - - for (std::size_t iGhost=0; iGhost<ghostTracks.size(); ++iGhost){ - const xAOD::TrackParticle * - tp{dynamic_cast<const xAOD::TrackParticle*>(ghostTracks[iGhost])}; - top::check(tp, "Failed to convert xAOD::IParticle to xAOD::TrackParticle for ghost track"); - - if (not tool->accept(tp, nominal)){ - continue; - } - - // We can re-use the existing xAOD::IParticle. - newGhosts.push_back(ghostTracks[iGhost]); - } - - jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), newGhosts); + return StatusCode::SUCCESS; + } + + StatusCode GhostTrackSystematicsMaker::applyTruthFilterSystematic(xAOD::JetContainer* nominal, + InDet::InDetTrackTruthFilterTool* tool, + const CP::SystematicSet& syst) const { + ///-- Inform the tool --/// + top::check(tool->applySystematicVariation(syst), + "Failed to configure tool for systematic variation"); + + ///-- Loop over the xAOD Container --/// + for (const auto& jet : *nominal) { + if ((jet->pt() < m_jetPtCut) || (std::abs(jet->eta()) > m_jetEtaCut)) continue; + const auto& ghostTracks = + jet->getAssociatedObjects<xAOD::IParticle>(m_config->decoKeyJetGhostTrack()); + std::vector<const xAOD::IParticle*> newGhosts; + + for (std::size_t iGhost = 0; iGhost < ghostTracks.size(); ++iGhost) { + if (ghostTracks[iGhost] == nullptr) continue; + const xAOD::TrackParticle* + tp { + dynamic_cast<const xAOD::TrackParticle*>(ghostTracks[iGhost]) + }; + top::check(tp, "Failed to convert xAOD::IParticle to xAOD::TrackParticle for ghost track"); + + if (!tool->accept(tp)) { + continue; } - return StatusCode::SUCCESS; - } - - StatusCode GhostTrackSystematicsMaker::applySmearingSystematic(xAOD::JetContainer * nominal, - InDet::InDetTrackSmearingTool * tool, - const CP::SystematicSet & syst) const { - ///-- Inform the tool --/// - top::check(tool->applySystematicVariation(syst), - "Failed to configure tool for systematic variation"); - - const std::string sgKey{m_config->decoKeyJetGhostTrack() + - "_Particles_" + syst.name()}; - const std::string sgKeyAux{sgKey + "Aux."}; - - - ///-- Loop over the xAOD Container --/// - xAOD::TrackParticleContainer * newTrackParticles = new xAOD::TrackParticleContainer; - top::check(evtStore()->record(newTrackParticles, sgKey), - "Failed to record systematically varied track particle container" ); - xAOD::TrackParticleAuxContainer * newTrackParticlesAux = new xAOD::TrackParticleAuxContainer; - top::check(evtStore()->record(newTrackParticlesAux, sgKeyAux), - "Failed to record systematically varied track particle container" ); - newTrackParticles->setStore(newTrackParticlesAux); - - for (const auto & jet : * nominal){ - const auto & ghostTracks = jet->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack()); + // We can re-use the existing xAOD::IParticle. + newGhosts.push_back(ghostTracks[iGhost]); + } - std::vector<const xAOD::IParticle *> newGhosts; - - for (std::size_t iGhost=0; iGhost<ghostTracks.size(); ++iGhost){ - const xAOD::TrackParticle * - tp{dynamic_cast<const xAOD::TrackParticle*>(ghostTracks.at(iGhost))}; - top::check(tp, "Failed to convert xAOD::IParticle to xAOD::TrackParticle for ghost track"); - - xAOD::TrackParticle * newTp{nullptr}; - top::check(tool->correctedCopy(* tp, newTp), - "Failure to apply ghost track systematic"); - top::check(newTp, "Systematically varied xAOD::TrackParticle is nullptr"); - - newTrackParticles->push_back(newTp); - newGhosts.push_back(newTp); - } - - jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), newGhosts); - } - - return StatusCode::SUCCESS; + jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), newGhosts); } - StatusCode GhostTrackSystematicsMaker::applyBiasingSystematic(xAOD::JetContainer * nominal, - InDet::InDetTrackBiasingTool * tool, - const CP::SystematicSet & syst) const { - ///-- Inform the tool --/// - top::check(tool->applySystematicVariation(syst), - "Failed to configure tool for systematic variation"); + return StatusCode::SUCCESS; + } + + StatusCode GhostTrackSystematicsMaker::applyJetTrackFilterSystematic(xAOD::JetContainer* nominal, + InDet::JetTrackFilterTool* tool, + const CP::SystematicSet& syst) const { + ///-- Inform the tool --/// + top::check(tool->applySystematicVariation(syst), + "Failed to configure tool for systematic variation"); + + ///-- Loop over the xAOD Container --/// + for (const auto& jet : *nominal) { + if ((jet->pt() < m_jetPtCut) || (std::abs(jet->eta()) > m_jetEtaCut)) continue; + const auto& ghostTracks = jet->getAssociatedObjects<xAOD::IParticle>(m_config->decoKeyJetGhostTrack()); + std::vector<const xAOD::IParticle*> newGhosts; + + + for (std::size_t iGhost = 0; iGhost < ghostTracks.size(); ++iGhost) { + if (ghostTracks[iGhost] == nullptr) continue; + const xAOD::TrackParticle* + tp { + dynamic_cast<const xAOD::TrackParticle*>(ghostTracks[iGhost]) + }; + top::check(tp, "Failed to convert xAOD::IParticle to xAOD::TrackParticle for ghost track"); + + if (!tool->accept(tp, nominal)) { + continue; + } - const std::string sgKey{m_config->decoKeyJetGhostTrack() + - "_Particles_" + syst.name()}; - const std::string sgKeyAux{sgKey + "Aux."}; + // We can re-use the existing xAOD::IParticle. + newGhosts.push_back(ghostTracks[iGhost]); + } + jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), newGhosts); + } - ///-- Loop over the xAOD Container --/// - xAOD::TrackParticleContainer * newTrackParticles = new xAOD::TrackParticleContainer; - top::check(evtStore()->record(newTrackParticles, sgKey), - "Failed to record systematically varied track particle container" ); - xAOD::TrackParticleAuxContainer * newTrackParticlesAux = new xAOD::TrackParticleAuxContainer; - top::check(evtStore()->record(newTrackParticlesAux, sgKeyAux), - "Failed to record systematically varied track particle container" ); - newTrackParticles->setStore(newTrackParticlesAux); + return StatusCode::SUCCESS; + } + + StatusCode GhostTrackSystematicsMaker::applySmearingSystematic(xAOD::JetContainer* nominal, + InDet::InDetTrackSmearingTool* tool, + const CP::SystematicSet& syst) const { + ///-- Inform the tool --/// + top::check(tool->applySystematicVariation(syst), + "Failed to configure tool for systematic variation"); + + const std::string sgKey { + m_config->decoKeyJetGhostTrack() + + "_Particles_" + syst.name() + }; + const std::string sgKeyAux { + sgKey + "Aux." + }; + + + ///-- Loop over the xAOD Container --/// + xAOD::TrackParticleContainer* newTrackParticles = new xAOD::TrackParticleContainer; + top::check(evtStore()->record(newTrackParticles, sgKey), + "Failed to record systematically varied track particle container"); + xAOD::TrackParticleAuxContainer* newTrackParticlesAux = new xAOD::TrackParticleAuxContainer; + top::check(evtStore()->record(newTrackParticlesAux, sgKeyAux), + "Failed to record systematically varied track particle container"); + newTrackParticles->setStore(newTrackParticlesAux); + + for (const auto& jet : *nominal) { + if ((jet->pt() < m_jetPtCut) || (std::abs(jet->eta()) > m_jetEtaCut)) continue; + const auto& ghostTracks = jet->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack()); + + std::vector<const xAOD::IParticle*> newGhosts; + + for (std::size_t iGhost = 0; iGhost < ghostTracks.size(); ++iGhost) { + if (ghostTracks[iGhost] == nullptr) continue; + + const xAOD::TrackParticle* + tp { + dynamic_cast<const xAOD::TrackParticle*>(ghostTracks.at(iGhost)) + }; + top::check(tp, "Failed to convert xAOD::IParticle to xAOD::TrackParticle for ghost track"); + + xAOD::TrackParticle* newTp { + nullptr + }; + top::check(tool->correctedCopy(*tp, newTp), + "Failure to apply ghost track systematic"); + top::check(newTp, "Systematically varied xAOD::TrackParticle is nullptr"); + + newTrackParticles->push_back(newTp); + newGhosts.push_back(newTp); + } + + jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), newGhosts); + } - for (const auto & jet : * nominal){ - const auto & ghostTracks = jet->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack()); + return StatusCode::SUCCESS; + } + + StatusCode GhostTrackSystematicsMaker::applyBiasingSystematic(xAOD::JetContainer* nominal, + InDet::InDetTrackBiasingTool* tool, + const CP::SystematicSet& syst) const { + ///-- Inform the tool --/// + top::check(tool->applySystematicVariation(syst), + "Failed to configure tool for systematic variation"); + + const std::string sgKey { + m_config->decoKeyJetGhostTrack() + + "_Particles_" + syst.name() + }; + const std::string sgKeyAux { + sgKey + "Aux." + }; + + + ///-- Loop over the xAOD Container --/// + xAOD::TrackParticleContainer* newTrackParticles = new xAOD::TrackParticleContainer; + top::check(evtStore()->record(newTrackParticles, sgKey), + "Failed to record systematically varied track particle container"); + xAOD::TrackParticleAuxContainer* newTrackParticlesAux = new xAOD::TrackParticleAuxContainer; + top::check(evtStore()->record(newTrackParticlesAux, sgKeyAux), + "Failed to record systematically varied track particle container"); + newTrackParticles->setStore(newTrackParticlesAux); + + for (const auto& jet : *nominal) { + if ((jet->pt() < m_jetPtCut) || (std::abs(jet->eta()) > m_jetEtaCut)) continue; + const auto& ghostTracks = jet->getAssociatedObjects<xAOD::TrackParticle>(m_config->decoKeyJetGhostTrack()); + + std::vector<const xAOD::IParticle*> newGhosts; + + for (std::size_t iGhost = 0; iGhost < ghostTracks.size(); ++iGhost) { + if (ghostTracks[iGhost] == nullptr) continue; + + const xAOD::TrackParticle* + tp { + dynamic_cast<const xAOD::TrackParticle*>(ghostTracks.at(iGhost)) + }; + top::check(tp, "Failed to convert xAOD::IParticle to xAOD::TrackParticle for ghost track"); + + xAOD::TrackParticle* newTp { + nullptr + }; + top::check(tool->correctedCopy(*tp, newTp), + "Failure to apply ghost track systematic"); + top::check(newTp, "Systematically varied xAOD::TrackParticle is nullptr"); + + newTrackParticles->push_back(newTp); + newGhosts.push_back(newTp); + } + + jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), newGhosts); + } - std::vector<const xAOD::IParticle *> newGhosts; + return StatusCode::SUCCESS; + } - for (std::size_t iGhost=0; iGhost<ghostTracks.size(); ++iGhost){ - const xAOD::TrackParticle * - tp{dynamic_cast<const xAOD::TrackParticle*>(ghostTracks.at(iGhost))}; - top::check(tp, "Failed to convert xAOD::IParticle to xAOD::TrackParticle for ghost track"); + StatusCode GhostTrackSystematicsMaker::execute(bool executeNominal) { + ATH_MSG_DEBUG(" top::GhostTrackSystematicsMaker execute:"); - xAOD::TrackParticle * newTp{nullptr}; - top::check(tool->correctedCopy(* tp, newTp), - "Failure to apply ghost track systematic"); - top::check(newTp, "Systematically varied xAOD::TrackParticle is nullptr"); - newTrackParticles->push_back(newTp); - newGhosts.push_back(newTp); - } + ///-- Get nominal jets --/// + xAOD::JetContainer* nominalJets(nullptr); + top::check(evtStore()->retrieve(nominalJets, + m_config->sgKeyJetsStandAlone(m_nominalSystematicSet.hash())), + "Failed to retrieve Jets"); - jet->setAssociatedObjects(m_config->decoKeyJetGhostTrack(syst.hash()), newGhosts); - } + // applyNoOpSystematic is used just to remove ghost track vector from thinned jets + top::check(applyNoOpSystematic(nominalJets, m_nominalSystematicSet), + "Failure to apply GhostTrackSystematic"); - return StatusCode::SUCCESS; + // We don't want to do anything on Data -> bail early so that we can + // rely on the inputs to be MC. + if (!m_config->isMC()) { + return StatusCode::SUCCESS; } - StatusCode GhostTrackSystematicsMaker::execute(){ - ATH_MSG_DEBUG(" top::GhostTrackSystematicsMaker execute:" ); + ///-- Only run this on the systematic execution --/// + if (executeNominal) return StatusCode::SUCCESS; - // We don't want to do anything on Data -> bail early so that we can - // rely on the inputs to be MC. - if (not m_config->isMC()){ - return StatusCode::SUCCESS; - } - - ///-- Get nominal jets --/// - xAOD::JetContainer * nominalJets(nullptr); - top::check(evtStore()->retrieve(nominalJets, - m_config->sgKeyJetsStandAlone(m_nominalSystematicSet.hash())), - "Failed to retrieve Jets"); + ///-- SMEARING --/// + for (const auto& syst : m_systs.smearing) { + top::check(applySmearingSystematic(nominalJets, &(*m_tools.smearing), syst), + "Failure to apply GhostTrackSystematic"); + } - ///-- SMEARING --/// - for (const auto & syst : m_systs.smearing){ - // std::cout << "[A] SYSTEMATIC = " << m_config->systematicName(syst.hash()) << std::endl; - top::check(applySmearingSystematic(nominalJets, &(* m_tools.smearing), syst), - "Failure to apply GhostTrackSystematic"); - } - - ///-- BIASING --/// - InDet::InDetTrackBiasingTool * biasingTool{nullptr}; - if (m_runPeriods.size() == 1){ - biasingTool = &(* m_tools.bias[0]); - - top::check(biasingTool, "Failure to selected biasing tool"); - for (const auto & syst : m_systs.bias){ - // std::cout << "[B] SYSTEMATIC = " << m_config->systematicName(syst.hash()) << std::endl; - top::check(applyBiasingSystematic(nominalJets, biasingTool, syst), - "Failure to apply GhostTrackSystematic"); - } - } else { - const xAOD::EventInfo * ei{nullptr}; - top::check(evtStore()->retrieve(ei, "EventInfo"), - "Failure to retrieve EventInfo"); - - top::check(ei->isAvailable<unsigned int>("RandomRunNumber"), - "Require that RandomRunNumber decoration is available."); - auto randomRunNumber = ei->auxdataConst<unsigned int>("RandomRunNumber"); - - if (randomRunNumber == 0){ - for (const auto & syst : m_systs.bias){ - // std::cout << "[B.1] SYSTEMATIC = " << m_config->systematicName(syst.hash()) << std::endl; - top::check(applyNoOpSystematic(nominalJets, syst), - "Failure to apply GhostTrackSystematic"); - } - } else { - top::check(m_runPeriods[0] <= randomRunNumber, - "RandomRunNumber is below valid range."); - top::check(randomRunNumber < m_runPeriods[m_runPeriods.size() - 1], - "RandomRunNumber is above valid range."); - - for (std::size_t i=1; i<m_runPeriods.size(); ++i){ - if (randomRunNumber < m_runPeriods[i]){ - biasingTool = &(* m_tools.bias[i - 1]); - break; - } - } - top::check(biasingTool, "Failure to selected biasing tool"); - for (const auto & syst : m_systs.bias){ - // std::cout << "[B.2] SYSTEMATIC = " << m_config->systematicName(syst.hash()) << std::endl; - top::check(applyBiasingSystematic(nominalJets, biasingTool, syst), - "Failure to apply GhostTrackSystematic"); - } - } + ///-- BIASING --/// + InDet::InDetTrackBiasingTool* biasingTool { + nullptr + }; + if (m_runPeriods.size() == 1) { + biasingTool = &(*m_tools.bias[0]); + + top::check(biasingTool, "Failure to selected biasing tool"); + for (const auto& syst : m_systs.bias) { + top::check(applyBiasingSystematic(nominalJets, biasingTool, syst), + "Failure to apply GhostTrackSystematic"); + } + } else { + const xAOD::EventInfo* ei { + nullptr + }; + top::check(evtStore()->retrieve(ei, "EventInfo"), + "Failure to retrieve EventInfo"); + + top::check(ei->isAvailable<unsigned int>("RandomRunNumber"), + "Require that RandomRunNumber decoration is available."); + auto randomRunNumber = ei->auxdataConst<unsigned int>("RandomRunNumber"); + + if (randomRunNumber == 0) { + for (const auto& syst : m_systs.bias) { + top::check(applyNoOpSystematic(nominalJets, syst), + "Failure to apply GhostTrackSystematic"); } - - ///-- TRUTH FILTER --/// - for (const auto & syst : m_systs.truthFilter){ - // std::cout << "[C] SYSTEMATIC = " << m_config->systematicName(syst.hash()) << std::endl; - top::check(applyTruthFilterSystematic(nominalJets, &(* m_tools.truthFilter), syst), - "Failure to apply GhostTrackSystematic"); + } else { + top::check(m_runPeriods[0] <= randomRunNumber, + "RandomRunNumber is below valid range."); + top::check(randomRunNumber < m_runPeriods[m_runPeriods.size() - 1], + "RandomRunNumber is above valid range."); + + for (std::size_t i = 1; i < m_runPeriods.size(); ++i) { + if (randomRunNumber < m_runPeriods[i]) { + biasingTool = &(*m_tools.bias[i - 1]); + break; + } } - - ///-- JET TRACK FILTER --/// - for (const auto & syst : m_systs.jetTrackFilter){ - // std::cout << "[D] SYSTEMATIC = " << m_config->systematicName(syst.hash()) << std::endl; - top::check(applyJetTrackFilterSystematic(nominalJets, &(* m_tools.jetTrackFilter), syst), - "Failure to apply GhostTrackSystematic"); + top::check(biasingTool, "Failure to selected biasing tool"); + for (const auto& syst : m_systs.bias) { + top::check(applyBiasingSystematic(nominalJets, biasingTool, syst), + "Failure to apply GhostTrackSystematic"); } + } + } - ATH_MSG_DEBUG(" top::GhostTrackSystematicsMaker completed execute" ); - return StatusCode::SUCCESS; + ///-- TRUTH FILTER --/// + for (const auto& syst : m_systs.truthFilter) { + top::check(applyTruthFilterSystematic(nominalJets, &(*m_tools.truthFilter), syst), + "Failure to apply GhostTrackSystematic"); } + ///-- JET TRACK FILTER --/// + for (const auto& syst : m_systs.jetTrackFilter) { + top::check(applyJetTrackFilterSystematic(nominalJets, &(*m_tools.jetTrackFilter), syst), + "Failure to apply GhostTrackSystematic"); + } - void GhostTrackSystematicsMaker::specifiedSystematics(const std::set<std::string> & specifiedSystematics) { - // NOTE: For this function -- unlike the "proper" ObjectCollectionMakers in AnalysisTop -- an empty specifiedSystematics input is considered to represent "No Systematics". All GhostTrack systematics can be requested with the string "AllGhostTrack". - const bool allGhostTrackSystematics = m_config->contains(specifiedSystematics, - "AllGhostTrack"); - - // Acquire the recommended systematics from the various tools and put - // into containers that store the per-tool systematics as well as a - // global container. At a later point we'll make the per-tool containers - // unique and check that the containers for various tools are - // orthogonal. - std::set<CP::SystematicSet> systs; - - // SMEARING - m_systs.smearing = - CP::make_systematics_vector(m_tools.smearing->recommendedSystematics()); - systs.insert(m_systs.smearing.begin(), m_systs.smearing.end()); - - // BIAS - for (const auto & tool : m_tools.bias){ - m_systs.bias = - CP::make_systematics_vector(tool->recommendedSystematics()); - systs.insert(m_systs.bias.begin(), m_systs.bias.end()); - } + ATH_MSG_DEBUG(" top::GhostTrackSystematicsMaker completed execute"); + return StatusCode::SUCCESS; + } + + void GhostTrackSystematicsMaker::specifiedSystematics(const std::set<std::string>& specSys) { + // NOTE: For this function -- unlike the "proper" ObjectCollectionMakers in AnalysisTop -- an empty + // specifiedSystematics input is considered to represent "No Systematics". All GhostTrack systematics can be + // requested with the string "AllGhostTrack". + const bool allGhostTrackSystematics = m_config->contains(specSys, + "AllGhostTrack"); + + // Acquire the recommended systematics from the various tools and put + // into containers that store the per-tool systematics as well as a + // global container. At a later point we'll make the per-tool containers + // unique and check that the containers for various tools are + // orthogonal. + std::set<CP::SystematicSet> systs; + + // SMEARING + m_systs.smearing = + CP::make_systematics_vector(m_tools.smearing->recommendedSystematics()); + systs.insert(m_systs.smearing.begin(), m_systs.smearing.end()); + + // BIAS + for (const auto& tool : m_tools.bias) { + m_systs.bias = + CP::make_systematics_vector(tool->recommendedSystematics()); + systs.insert(m_systs.bias.begin(), m_systs.bias.end()); + } - // TRUTH FILTER - m_systs.truthFilter = - CP::make_systematics_vector(m_tools.truthFilter->recommendedSystematics()); - systs.insert(m_systs.truthFilter.begin(), m_systs.truthFilter.end()); - - // JET TRACK FILTER - m_systs.jetTrackFilter = - CP::make_systematics_vector(m_tools.jetTrackFilter->recommendedSystematics()); - systs.insert(m_systs.jetTrackFilter.begin(), m_systs.jetTrackFilter.end()); - - // PUT INTO RECOMMENDED AND SPECIFIED - for (const auto & s : systs){ - // We don't want nominal. - if (s.name() == ""){ - continue; - } + // TRUTH FILTER + m_systs.truthFilter = + CP::make_systematics_vector(m_tools.truthFilter->recommendedSystematics()); + systs.insert(m_systs.truthFilter.begin(), m_systs.truthFilter.end()); + + // JET TRACK FILTER + m_systs.jetTrackFilter = + CP::make_systematics_vector(m_tools.jetTrackFilter->recommendedSystematics()); + systs.insert(m_systs.jetTrackFilter.begin(), m_systs.jetTrackFilter.end()); + + // PUT INTO RECOMMENDED AND SPECIFIED + for (const auto& s : systs) { + // We don't want nominal. + if (s.name() == "") { + continue; + } + + if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter + m_recommendedSystematics.push_back(s); + + ///-- MC only --/// + if (m_config->isMC()) { + ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// + if (!m_config->isSystNominal(m_config->systematics())) { + if (allGhostTrackSystematics) { + m_specifiedSystematics.push_back(s); + continue; + } - m_recommendedSystematics.push_back(s); - - ///-- MC only --/// - if (m_config->isMC()) { - ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// - if (not m_config->isSystNominal(m_config->systematics())) { - if (allGhostTrackSystematics) { - m_specifiedSystematics.push_back(s); - continue; - } - - for (const auto & i : specifiedSystematics) { - if (i == s.name()) { - m_specifiedSystematics.push_back(s); - } - } - } + for (const auto& i : specSys) { + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematics.push_back(s); } + } } + } + } - m_recommendedSystematics.sort(); - m_recommendedSystematics.unique(); + m_recommendedSystematics.sort(); + m_recommendedSystematics.unique(); + + m_specifiedSystematics.sort(); + m_specifiedSystematics.unique(); + + // Make the sublists unique and remove any elements that have not "been specified". + m_systs.makeUnique(); + m_systs.removeNonSpecified(m_specifiedSystematics); + + // Lastly, let use introduce a safeguard which ensures that the + // systematics selected for the various tools are orthogonal. This is + // done by asserting that the sum of the sizes of the individual + // systematics lists equals the size of the list of specified + // systematics. We can do this because we've made the individual + // per-tool containers unique (in makeUnique). + top::check(m_systs.numSystematics() == m_specifiedSystematics.size(), + "Sanity check failed"); + } + + StatusCode GhostTrackSystematicsMaker::retrieveGhostTrackCPTool() { + ATH_MSG_INFO(" Retrieving ghost track CPTools"); + + std::string smearingToolName { + "top::GhostTrackCPTools::InDetTrackSmearingTool" + }; + if (asg::ToolStore::contains<InDet::InDetTrackSmearingTool>(smearingToolName)) { + m_tools.smearing = + asg::ToolStore::get<InDet::InDetTrackSmearingTool>(smearingToolName); + } else { + ATH_MSG_ERROR(" Impossible to retrieve " + smearingToolName); + return StatusCode::FAILURE; + } - m_specifiedSystematics.sort(); - m_specifiedSystematics.unique(); + std::string biasToolPrefix { + "top::GhostTrackCPTools::InDetTrackBiasingTool" + }; + top::check(!m_runPeriods.empty(), "Assertion failed"); + // Two cases are possible: + // - Either a single run number was specified to the runPeriods + // parameter in which case we'll use exactly that run number, or + // - at least two numbers have been specified, which then define + // (potentially multiple) run number ranges. + unsigned int end = 0; + if (m_runPeriods.size() == 1) { + end = 1; + m_tools.bias.resize(1); + } else { + end = m_runPeriods.size() - 1; + m_tools.bias.resize(m_runPeriods.size() - 1); + } + for (unsigned int i = 0; i < end; i++) { + std::string biasToolName { + "" + }; + if (m_runPeriods.size() == 1) { + biasToolName = biasToolPrefix + "_" + std::to_string(m_runPeriods[0]); + } else { + biasToolName = biasToolPrefix + "_" + std::to_string(m_runPeriods[i]) + "_" + + std::to_string(m_runPeriods[i + 1]); + } + if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)) { + m_tools.bias[i] = asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); + } else { + ATH_MSG_ERROR(" Impossible to retrieve " + biasToolName); + return StatusCode::FAILURE; + } + } - // Make the sublists unique and remove any elements that have not "been specified". - m_systs.makeUnique(); - m_systs.removeNonSpecified(m_specifiedSystematics); + std::string truthOriginToolName { + "top::GhostTrackCPTools::InDetTrackTruthOriginTool" + }; + if (asg::ToolStore::contains<InDet::InDetTrackTruthOriginTool>(truthOriginToolName)) { + m_tools.truthOrigin = asg::ToolStore::get<InDet::InDetTrackTruthOriginTool>(truthOriginToolName); + } else { + ATH_MSG_ERROR(" Impossible to retrieve " + truthOriginToolName); + return StatusCode::FAILURE; + } - // Lastly, let use introduce a safeguard which ensures that the - // systematics selected for the various tools are orthogonal. This is - // done by asserting that the sum of the sizes of the individual - // systematics lists equals the size of the list of specified - // systematics. We can do this because we've made the individual - // per-tool containers unique (in makeUnique). - top::check(m_systs.numSystematics() == m_specifiedSystematics.size(), - "Sanity check failed"); + std::string truthFilterToolName { + "top::GhostTrackCPTools::InDetTrackTruthFilterTool" + }; + if (asg::ToolStore::contains<InDet::InDetTrackTruthFilterTool>(truthFilterToolName)) { + m_tools.truthFilter = asg::ToolStore::get<InDet::InDetTrackTruthFilterTool>(truthFilterToolName); + } else { + ATH_MSG_ERROR(" Impossible to retrieve " + truthFilterToolName); + return StatusCode::FAILURE; } - StatusCode GhostTrackSystematicsMaker::retrieveGhostTrackCPTool(){ - ATH_MSG_INFO(" Retrieving ghost track CPTools" ); - - std::string smearingToolName{"top::GhostTrackCPTools::InDetTrackSmearingTool"}; - if (asg::ToolStore::contains<InDet::InDetTrackSmearingTool>(smearingToolName)) { - m_tools.smearing = - asg::ToolStore::get<InDet::InDetTrackSmearingTool>(smearingToolName); - } - else { - ATH_MSG_ERROR(" Impossible to retrieve " + smearingToolName ); - return StatusCode::FAILURE; - } - - std::string biasToolPrefix{"top::GhostTrackCPTools::InDetTrackBiasingTool"}; - top::check(not m_runPeriods.empty(), "Assertion failed"); - // Two cases are possible: - // - Either a single run number was specified to the runPeriods - // parameter in which case we'll use exactly that run number, or - // - at least two numbers have been specified, which then define - // (potentially multiple) run number ranges. - unsigned int end = 0; - if (m_runPeriods.size() == 1) { - end = 1; - m_tools.bias.resize(1); - } - else { - end = m_runPeriods.size()-1; - m_tools.bias.resize(m_runPeriods.size()-1); - } - for (unsigned int i = 0; i<end; i++) { - std::string biasToolName{""}; - if (m_runPeriods.size() == 1) { - biasToolName = biasToolPrefix + "_" + std::to_string(m_runPeriods[0]); - } - else { - biasToolName = biasToolPrefix + "_" + std::to_string(m_runPeriods[i]) + "_" + std::to_string(m_runPeriods[i + 1]); - } - if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)){ - m_tools.bias[i] = asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); - } - else { - ATH_MSG_ERROR(" Impossible to retrieve " + biasToolName ); - return StatusCode::FAILURE; - } - } - - std::string truthOriginToolName{"top::GhostTrackCPTools::InDetTrackTruthOriginTool"}; - if (asg::ToolStore::contains<InDet::InDetTrackTruthOriginTool>(truthOriginToolName)){ - m_tools.truthOrigin = asg::ToolStore::get<InDet::InDetTrackTruthOriginTool>(truthOriginToolName); - } - else { - ATH_MSG_ERROR(" Impossible to retrieve " + truthOriginToolName ); - return StatusCode::FAILURE; - } - - std::string truthFilterToolName{"top::GhostTrackCPTools::InDetTrackTruthFilterTool"}; - if (asg::ToolStore::contains<InDet::InDetTrackTruthFilterTool>(truthFilterToolName)){ - m_tools.truthFilter = asg::ToolStore::get<InDet::InDetTrackTruthFilterTool>(truthFilterToolName); - } - else { - ATH_MSG_ERROR(" Impossible to retrieve " + truthFilterToolName ); - return StatusCode::FAILURE; - } - - std::string jetTrackFilterToolName{"top::GhostTrackCPTools::JetTrackFilterTool"}; - if (asg::ToolStore::contains<InDet::JetTrackFilterTool>(jetTrackFilterToolName)){ - m_tools.jetTrackFilter = asg::ToolStore::get<InDet::JetTrackFilterTool>(jetTrackFilterToolName); - } - else { - ATH_MSG_ERROR(" Impossible to retrieve " + jetTrackFilterToolName ); - return StatusCode::FAILURE; - } - - return StatusCode::SUCCESS; + std::string jetTrackFilterToolName { + "top::GhostTrackCPTools::JetTrackFilterTool" + }; + if (asg::ToolStore::contains<InDet::JetTrackFilterTool>(jetTrackFilterToolName)) { + m_tools.jetTrackFilter = asg::ToolStore::get<InDet::JetTrackFilterTool>(jetTrackFilterToolName); + } else { + ATH_MSG_ERROR(" Impossible to retrieve " + jetTrackFilterToolName); + return StatusCode::FAILURE; } + return StatusCode::SUCCESS; + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/JetObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/JetObjectCollectionMaker.cxx index 7c1bdf02d213..7edf05738daa 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/JetObjectCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/JetObjectCollectionMaker.cxx @@ -1,10 +1,11 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ -// $Id: JetObjectCollectionMaker.cxx 802997 2017-04-17 01:24:36Z tpelzer $ +// $Id: JetObjectCollectionMaker.cxx 809674 2017-08-23 14:10:24Z iconnell $ #include "TopSystematicObjectMaker/JetObjectCollectionMaker.h" #include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/TreeFilter.h" #include "TopEvent/EventTools.h" #include "xAODJet/JetContainer.h" @@ -19,722 +20,879 @@ #include "TopJetSubstructure/LargeJetTrimmer.h" #include "TopJetSubstructure/SubjetMaker.h" -namespace top{ - -JetObjectCollectionMaker::JetObjectCollectionMaker( const std::string& name ) : - asg::AsgTool( name ), - m_config(nullptr), - m_doJER(false), - m_doFull_JER(false), - - m_specifiedSystematics(), - m_specifiedSystematicsLargeR(), - m_specifiedSystematicsTrackJets(), - m_recommendedSystematics(), - m_nominalSystematicSet(), - - m_jetCalibrationTool("JetCalibrationTool"), - m_jetCalibrationToolLargeR("JetCalibrationToolLargeR"), - - m_jetUncertaintiesTool("JetUncertaintiesTool"), - m_jetUncertaintiesToolReducedNPScenario1("JetUncertaintiesToolReducedNPScenario1"), - m_jetUncertaintiesToolReducedNPScenario2("JetUncertaintiesToolReducedNPScenario2"), - m_jetUncertaintiesToolReducedNPScenario3("JetUncertaintiesToolReducedNPScenario3"), - m_jetUncertaintiesToolReducedNPScenario4("JetUncertaintiesToolReducedNPScenario4"), - - m_jetUncertaintiesToolLargeR_strong("JetUncertaintiesToolLargeR_Strong"), - m_jetUncertaintiesToolLargeR_medium("JetUncertaintiesToolLargeR_Medium"), - m_jetUncertaintiesToolLargeR_weak("JetUncertaintiesToolLargeR_Weak"), - - m_jetJERSmearingTool("JetJERSmearingTool"), - m_jetUpdateJvtTool("JetUpdateJvtTool"), - m_fjvtTool("fJVTTool"), - - m_jetSubstructure(nullptr), - - m_systMap_AllNP(), - m_systMap_ReducedNPScenario1(), - m_systMap_ReducedNPScenario2(), - m_systMap_ReducedNPScenario3(), - m_systMap_ReducedNPScenario4(), - m_systMap_LargeR_strong(), - m_systMap_JER() -{ - declareProperty( "config" , m_config ); - - declareProperty( "JetCalibrationTool" , m_jetCalibrationTool ); - declareProperty( "JetCalibrationToolLargeR" , m_jetCalibrationToolLargeR ); - - declareProperty( "JetUncertaintiesToolLargeR" , m_jetUncertaintiesToolLargeR_strong); - declareProperty( "JetUncertaintiesTool" , m_jetUncertaintiesTool); - declareProperty( "JetUncertaintiesToolReducedNPScenario1" , m_jetUncertaintiesToolReducedNPScenario1 ); - declareProperty( "JetUncertaintiesToolReducedNPScenario2" , m_jetUncertaintiesToolReducedNPScenario2 ); - declareProperty( "JetUncertaintiesToolReducedNPScenario3" , m_jetUncertaintiesToolReducedNPScenario3 ); - declareProperty( "JetUncertaintiesToolReducedNPScenario4" , m_jetUncertaintiesToolReducedNPScenario4 ); - - declareProperty( "JetJERSmearingTool" , m_jetJERSmearingTool ); - declareProperty( "JetUpdateJvtTool" , m_jetUpdateJvtTool ); - - declareProperty( "TruthJetCollectionForHSTagging" , m_truthJetCollForHS = "AntiKt4TruthJets" ); -} - -StatusCode JetObjectCollectionMaker::initialize() { - ATH_MSG_INFO(" top::JetObjectCollectionMaker initialize" ); - - ///-- Lets do the nominal systematics --/// - ///-- JetObjectCollectionMaker is a little different from the others --/// - m_specifiedSystematics.push_back(CP::SystematicSet()); - m_specifiedSystematicsLargeR.push_back(CP::SystematicSet()); - m_specifiedSystematicsTrackJets.push_back(CP::SystematicSet()); - m_recommendedSystematics.push_back(CP::SystematicSet()); - - - top::check( m_jetCalibrationTool.retrieve() , "Failed to retrieve JetCalibrationTool" ); - if (m_config->useLargeRJets()) { - top::check( m_jetCalibrationToolLargeR.retrieve(), - "Failed to retrieve JetCalibrationToolLargeR" ); - top::check( m_jetUncertaintiesToolLargeR_strong.retrieve(), - "Failed to retrieve JetUncertaintiesToolLargeR_Strong" ); - top::check( m_jetUncertaintiesToolLargeR_medium.retrieve(), - "Failed to retrieve JetUncertaintiesToolLargeR_Medium" ); - top::check( m_jetUncertaintiesToolLargeR_weak.retrieve(), - "Failed to retrieve JetUncertaintiesToolLargeR_Weak" ); +namespace top { + JetObjectCollectionMaker::JetObjectCollectionMaker(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), + m_doJER(false), + m_doFull_JER(false), + m_doFull_JER_Pseudodata(false), + m_isMC(false), + m_doMultipleJES(false), + + m_specifiedSystematics(), + m_specifiedSystematicsLargeR(), + m_specifiedSystematicsTrackJets(), + m_recommendedSystematics(), + m_nominalSystematicSet(), + + m_jetCalibrationTool("JetCalibrationTool"), + m_jetCalibrationToolLargeR("JetCalibrationToolLargeR"), + + m_jetUncertaintiesTool("JetUncertaintiesTool"), + m_jetUncertaintiesToolFrozenJMS("JetUncertaintiesToolFrozenJMS"), + m_jetUncertaintiesToolReducedNPScenario1("JetUncertaintiesToolReducedNPScenario1"), + m_jetUncertaintiesToolReducedNPScenario2("JetUncertaintiesToolReducedNPScenario2"), + m_jetUncertaintiesToolReducedNPScenario3("JetUncertaintiesToolReducedNPScenario3"), + m_jetUncertaintiesToolReducedNPScenario4("JetUncertaintiesToolReducedNPScenario4"), + m_jetUncertaintiesToolLargeR("JetUncertaintiesToolLargeR"), + + m_jetUpdateJvtTool("JetUpdateJvtTool"), + m_jetSelectfJvtTool("JetSelectfJvtTool"), + + m_jetSubstructure(nullptr), + + m_systMap_AllNP(), + m_systMap_AllNP_FrozenJMS(), + m_systMap_ReducedNPScenario1(), + m_systMap_ReducedNPScenario2(), + m_systMap_ReducedNPScenario3(), + m_systMap_ReducedNPScenario4(), + m_systMap_LargeR() { + declareProperty("config", m_config); + + declareProperty("JetCalibrationTool", m_jetCalibrationTool); + declareProperty("JetCalibrationToolLargeR", m_jetCalibrationToolLargeR); + + declareProperty("JetUncertaintiesTool", m_jetUncertaintiesTool); + declareProperty("JetUncertaintiesToolFrozenJMS", m_jetUncertaintiesToolFrozenJMS); + declareProperty("JetUncertaintiesToolReducedNPScenario1", m_jetUncertaintiesToolReducedNPScenario1); + declareProperty("JetUncertaintiesToolReducedNPScenario2", m_jetUncertaintiesToolReducedNPScenario2); + declareProperty("JetUncertaintiesToolReducedNPScenario3", m_jetUncertaintiesToolReducedNPScenario3); + declareProperty("JetUncertaintiesToolReducedNPScenario4", m_jetUncertaintiesToolReducedNPScenario4); + declareProperty("JetUncertaintiesToolLargeR", m_jetUncertaintiesToolLargeR); + + declareProperty("JetUpdateJvtTool", m_jetUpdateJvtTool); + + declareProperty("TruthJetCollectionForHSTagging", m_truthJetCollForHS = "AntiKt4TruthJets"); } - // If we are using particle flow jets then we - // don't have any uncertainties so skip the retrieval. - if (!m_config->useParticleFlowJets()) { - ///-- JER uncertainties model --/// - if (m_config->jetJERSmearingModel() == "Full") - m_doFull_JER = true; - if (m_config->jetJERSmearingModel() == "Simple") - m_doFull_JER = false; + StatusCode JetObjectCollectionMaker::initialize() { + ATH_MSG_INFO(" top::JetObjectCollectionMaker initialize"); - ///-- Are we doing JER? Let's not repeat this logic over and over --/// - if (m_config->isMC()) - m_doJER = true; - if (!m_config->isMC() && m_doFull_JER) - m_doJER = true; + ///-- Lets do the nominal systematics --/// + ///-- JetObjectCollectionMaker is a little different from the others --/// + m_specifiedSystematics.push_back(CP::SystematicSet()); + m_specifiedSystematicsLargeR.push_back(CP::SystematicSet()); + m_specifiedSystematicsTrackJets.push_back(CP::SystematicSet()); + m_recommendedSystematics.push_back(CP::SystematicSet()); - if (m_config->isMC()) { - if (!m_config->doMultipleJES()) { - top::check( m_jetUncertaintiesTool.retrieve() , "Failed to retrieve JetUncertaintiesToolAllNP" ); - } - if (m_config->doMultipleJES()) { - top::check( m_jetUncertaintiesToolReducedNPScenario1.retrieve() , "Failed to retrieve JetUncertaintiesToolReducedNPScenario1" ); - top::check( m_jetUncertaintiesToolReducedNPScenario2.retrieve() , "Failed to retrieve JetUncertaintiesToolReducedNPScenario2" ); - top::check( m_jetUncertaintiesToolReducedNPScenario3.retrieve() , "Failed to retrieve JetUncertaintiesToolReducedNPScenario3" ); - top::check( m_jetUncertaintiesToolReducedNPScenario4.retrieve() , "Failed to retrieve JetUncertaintiesToolReducedNPScenario4" ); - } + top::check(m_jetCalibrationTool.retrieve(), "Failed to retrieve JetCalibrationTool"); + if (m_config->useLargeRJets()) { + top::check(m_jetCalibrationToolLargeR.retrieve(), + "Failed to retrieve JetCalibrationToolLargeR"); + top::check(m_jetUncertaintiesToolLargeR.retrieve(), + "Failed to retrieve JetUncertaintiesToolLargeR"); } - top::check( m_jetJERSmearingTool.retrieve() , "Failed to retrieve JetJERSmearingTool" ); - } - - top::check( m_jetUpdateJvtTool.retrieve() , "Failed to retrieve JetUpdateJvtTool" ); - top::check(m_fjvtTool.retrieve(), "Failed to retrieve fJVTTool"); + if (m_config->getDerivationStream() == "PHYS") { + m_truthJetCollForHS = "AntiKt4TruthDressedWZJets"; + } - // Take this from the TopConfiguration - // A blank vector will setup all systematics + ///-- JER uncertainties model --/// + if (m_config->jetJERSmearingModel() == "Full" || m_config->jetJERSmearingModel() == "All") m_doFull_JER = true; + if (m_config->jetJERSmearingModel() == "Simple") m_doFull_JER = false; + if (m_config->jetJERSmearingModel() == "Full_PseudoData" || + m_config->jetJERSmearingModel() == "All_PseudoData") m_doFull_JER_Pseudodata = true; + else m_doFull_JER_Pseudodata = false; - const std:: string& syststr = m_config->systematics(); - std::set<std::string> syst,systLargeR; - if( !m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)){ - bool ok = m_config->getSystematicsList(syststr, syst); - bool okLargeR = m_config->getSystematicsList(syststr, systLargeR); - if (!ok || !okLargeR) { - ATH_MSG_ERROR(" top::JetObjectCollectionMaker could not determine systematic list" ); - return StatusCode::FAILURE; - } - if (m_config->contains(syst, "AllJets")) { - syst.clear(); - systLargeR.clear(); - } - } + m_isMC = m_config->isMC(); + m_doMultipleJES = m_config->doMultipleJES(); - // If we are using particle flow jets then we - // don't have any uncertainties so skip - // trying to use the tools - if (!m_config->useParticleFlowJets()) { - ///-- JES systematics --/// - if (m_config->isMC()) { - std::string allNP("JET_"+m_config->jetUncertainties_NPModel()+"_"),np1("JET_NPScenario1_"),np2("JET_NPScenario2_"),np3("JET_NPScenario3_"),np4("JET_NPScenario4_"); - std::string largeR_strong("LARGERJET_Strong_"), - largeR_medium("LARGERJET_Medium_"), - largeR_weak("LARGERJET_Weak_"); - - if (!m_config->doMultipleJES()) { - specifiedSystematics( syst , m_jetUncertaintiesTool , m_systMap_AllNP , allNP ); - } - if (m_config->doMultipleJES()) { - specifiedSystematics( syst , m_jetUncertaintiesToolReducedNPScenario1 , m_systMap_ReducedNPScenario1 , np1 ); - specifiedSystematics( syst , m_jetUncertaintiesToolReducedNPScenario2 , m_systMap_ReducedNPScenario2 , np2 ); - specifiedSystematics( syst , m_jetUncertaintiesToolReducedNPScenario3 , m_systMap_ReducedNPScenario3 , np3 ); - specifiedSystematics( syst , m_jetUncertaintiesToolReducedNPScenario4 , m_systMap_ReducedNPScenario4 , np4 ); - } - if (m_config->useLargeRJets()) { - specifiedSystematics( syst , m_jetUncertaintiesToolLargeR_strong , m_systMap_LargeR_strong , largeR_strong , true); - specifiedSystematics( syst , m_jetUncertaintiesToolLargeR_medium , m_systMap_LargeR_medium , largeR_medium , true); - specifiedSystematics( syst , m_jetUncertaintiesToolLargeR_weak , m_systMap_LargeR_weak , largeR_weak , true); + ///-- Are we doing JER? Let's not repeat this logic over and over --/// + if (m_isMC) m_doJER = true; + if (!m_isMC && m_doFull_JER) m_doJER = true; + /// NB: for "Full_PseudoData", no need to smear the data, so m_doJER is false on data unless it's "Full" + + if (m_isMC || m_doFull_JER) { + if (!m_doMultipleJES) { + top::check(m_jetUncertaintiesTool.retrieve(), "Failed to retrieve JetUncertaintiesTool"); + if (m_config->jetCalibSequence() == "JMS") { + top::check(m_jetUncertaintiesToolFrozenJMS.retrieve(), "Failed to retrieve JetUncertaintiesTool (FrozenJMS)"); + } + } else { + top::check( + m_jetUncertaintiesToolReducedNPScenario1.retrieve(), + "Failed to retrieve JetUncertaintiesToolReducedNPScenario1"); + top::check( + m_jetUncertaintiesToolReducedNPScenario2.retrieve(), + "Failed to retrieve JetUncertaintiesToolReducedNPScenario2"); + top::check( + m_jetUncertaintiesToolReducedNPScenario3.retrieve(), + "Failed to retrieve JetUncertaintiesToolReducedNPScenario3"); + top::check( + m_jetUncertaintiesToolReducedNPScenario4.retrieve(), + "Failed to retrieve JetUncertaintiesToolReducedNPScenario4"); } } - ///-- JER systematics --/// - if (m_doJER) - specifiedSystematics( syst , m_jetJERSmearingTool , m_systMap_JER ); - } - - // See http://cern.ch/go/nHF6 for more information - if (m_config->doLargeRSmallRCorrelations()) { - systMap* smallR_systs = &m_systMap_AllNP; - if (m_config->doMultipleJES()) { - smallR_systs = &m_systMap_ReducedNPScenario1; - } - addCorrelation("CORR_LargeRSmallR_A", *smallR_systs, - "JET_GroupedNP_2", - m_systMap_LargeR_strong, "JET_Top_Run1_Tau32"); - - addCorrelation("CORR_LargeRSmallR_B", *smallR_systs, - "JET_GroupedNP_2", - m_systMap_LargeR_weak, "JET_Rtrk_Baseline_pT"); - - addCorrelation("CORR_LargeRSmallR_C__1up", m_systMap_LargeR_weak, - "JET_Rtrk_Baseline_mass__1up-JET_Top_Run1_Tau32__1up", - m_specifiedSystematicsLargeR); - - addCorrelation("CORR_LargeRSmallR_C__1down", m_systMap_LargeR_weak, - "JET_Rtrk_Baseline_mass__1down-JET_Top_Run1_Tau32__1down", - m_specifiedSystematicsLargeR); - } - ///-- Large R jet substructure --/// - if (m_config->jetSubstructureName() == "Trimmer") - m_jetSubstructure.reset(new top::LargeJetTrimmer); - if (m_config->jetSubstructureName() == "SubjetMaker") - m_jetSubstructure.reset(new top::SubjetMaker); - m_config->systematicsJets( specifiedSystematics() ); - m_config->systematicsLargeRJets( specifiedSystematicsLargeR() ); - m_config->systematicsTrackJets( m_specifiedSystematicsTrackJets ); - return StatusCode::SUCCESS; -} -StatusCode JetObjectCollectionMaker::executeJets() { - bool isLargeR(false); - return execute( isLargeR ); -} + top::check(m_jetUpdateJvtTool.retrieve(), "Failed to retrieve JetUpdateJvtTool"); + //fJVT tool isn't setup unless requested + if (m_config->doForwardJVTinMET() || m_config->getfJVTWP() != "None") { + top::check(m_jetSelectfJvtTool.retrieve(), "Failed to retrieve JetSelectfJvtTool"); + } + // Take this from the TopConfiguration + // A blank vector will setup all systematics -StatusCode JetObjectCollectionMaker::executeLargeRJets() { - bool isLargeR(true); - return execute( isLargeR ); -} + const std:: string& syststr = m_config->systematics(); + std::set<std::string> syst, systLargeR; -StatusCode JetObjectCollectionMaker::execute( const bool isLargeR ) { - // decorating the HS jets with truth info on which are HS jets - if (!isLargeR & m_config->isMC()) { - top::check( decorateHSJets() , "Failed to decorate jets with truth info of which are HS - this is needed for JVT scale-factors!"); - } - - ///-- First calibrate the nominal jets, everything else comes from this, so let's only do it once not 3000 times --/// - top::check( calibrate( isLargeR ) , "Failed to calibrate jets"); + if (!m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)) { + bool ok = m_config->getSystematicsList(syststr, syst); + bool okLargeR = m_config->getSystematicsList(syststr, systLargeR); + if (!ok || !okLargeR) { + ATH_MSG_ERROR(" top::JetObjectCollectionMaker could not determine systematic list"); + return StatusCode::FAILURE; + } + //here the idea is that if the user specifies AllXXX, we leave syst as an empty string, so that all recommended CP + // systematics are then used + if (m_config->contains(syst, "AllJets")) { + syst.clear(); + systLargeR.clear(); + } + if (m_config->contains(syst, "AllSmallRJets")) { + syst.clear(); + } + if (m_config->contains(systLargeR, "AllLargeRJets")) { + systLargeR.clear(); + } + } - // No uncertainties yet for pflow - // - return SUCCESS after calibration - if (m_config->useParticleFlowJets()) - return StatusCode::SUCCESS; - ///-- JES, JER regular atk4 for now --/// - if (!isLargeR) { - ///-- JES --/// - if (m_config->isMC()) { - if (!m_config->doMultipleJES()) { - top::check( applySystematic( m_jetUncertaintiesTool , m_systMap_AllNP ) , "Failed to apply JES"); + ///-- JES systematics --/// + if (m_isMC || m_doFull_JER) { + std::string allNP(m_config->jetUncertainties_NPModel() + "_"), + np1("SR_Scenario1_"), np2("SR_Scenario2_"), np3("SR_Scenario3_"), np4("SR_Scenario4_"); + std::string allNP_FrozenJMS(m_config->jetUncertainties_NPModel() + "_FrozenJMS_"); + + bool onlyJER = ((!m_isMC) && m_doFull_JER) || (m_isMC && m_doFull_JER_Pseudodata); + + if (!m_doMultipleJES) { + addSystematics(syst, m_jetUncertaintiesTool->recommendedSystematics(), m_systMap_AllNP, allNP, false, onlyJER); + if (m_config->jetCalibSequence() == "JMS") { + addSystematics(syst, + m_jetUncertaintiesToolFrozenJMS->recommendedSystematics(), m_systMap_AllNP_FrozenJMS, allNP_FrozenJMS, false, + onlyJER); + } + } else { + addSystematics(syst, + m_jetUncertaintiesToolReducedNPScenario1->recommendedSystematics(), m_systMap_ReducedNPScenario1, np1, false, + onlyJER); + addSystematics(syst, + m_jetUncertaintiesToolReducedNPScenario2->recommendedSystematics(), m_systMap_ReducedNPScenario2, np2, false, + onlyJER); + addSystematics(syst, + m_jetUncertaintiesToolReducedNPScenario3->recommendedSystematics(), m_systMap_ReducedNPScenario3, np3, false, + onlyJER); + addSystematics(syst, + m_jetUncertaintiesToolReducedNPScenario4->recommendedSystematics(), m_systMap_ReducedNPScenario4, np4, false, + onlyJER); } - if (m_config->doMultipleJES()) { - top::check( applySystematic( m_jetUncertaintiesToolReducedNPScenario1 , m_systMap_ReducedNPScenario1 ) , "Failed to apply JES"); - top::check( applySystematic( m_jetUncertaintiesToolReducedNPScenario2 , m_systMap_ReducedNPScenario2 ) , "Failed to apply JES"); - top::check( applySystematic( m_jetUncertaintiesToolReducedNPScenario3 , m_systMap_ReducedNPScenario3 ) , "Failed to apply JES"); - top::check( applySystematic( m_jetUncertaintiesToolReducedNPScenario4 , m_systMap_ReducedNPScenario4 ) , "Failed to apply JES"); + } + ///-- Large-R JES systematics --/// + std::string largeRModName = getLargeRModName(m_config->largeRJetUncertainties_NPModel()); + CP::SystematicSet largeRsysts; + if (m_config->useLargeRJets() && m_config->isMC()) { //No JES uncertainties for Data at the moment + if ((m_config->largeRJESJMSConfig() == "CombMass") || (m_config->largeRJESJMSConfig() == "TCCMass")) { //TA mass + // and + // combined + // mass not + // supported + // for + // JMS/JMR + // for now + largeRsysts.insert(m_jetUncertaintiesToolLargeR->recommendedSystematics()); + } else { + ATH_MSG_WARNING( + "TA Mass & Calo Mass are not supported for large-R jet uncertainties at the moment. Large-R jet systemtatics skipped!"); } } - ///-- JER --/// - if (m_doJER) - top::check( applySystematic ( m_jetJERSmearingTool , m_systMap_JER ) , "Failed to apply JER" ); - } else { - if (m_config->isMC()) { - top::check( applySystematic( m_jetUncertaintiesToolLargeR_strong , m_systMap_LargeR_strong, true ) , "Failed to apply large-R syst."); - top::check( applySystematic( m_jetUncertaintiesToolLargeR_medium , m_systMap_LargeR_medium, true ) , "Failed to apply large-R syst."); - top::check( applySystematic( m_jetUncertaintiesToolLargeR_weak , m_systMap_LargeR_weak, true ) , "Failed to apply large-R syst."); + ///-- Large R jet tagger scale factor uncertainties -- /// + if (m_config->isMC() && m_config->useLargeRJets()) { + for (const std::pair<std::string, std::string>& name : m_config->boostedTaggerSFnames()) { + ToolHandle<ICPJetUncertaintiesTool> tmp_SF_uncert_tool("JetSFuncert_" + name.first); + if (tmp_SF_uncert_tool.retrieve()) { + largeRsysts.insert(tmp_SF_uncert_tool->recommendedSystematics()); + m_tagSFuncertTool[name.first] = tmp_SF_uncert_tool; + } + } + } + + // add the merged set of systematics for large-R jets including the tagging SF systs + addSystematics(systLargeR, largeRsysts, m_systMap_LargeR, largeRModName, true); + + ///-- Large R jet substructure --/// + if (m_config->jetSubstructureName() == "Trimmer") m_jetSubstructure.reset(new top::LargeJetTrimmer); + + if (m_config->jetSubstructureName() == "SubjetMaker") m_jetSubstructure.reset(new top::SubjetMaker); + + ///-- Large R jet truth labeling --/// +// m_jetTruthLabelingTool = nullptr; +// if (m_config->isMC() && m_config->useLargeRJets()) { +// m_jetTruthLabelingTool = std::unique_ptr<JetTruthLabelingTool>(new JetTruthLabelingTool("JetTruthLabeling")); +// // For DAOD_PHYS we need to pass few more arguments as it uses TRUTH3 +// if (m_config->getDerivationStream() == "PHYS") { +// top::check(m_jetTruthLabelingTool->setProperty("UseTRUTH3", true), "Failed to set UseTRUTH3 for m_jetTruthLabelingTool"); +// top::check(m_jetTruthLabelingTool->setProperty("TruthBosonContainerName", "TruthBoson"), "Failed to set truth container name for m_jetTruthLabelingTool"); +// top::check(m_jetTruthLabelingTool->setProperty("TruthTopQuarkContainerName", "TruthTop"), "Failed to set truth container name for m_jetTruthLabelingTool"); +// } +// top::check(m_jetTruthLabelingTool->initialize(), "Failed to initialize m_jetTruthLabelingTool"); +// } + + // set the systematics list + m_config->systematicsJets(specifiedSystematics()); + m_config->systematicsLargeRJets(specifiedSystematicsLargeR()); + m_config->systematicsTrackJets(m_specifiedSystematicsTrackJets); + + ///-- DL1 Decoration --/// + for (const std::pair<std::string, std::string>& algo : m_config->bTagAlgo_selToolNames()) { + m_btagSelToolsDL1Decor[algo.first] = algo.second; + top::check(m_btagSelToolsDL1Decor[algo.first].retrieve(), "Failed to retrieve " + algo.first + " btagging selector for " + m_config->sgKeyJets() + ". This is required for b-tagging score decorations in EventSaver!"); + if (DLx.count(algo.first) == 0) { + DLx.emplace(algo.first, SG::AuxElement::Decorator<float>("AnalysisTop_" + algo.first)); + } } - } - return StatusCode::SUCCESS; -} + if (m_config->useTrackJets()) { + for (const std::pair<std::string, std::string>& algo : m_config->bTagAlgo_selToolNames_trkJet()) { + m_btagSelToolsDL1Decor_trkJet[algo.first] = algo.second; + top::check(m_btagSelToolsDL1Decor_trkJet[algo.first].retrieve(), "Failed to retrieve " + algo.first + " btagging selector for " + m_config->sgKeyTrackJets() + ". This is required for b-tagging score decorations in EventSaver!"); + if (DLx.count(algo.first) == 0) { + DLx.emplace(algo.first, SG::AuxElement::Decorator<float>("AnalysisTop_" + algo.first)); + } + } + } -StatusCode JetObjectCollectionMaker::calibrate(const bool isLargeR) { - ///-- Get base jets from xAOD --/// - std::string sgKey = isLargeR ? m_config->sgKeyLargeRJets() : m_config->sgKeyJets(); + // initialize boosted jet taggers -- we have to do it here instead pf TopObjectSelectionTools + // because we have to apply tagger inbetween JES uncertainty tool and the tagging SF tool + if (m_config->useLargeRJets()) { + for (const std::pair<std::string, std::string>& name : m_config->boostedJetTaggers()) { + std::string fullName = name.first + "_" + name.second; + m_boostedJetTaggers[fullName] = ToolHandle<IJetSelectorTool>(fullName); + top::check(m_boostedJetTaggers[fullName].retrieve(), "Failed to retrieve " + fullName); + } + } - const xAOD::JetContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , sgKey ) , "Failed to retrieve Jets" ); + return StatusCode::SUCCESS; + } - ///-- Shallow copy of the xAOD --/// - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *xaod ); + StatusCode JetObjectCollectionMaker::executeJets(bool executeNominal) { + bool isLargeR(false); - ///-- Loop over the xAOD Container --/// - for( auto jet : *(shallow_xaod_copy.first) ){ + return execute(isLargeR, executeNominal); + } - if (!isLargeR) { ///-- small-R jets used in most analyses --/// - ///-- Calibrate jet --/// - - top::check(m_jetCalibrationTool->applyCalibration(*jet), "Failed to applyCalibration"); - - // only multiply by JSF and bJSF if one of them != 1.0 (used by top mass analysis) - float JSF = m_config -> JSF(); - float bJSF = m_config -> bJSF(); + StatusCode JetObjectCollectionMaker::executeLargeRJets(bool executeNominal) { + bool isLargeR(true); - if(JSF != 1.0 || bJSF != 1.0){ + return execute(isLargeR, executeNominal); + } - int truthflav = -1; - if(jet->isAvailable<int>("HadronConeExclTruthLabelID")){ - jet->getAttribute("HadronConeExclTruthLabelID", truthflav); + StatusCode JetObjectCollectionMaker::execute(const bool isLargeR, bool executeNominal) { + ///-- Run nominal first, if executing nominal + if (executeNominal) { + // decorating the HS jets with truth info on which are HS jets + if (!isLargeR & m_isMC) { + top::check( + decorateHSJets(), + "Failed to decorate jets with truth info of which are HS - this is needed for JVT scale-factors!"); + if (m_isMC && m_config->jetResponseMatchingDeltaR() > 0) { + top::check(decorateMatchedTruth(), "Failed to decorate matched jet"); } - - xAOD::JetFourMom_t jet_p4 = jet->jetP4()*JSF; - if(truthflav == 5) jet_p4 = jet_p4*bJSF; - - jet -> setJetP4(jet_p4); - } - // end application JSF/bJSF + // Decorate the DL1 variable + top::check(decorateDL1(), "Failed to decorate jets with DL1 b-tagging discriminant"); - top::check(decorateBJets(*jet), "Failed to decorate if b-jet"); + ///-- First calibrate the nominal jets, everything else comes from this, so let's only do it once not 3000 times + // --/// + top::check(calibrate(isLargeR), "Failed to calibrate jets"); + + ///-- Return after calibrating the nominal --/// + return StatusCode::SUCCESS; } - if (isLargeR && m_jetSubstructure.get() != nullptr) { - m_jetSubstructure->correctJet( *jet ); + ///-- Systematics from here --/// + + ///-- JES, JER regular atk4 for now --/// + if (!isLargeR) { + ///-- JES --/// + if (m_isMC || m_doFull_JER) { + if (!m_doMultipleJES) { + top::check(applySystematic(m_jetUncertaintiesTool, m_systMap_AllNP), "Failed to apply JES"); + if (m_config->jetCalibSequence() == "JMS") { + top::check(applySystematic(m_jetUncertaintiesToolFrozenJMS, + m_systMap_AllNP_FrozenJMS), "Failed to apply JES Frozen JMS"); + } + } + if (m_doMultipleJES) { + top::check(applySystematic(m_jetUncertaintiesToolReducedNPScenario1, + m_systMap_ReducedNPScenario1), "Failed to apply JES"); + top::check(applySystematic(m_jetUncertaintiesToolReducedNPScenario2, + m_systMap_ReducedNPScenario2), "Failed to apply JES"); + top::check(applySystematic(m_jetUncertaintiesToolReducedNPScenario3, + m_systMap_ReducedNPScenario3), "Failed to apply JES"); + top::check(applySystematic(m_jetUncertaintiesToolReducedNPScenario4, + m_systMap_ReducedNPScenario4), "Failed to apply JES"); + } + } + } else { + // tag calibrated (nominal) jets -- the tagging information will be available + // for systematically-shifted shallow copies as well + top::check(tagNominalLargeRJets(), "Failed to tag large-R jets"); + if (m_config->isMC()) { + top::check(applySystematic(m_jetUncertaintiesToolLargeR, m_systMap_LargeR, + true), "Failed to apply large-R syst."); + } } - if (isLargeR) { - ///-- Calibrate jet --/// + return StatusCode::SUCCESS; + } - float tau3 = jet->getAttribute<float>("Tau3_wta"); - float tau2 = jet->getAttribute<float>("Tau2_wta"); - float tau1 = jet->getAttribute<float>("Tau1_wta"); + StatusCode JetObjectCollectionMaker::calibrate(const bool isLargeR) { + ///-- Get base jets from xAOD --/// + std::string sgKey = isLargeR ? m_config->sgKeyLargeRJets() : m_config->sgKeyJets(); - jet -> auxdecor<float>("Tau32_wta") = fabs(tau2) > 1.e-6 ? (tau3/tau2) : -999; // 999 to match JetSubStructureMomentTools/NSubjettinessRatiosTool - jet -> auxdecor<float>("Tau21_wta") = fabs(tau1) > 1.e-6 ? (tau2/tau1) : -999; // 999 to match JetSubStructureMomentTools/NSubjettinessRatiosTool + const xAOD::JetContainer* xaod(nullptr); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve Jets"); + + ///-- Shallow copy of the xAOD --/// + std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer(*xaod); + + ///-- Loop over the xAOD Container --/// +// for (const auto jet : *(shallow_xaod_copy.first)) { +// if (!isLargeR) { ///-- small-R jets used in most analyses --/// +// ///-- Calibrate jet --/// +// +// top::check(m_jetCalibrationTool->applyCalibration(*jet), "Failed to applyCalibration"); +// +// // only multiply by JSF and bJSF if one of them != 1.0 (used by top mass analysis) +// float JSF = m_config->JSF(); +// float bJSF = m_config->bJSF(); +// +// if (JSF != 1.0 || bJSF != 1.0) { +// int truthflav = -1; +// if (jet->isAvailable<int>("PartonTruthLabelID")) { +// jet->getAttribute("PartonTruthLabelID", truthflav); +// } +// +// xAOD::JetFourMom_t jet_p4 = jet->jetP4() * JSF; +// if (truthflav == 5) jet_p4 = jet_p4 * bJSF; +// +// jet->setJetP4(jet_p4); +// } +// // end application JSF/bJSF +// +// +// top::check(decorateBJets(*jet), "Failed to decorate if b-jet"); +// } +// +// if (isLargeR && m_jetSubstructure.get() != nullptr) { +// m_jetSubstructure->correctJet(*jet); +// } +// +// if (isLargeR) { +// ///-- Calibrate jet --/// +// +// float tau3 = jet->getAttribute<float>("Tau3_wta"); +// float tau2 = jet->getAttribute<float>("Tau2_wta"); +// float tau1 = jet->getAttribute<float>("Tau1_wta"); +// float ECF1 = jet->getAttribute<float>("ECF1"); +// float ECF2 = jet->getAttribute<float>("ECF2"); +// float ECF3 = jet->getAttribute<float>("ECF3"); +// +// jet->auxdecor<float>("Tau32_wta") = fabs(tau2) > 1.e-6 ? (tau3 / tau2) : -999; // 999 to match +// // JetSubStructureMomentTools/NSubjettinessRatiosTool +// jet->auxdecor<float>("Tau21_wta") = fabs(tau1) > 1.e-6 ? (tau2 / tau1) : -999; // 999 to match +// // JetSubStructureMomentTools/NSubjettinessRatiosTool +// // Same definition as in JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx +// jet->auxdecor<float>("D2") = (ECF2 > 1e-8) ? (ECF3*ECF1*ECF1*ECF1) / (ECF2*ECF2*ECF2) : -999; +// jet->auxdecor<float>("C2") = (ECF2 > 1e-8) ? (ECF3*ECF1) / (ECF2*ECF2) : -999; +// jet->auxdecor<float>("E3") = (ECF1 > 1e-8) ? ECF3 / (ECF1*ECF1*ECF1) : -999; +// +// +// top::check(m_jetCalibrationToolLargeR->applyCalibration(*jet), "Failed to applyCalibration"); +// +// ///-- for TA mass or calo mass, the calibrated mass or pt needs special treatment --/// +// const std::string calibChoice = m_config->largeRJESJMSConfig(); +// if (m_config->isMC()) { +// ///-- Truth labeling required by the large-R jet uncertainties --/// +//// top::check(m_jetTruthLabelingTool->modifyJet(*jet), "Failed to do truth labeling for large-R jet"); +// if (calibChoice == "TAMass") { +// xAOD::JetFourMom_t jet_calib_p4; +// jet->getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumTA", jet_calib_p4); +// jet->setJetP4(jet_calib_p4); +// } +// } else { //For data, there's only one config file so special method is required for TA mass and Calos mass +// if (calibChoice == "CaloMass") { +// xAOD::JetFourMom_t jetInsituP4_calo; +// jet->getAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentumCalo", jetInsituP4_calo); +// jet->setJetP4(jetInsituP4_calo); +// } else if (calibChoice == "TAMass") { +// xAOD::JetFourMom_t jetInsituP4_ta; +// jet->getAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentumTA", jetInsituP4_ta); +// jet->setJetP4(jetInsituP4_ta); +// } +// } +// } +// +// ///-- Update JVT --/// +// if (!isLargeR) { +// jet->auxdecor<float>("AnalysisTop_JVT") = m_jetUpdateJvtTool->updateJvt(*jet); +// } +// } + + // Check if the derivation we are running on contains + // MET_Track (once), if so apply the fJVT decoration + // if not then don't + if (!isLargeR && (m_config->doForwardJVTinMET() || m_config->getfJVTWP() != "None")) { + static bool checked_track_MET = false; + if (!checked_track_MET) { + if (evtStore()->contains<xAOD::MissingETContainer>("MET_Track")) { + m_do_fjvt = true; + } else { + ATH_MSG_ERROR(" Cannot retrieve MET_Track, fJVT values can't be calculated correctly!!"); + return StatusCode::FAILURE; + } + checked_track_MET = true; + } + } + if (m_do_fjvt) { + top::check(!m_jetSelectfJvtTool->modify(*shallow_xaod_copy.first), + "Failed to apply fJVT decoration"); + } - top::check( m_jetCalibrationToolLargeR->applyCalibration( *jet ) , "Failed to applyCalibration" ); + if (!isLargeR) { + ///-- Save calibrated jet to TStore --/// + ///-- set links to original objects- needed for MET calculation --/// + // NOTE, if we use one of the b-tagging re-trained collections, we need to load + // the original uncalibrated jet container to which the b-tagging shallow-copy is pointing to + const xAOD::JetContainer* xaod_original(nullptr); + // for small-R jet collections, set links to uncalibrated *original* jets (not BTagging shallow-copy) + if (m_config->sgKeyJets() != m_config->sgKeyJetsType()) { + top::check(evtStore()->retrieve(xaod_original, + m_config->sgKeyJetsType()), + "Failed to retrieve uncalibrated Jets for METMaker!"); + } else { + xaod_original = xaod; + } + bool setLinks = xAOD::setOriginalObjectLink(*xaod_original, *shallow_xaod_copy.first); + if (!setLinks) ATH_MSG_ERROR(" Cannot set original object links for jets, MET recalculation may struggle"); } - ///-- Update JVT --/// + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + std::string outputSGKey; if (!isLargeR) { - jet->auxdecor<float>("AnalysisTop_JVT") = m_jetUpdateJvtTool->updateJvt( *jet ); + outputSGKey = m_config->sgKeyJetsStandAlone(m_nominalSystematicSet.hash()); } - - } - - // Check if the derivation we are running on contains - // MET_Track (once), if so apply the fJVT decoration - // if not then don't - static bool checked_track_MET = false; - if (!checked_track_MET) { - if (evtStore()->contains<xAOD::MissingETContainer>("MET_Track")) { - m_do_fjvt = true; + if (isLargeR) { + outputSGKey = m_config->sgKeyLargeRJets(m_nominalSystematicSet.hash()); } - else { - if (m_config->fwdJetAndMET() == "fJVT") - ATH_MSG_ERROR(" Cannot retrieve MET_Track while fJVT is to be applied on forward jets" ); - else - ATH_MSG_WARNING(" Cannot retrieve MET_Track, so fJVT information will probably be wrong in output" ); + + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; } - checked_track_MET = true; - } - if (m_do_fjvt) { - top::check(!m_fjvtTool->modify(*shallow_xaod_copy.first), - "Failed to apply fJVT decoration"); + return StatusCode::SUCCESS; } - ///-- Save calibrated jet to TStore --/// - ///-- set links to original objects- needed for MET calculation --/// - bool setLinks = xAOD::setOriginalObjectLink( *xaod, *shallow_xaod_copy.first ); - if (!setLinks) - ATH_MSG_ERROR(" Cannot set original object links for jets, MET recalculation may struggle" ); + StatusCode JetObjectCollectionMaker::applySystematic(ToolHandle<ICPJetUncertaintiesTool>& tool, + const std::unordered_map<CP::SystematicSet, + CP::SystematicSet>& map, + bool isLargeR) { + ///-- Get calibrated jets --/// + const xAOD::JetContainer* xaod(nullptr); - ///-- Save corrected xAOD Container to StoreGate / TStore --/// - std::string outputSGKey; - if (!isLargeR) { - outputSGKey = m_config->sgKeyJetsStandAlone( m_nominalSystematicSet.hash() ); - } - if (isLargeR) { - outputSGKey = m_config->sgKeyLargeRJets( m_nominalSystematicSet.hash() ); - } + if (!isLargeR) { + top::check(evtStore()->retrieve(xaod, m_config->sgKeyJetsStandAlone( + m_nominalSystematicSet.hash())), "Failed to retrieve Jets"); + } else { + top::check(evtStore()->retrieve(xaod, m_config->sgKeyLargeRJets( + m_nominalSystematicSet.hash())), "Failed to retrieve Jets"); + } - std::string outputSGKeyAux = outputSGKey + "Aux."; + ///-- Loop over the systematics --/// - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_xaod_copy.first , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_xaod_copy.second , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } + for (Itr syst = map.begin(); syst != map.end(); ++syst) { + ///-- Don't do the nominal, we've already done that --/// + if ((*syst).second.hash() != m_nominalSystematicSet.hash()) { + ///-- Tell the tool which systematic to use --/// + ///-- Here we use the second, original CP::SystematicSet --/// + top::check(tool->applySystematicVariation((*syst).second), + "Failed to applySystematicVariation"); - return StatusCode::SUCCESS; -} + if (isLargeR && m_config->isMC()) { + // for boosted tagging SFs, apply syst variation for all initialized WPs + for (std::pair<const std::string, ToolHandle<ICPJetUncertaintiesTool> >& tagSF : m_tagSFuncertTool) { + top::check(tagSF.second->applySystematicVariation((*syst).second), "Failed to applySystematicVariation"); + } + } + ///-- Shallow copy of the xAOD --/// + std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > + shallow_xaod_copy = xAOD::shallowCopyContainer(*xaod); + + ///-- Loop over the xAOD Container --/// + for (auto jet : *(shallow_xaod_copy.first)) { + if (isLargeR && m_config->isMC()) { //JES for large-R jets only exist for MC + ///-- Only large R jets with the following properties can be calibrated.--/// + bool calibratable_jet = (std::fabs(jet->eta()) <= 2.0 + && jet->pt() > 175e3); //lower than 200e3 to allow studying on migration + std::string jetCalibrationNameLargeR = m_config->sgKeyLargeRJets(); + if (jetCalibrationNameLargeR.find("TrackCaloCluster") != std::string::npos) { //TCC jet + calibratable_jet = (jet->m() / jet->pt() <= 1. + && jet->m() / jet->pt() >= 0. + && std::fabs(jet->eta()) <= 2.0 + && jet->pt() > 150e3 + && jet->pt() < 3000e3); + } + if (!calibratable_jet) continue; + } + ///-- Apply Corrrection --/// + if (!(isLargeR && !m_config->isMC())) { //Large-R jet uncertainties don't apply to Data + top::check(tool->applyCorrection(*jet), "Failed to applyCorrection"); + } + ///-- Update JVT --/// + if (!isLargeR) jet->auxdecor<float>("AnalysisTop_JVT") = m_jetUpdateJvtTool->updateJvt(*jet); + + ///-- Decorate fJVT for systematics too --/// + // Check if the derivation we are running on contains + // MET_Track (once) before applying the fJVT decoration + if (!isLargeR && (m_config->doForwardJVTinMET() || m_config->getfJVTWP() != "None")) { + static bool checked_track_MET = false; + if (!checked_track_MET) { + if (evtStore()->contains<xAOD::MissingETContainer>("MET_Track")) { + m_do_fjvt = true; + } else { + ATH_MSG_ERROR(" Cannot retrieve MET_Track, fJVT values can't be calculated correctly!!"); + return StatusCode::FAILURE; + } + checked_track_MET = true; + } + } + if (m_do_fjvt) { + top::check(!m_jetSelectfJvtTool->modify(*shallow_xaod_copy.first), + "Failed to apply fJVT decoration"); + } + + + ///-- Apply large-R jet tagging SF uncertainties --/// + if (isLargeR && m_config->isMC()) { + for (std::pair<const std::string, ToolHandle<ICPJetUncertaintiesTool> >& tagSF : m_tagSFuncertTool) { + top::check(tagSF.second->applyCorrection(*jet), "Failed to applyCorrection"); + } + } + } -StatusCode JetObjectCollectionMaker::applySystematic(ToolHandle<ICPJetUncertaintiesTool>& tool, - const std::unordered_map<CP::SystematicSet,CP::SystematicSet>& map, - bool isLargeR ) { - ///-- Get calibrated jets --/// - const xAOD::JetContainer* xaod(nullptr); - if (!isLargeR) { - top::check( evtStore()->retrieve( xaod , m_config->sgKeyJetsStandAlone( m_nominalSystematicSet.hash() ) ) , "Failed to retrieve Jets" ); - } else { - top::check( evtStore()->retrieve( xaod , m_config->sgKeyLargeRJets( m_nominalSystematicSet.hash() ) ) , "Failed to retrieve Jets" ); - } + ///-- set links to original objects- needed for MET calculation --/// + bool setLinks = xAOD::setOriginalObjectLink(*xaod, + *shallow_xaod_copy.first); + if (!setLinks) ATH_MSG_ERROR(" Cannot set original object links" + " for jets, MET recalculation may struggle"); - ///-- Loop over the systematics --/// - - for (Itr syst=map.begin();syst!=map.end();++syst) { - ///-- Don't do the nominal, we've already done that --/// - if ((*syst).second.hash() != m_nominalSystematicSet.hash()) { - - ///-- Tell the tool which systematic to use --/// - ///-- Here we use the second, original CP::SystematicSet --/// - top::check( tool->applySystematicVariation((*syst).second) , - "Failed to applySystematicVariation" ); - - ///-- Shallow copy of the xAOD --/// - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > - shallow_xaod_copy = xAOD::shallowCopyContainer( *xaod ); - - ///-- Loop over the xAOD Container --/// - for( auto jet : *(shallow_xaod_copy.first) ){ - + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + ///-- Here we use the first, AnalysisTop modified CP::SystematicSer --/// + ///-- This allows us to run multiple JES scenarios, which all have the same hash values --/// + std::string outputSGKey; if (isLargeR) { - - if ((*syst).first.name().find("LARGER") == std::string::npos) - continue; - - ///-- Only large R jets with the following properties can be calibrated.--/// - bool calibratable_jet = (jet->m()/jet->pt() <= 1 - && std::fabs(jet->eta()) <= 2.0 - && jet->pt() > 150e3 - && jet->pt() < 3000e3); - if(!calibratable_jet) - continue; + outputSGKey = m_config->sgKeyLargeRJets((*syst).first.hash()); + } else { + outputSGKey = m_config->sgKeyJetsStandAlone((*syst).first.hash()); } - ///-- Apply Corrrection --/// - top::check( tool->applyCorrection( *jet ) , "Failed to applyCorrection" ); - ///-- Update JVT --/// - if (!isLargeR) jet->auxdecor<float>("AnalysisTop_JVT") = m_jetUpdateJvtTool->updateJvt( *jet ); - } - - ///-- set links to original objects- needed for MET calculation --/// - bool setLinks = xAOD::setOriginalObjectLink(*xaod, - *shallow_xaod_copy.first ); - if (!setLinks) - ATH_MSG_ERROR(" Cannot set original object links" - " for jets, MET recalculation may struggle" ); - - ///-- Save corrected xAOD Container to StoreGate / TStore --/// - ///-- Here we use the first, AnalysisTop modified CP::SystematicSer --/// - ///-- This allows us to run multiple JES scenarios, which all have the same hash values --/// - std::string outputSGKey; - if (isLargeR) { - outputSGKey = m_config->sgKeyLargeRJets( (*syst).first.hash() ); - } else { - outputSGKey = m_config->sgKeyJetsStandAlone( (*syst).first.hash() ); - } - std::string outputSGKeyAux = outputSGKey + "Aux."; + std::string outputSGKeyAux = outputSGKey + "Aux."; - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_xaod_copy.first , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_xaod_copy.second , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } } } - } - return StatusCode::SUCCESS; -} + return StatusCode::SUCCESS; + } + StatusCode JetObjectCollectionMaker::executeTrackJets(bool executeNominal) { + ///-- No calibrations or systematics yet --/// + ///-- Only run this on the nominal execution --/// + if (!executeNominal) return StatusCode::SUCCESS; + top::check(decorateDL1(true), "Failed to decorate track jets with DL1 b-tagging discriminant"); -StatusCode JetObjectCollectionMaker::applySystematic(ToolHandle<IJERSmearingTool>& tool, - const std::unordered_map<CP::SystematicSet,CP::SystematicSet>& map ) { - ///-- Get calibrated jets --/// - const xAOD::JetContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyJetsStandAlone( m_nominalSystematicSet.hash() ) ) , "Failed to retrieve Jets" ); - ///-- Loop over the systematics --/// + ///-- Just make a shallow copy to keep these in line with everything else --/// - for (Itr syst=map.begin();syst!=map.end();++syst) { - ///-- Don't do the nominal, we've already done that --/// - if ((*syst).second.hash() != m_nominalSystematicSet.hash()) { + const xAOD::JetContainer* xaod(nullptr); + top::check(evtStore()->retrieve(xaod, m_config->sgKeyTrackJets()), "Failed to retrieve Jets"); - ///-- Tell the tool which systematic to use --/// - ///-- Here we use the second, original CP::SystematicSet --/// - top::check( tool->applySystematicVariation( (*syst).second ) , "Failed to apply systematic" ); + ///-- Shallow copy of the xAOD --/// + std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer(*xaod); - ///-- Shallow copy of the xAOD --/// - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *xaod ); + ///-- set links to original objects --/// + bool setLinks = xAOD::setOriginalObjectLink(*xaod, *shallow_xaod_copy.first); + if (!setLinks) ATH_MSG_ERROR(" Cannot set original object links for track jets"); - ///-- Loop over the xAOD Container --/// - for( auto jet : *(shallow_xaod_copy.first) ){ - ///-- Apply Corrrection --/// - top::check( tool->applyCorrection( *jet ) , "Failed to applyCorrection" ); - ///-- Update JVT --/// - jet->auxdecor<float>("AnalysisTop_JVT") = m_jetUpdateJvtTool->updateJvt( *jet ); - } + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + std::string outputSGKey = m_config->sgKeyTrackJets(m_config->nominalHashValue()); + std::string outputSGKeyAux = outputSGKey + "Aux."; - ///-- set links to original objects- needed for MET calculation --/// - bool setLinks = xAOD::setOriginalObjectLink( *xaod, *shallow_xaod_copy.first ); - if (!setLinks) - ATH_MSG_ERROR(" Cannot set original object links for jets, MET recalculation may struggle" ); - - ///-- Save corrected xAOD Container to StoreGate / TStore --/// - ///-- Here we use the first, AnalysisTop modified CP::SystematicSer --/// - ///-- This allows us to run multiple JES scenarios, which all have the same hash values --/// - std::string outputSGKey = m_config->sgKeyJetsStandAlone( (*syst).first.hash() ); - std::string outputSGKeyAux = outputSGKey + "Aux."; - - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_xaod_copy.first , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_xaod_copy.second , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; } + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} - -StatusCode JetObjectCollectionMaker::executeTrackJets() { - ///-- No calibrations or systematics yet --/// - ///-- Just make a shallow copy to keep these in line with everything else --/// + StatusCode JetObjectCollectionMaker::printoutJets() { + bool isLargeR(false); - const xAOD::JetContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyTrackJets() ) , "Failed to retrieve Jets" ); - - ///-- Shallow copy of the xAOD --/// - std::pair< xAOD::JetContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *xaod ); - - ///-- set links to original objects --/// - bool setLinks = xAOD::setOriginalObjectLink( *xaod, *shallow_xaod_copy.first ); - if (!setLinks) - ATH_MSG_ERROR(" Cannot set original object links for track jets" ); + return this->printout(isLargeR); + } - ///-- Save corrected xAOD Container to StoreGate / TStore --/// - std::string outputSGKey = m_config->sgKeyTrackJets( m_config->nominalHashValue() ); - std::string outputSGKeyAux = outputSGKey + "Aux."; + StatusCode JetObjectCollectionMaker::printoutLargeRJets() { + bool isLargeR(true); - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_xaod_copy.first , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_xaod_copy.second , outputSGKeyAux ); - if( !save || !saveAux ){ - return StatusCode::FAILURE; + return this->printout(isLargeR); } - return StatusCode::SUCCESS; -} - -StatusCode JetObjectCollectionMaker::printoutJets() { - bool isLargeR(false); - return this->printout( isLargeR ); -} - -StatusCode JetObjectCollectionMaker::printoutLargeRJets() { - bool isLargeR(true); - return this->printout( isLargeR ); -} - -StatusCode JetObjectCollectionMaker::printout( const bool isLargeR ) { - ///-- Loop over all systematics --/// - for( auto s : m_specifiedSystematics ){ - std::string sgKey = isLargeR ? m_config->sgKeyLargeRJets() : m_config->sgKeyJets(); - const xAOD::JetContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , sgKey ) , "Failed to retrieve Jets" ); + StatusCode JetObjectCollectionMaker::printout(const bool isLargeR) { + ///-- Loop over all systematics --/// + for (auto s : m_specifiedSystematics) { + std::string sgKey = isLargeR ? m_config->sgKeyLargeRJets() : m_config->sgKeyJets(); - ATH_MSG_INFO(" Jets with sgKey = "<<sgKey ); - for( auto x : *xaod ){ - ATH_MSG_INFO(" Jet pT , eta = "<<x->pt()<<" , "<<x->eta() ); - } - } + const xAOD::JetContainer* xaod(nullptr); + top::check(evtStore()->retrieve(xaod, sgKey), "Failed to retrieve Jets"); - return StatusCode::SUCCESS; -} + ATH_MSG_INFO(" Jets with sgKey = " << sgKey); + for (auto x : *xaod) { + ATH_MSG_INFO(" Jet pT , eta = " << x->pt() << " , " << x->eta()); + } + } + return StatusCode::SUCCESS; + } -void JetObjectCollectionMaker::specifiedSystematics(const std::set<std::string>& specifiedSystematics, - const ToolHandle<ICPJetUncertaintiesTool>& tool, - std::unordered_map<CP::SystematicSet,CP::SystematicSet>& map, - const std::string& modName, bool isLargeR ) { + std::string JetObjectCollectionMaker::getLargeRModName(const std::string& NPModel) const { + if (NPModel.find("CategoryReduction")!=std::string::npos) return "CategoryReduction_"; + return NPModel+"_"; + } - ///-- MC only --/// - if (m_config->isMC()) { + void JetObjectCollectionMaker::addSystematics(const std::set<std::string>& specifiedSystematics, + const CP::SystematicSet& recommendedSysts, + std::unordered_map<CP::SystematicSet, CP::SystematicSet>& map, + const std::string& modName, bool isLargeR, bool onlyJER) { ///-- Get the recommended systematics from the tool, in std::vector format --/// - const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( tool->recommendedSystematics() ); + const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector(recommendedSysts); + - for (auto s : systList) { + for (const CP::SystematicSet& s : systList) { if (s.size() == 1) { CP::SystematicSet::const_iterator ss = s.begin(); - CP::SystematicSet modSet( modName + ss->name() ); + if(!m_config->getTreeFilter()->filterTree(modName + ss->name())) continue; // Applying tree filter + + if (onlyJER && ss->name().find("JER") == std::string::npos) continue; + + CP::SystematicSet modSet(modName + ss->name()); m_recommendedSystematics.push_back(modSet); - if (!m_config->isSystNominal( m_config->systematics() )) { + if (!m_config->isSystNominal(m_config->systematics())) { if (specifiedSystematics.size() == 0) { - if (!isLargeR) - m_specifiedSystematics.push_back(modSet); - else - m_specifiedSystematicsLargeR.push_back(modSet); - map.insert( std::make_pair(modSet,s) ); - } else if (specifiedSystematics.size() > 0) { - for (auto i : specifiedSystematics) { - if ( i == modSet.name() ) { - if (!isLargeR) - m_specifiedSystematics.push_back(modSet); - else - m_specifiedSystematicsLargeR.push_back(modSet); - map.insert( std::make_pair(modSet,s) ); + if (!isLargeR) m_specifiedSystematics.push_back(modSet); + else m_specifiedSystematicsLargeR.push_back(modSet); + map.insert(std::make_pair(modSet, s)); + } else if (specifiedSystematics.size() > 0) { + for (std::string i : specifiedSystematics) { + TreeFilter filter(i); + if (!filter.filterTree(modSet.name())) { + if (!isLargeR) m_specifiedSystematics.push_back(modSet); + else m_specifiedSystematicsLargeR.push_back(modSet); + map.insert(std::make_pair(modSet, s)); } } } // User has specified a systematic - } // Don't do anything if the user requests nominal only } // size() == 1 -- this means that there is a CP::SystematicVariation } // Loop over systList - } // MC only - m_recommendedSystematics.sort(); - m_recommendedSystematics.unique(); - - m_specifiedSystematics.sort(); - m_specifiedSystematics.unique(); - - m_specifiedSystematicsLargeR.sort(); - m_specifiedSystematicsLargeR.unique(); -} + m_recommendedSystematics.sort(); + m_recommendedSystematics.unique(); + m_specifiedSystematics.sort(); + m_specifiedSystematics.unique(); + m_specifiedSystematicsLargeR.sort(); + m_specifiedSystematicsLargeR.unique(); + } -///-- Don't really need to do this, but would rather stay consistent with JetObjectCollectionMaker --/// -///-- This could be done like all the other xyzObjectCollectionMakers, but would need to change the way execute() works --/// -void JetObjectCollectionMaker::specifiedSystematics( const std::set<std::string>& specifiedSystematics, - const ToolHandle<IJERSmearingTool>& tool, - std::unordered_map<CP::SystematicSet,CP::SystematicSet>& map ) { - ///-- Get the recommended systematics from the tool, in std::vector format --/// - const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( tool->recommendedSystematics() ); + StatusCode JetObjectCollectionMaker::tagNominalLargeRJets() { + const xAOD::JetContainer* xaod_calibrated_jets(nullptr); - for (auto s : systList) { - m_recommendedSystematics.push_back(s); + top::check(evtStore()->retrieve(xaod_calibrated_jets, m_config->sgKeyLargeRJets( + m_nominalSystematicSet.hash())), + "Failed to retrieve nominal calibrated large-R jets"); + for (const xAOD::Jet* jet : *xaod_calibrated_jets) { + top::check(tagLargeRJet(*jet), "Failed to tag large-R jet"); + } + return StatusCode::SUCCESS; + } - ///-- Are we doing JER? Are we only doing Nominal? Did the user specify specific systematics to use? --/// - if (m_doJER) { - if (!m_config->isSystNominal( m_config->systematics() )) { - if (specifiedSystematics.size() == 0) { - m_specifiedSystematics.push_back(s); - map.insert( std::make_pair(s,s) ); - } - if (specifiedSystematics.size() > 0) { - for (auto i : specifiedSystematics) { - if ( i == s.name() ) { - m_specifiedSystematics.push_back(s); - map.insert( std::make_pair(s,s) ); - } - } - } + StatusCode JetObjectCollectionMaker::tagLargeRJet(const xAOD::Jet& jet) { + //decorate with boosted-tagging flags + for (const std::pair<std::string, std::string>& name : m_config->boostedJetTaggers()) { + std::string fullName = name.first + "_" + name.second; +// const Root::TAccept& result = m_boostedJetTaggers[fullName]->tag(jet); + // TAccept has bool operator overloaded, but let's be more explicit in the output to char +// jet.auxdecor<char>("isTagged_" + fullName) = (result ? 1 : 0); + jet.auxdecor<char>("isTagged_" + fullName) = 0; + // for users to extract more detailed tagging result information in custom event saver + //jet.auxdecor<unsigned long>("TAccept_bitmap_" + fullName) = result.getCutResultBitSet().to_ulong(); + } + return StatusCode::SUCCESS; + } + + StatusCode JetObjectCollectionMaker::decorateBJets(xAOD::Jet& jet) { + // initialise decorator and accessor + static SG::AuxElement::Decorator<char> isbjet("IsBjet"); + static const std::string labelB = "PartonTruthLabelID"; + static SG::AuxElement::Accessor<int> truth_label(labelB); + + // Is b-jet if truth label == 5 and pT > 15 GeV + isbjet(jet) = (jet.pt() > 15000. && truth_label(jet) == 5); + + return StatusCode::SUCCESS; + } + + StatusCode JetObjectCollectionMaker::decorateHSJets() { + // initialise decorator + static SG::AuxElement::Decorator<char> isHS("AnalysisTop_isHS"); + + // retrieve small-R jets collection + const xAOD::JetContainer* jets(nullptr); + + top::check(evtStore()->retrieve(jets, + m_config->sgKeyJets()), + "Failed to retrieve small-R jet collection" + m_config->sgKeyJets()); + + // retrieve truth jet collection + const xAOD::JetContainer* truthJets = nullptr; + top::check(evtStore()->retrieve(truthJets, + m_truthJetCollForHS), + "Unable to retrieve truth jet container " + m_truthJetCollForHS + + " - this is needed to define HS jets for application of JVT"); + + for (const auto& jet : *jets) { + bool ishs = false; + for (const auto& tjet : *truthJets) { + if (tjet->p4().DeltaR(jet->p4()) < 0.3 && tjet->pt() > 10e3) ishs = true; } + isHS(*jet) = ishs; } + + return StatusCode::SUCCESS; } - m_recommendedSystematics.sort(); - m_recommendedSystematics.unique(); - m_specifiedSystematics.sort(); - m_specifiedSystematics.unique(); -} - -StatusCode JetObjectCollectionMaker::decorateBJets(xAOD::Jet& jet) { - // initialise decorator and accessor - static SG::AuxElement::Decorator<char> isbjet("IsBjet"); - static const std::string labelB = "HadronConeExclTruthLabelID"; - static SG::AuxElement::Accessor<int> truth_label(labelB); - - // Is b-jet if truth label == 5 and pT > 20 GeV - isbjet(jet) = (jet.pt() > 20000. && truth_label(jet) == 5); - - return StatusCode::SUCCESS; -} - -StatusCode JetObjectCollectionMaker::decorateHSJets() { - // initialise decorator - static SG::AuxElement::Decorator<char> isHS("AnalysisTop_isHS"); - // retrieve small-R jets collection - const xAOD::JetContainer* jets(nullptr); - top::check( evtStore()->retrieve( jets , m_config->sgKeyJets() ) , "Failed to retrieve small-R jet collection"+m_config->sgKeyJets() ); - - // retrieve truth jet collection - const xAOD::JetContainer *truthJets = nullptr; - top::check( evtStore()->retrieve(truthJets, m_truthJetCollForHS) , "Unable to retrieve truth jet container "+m_truthJetCollForHS+" - this is needed to define HS jets for application of JVT" ); - - for(const auto& jet : *jets) { - bool ishs = false; - for(const auto& tjet : *truthJets) { - if (tjet->p4().DeltaR(jet->p4())<0.3 && tjet->pt()>10e3) ishs = true; + StatusCode JetObjectCollectionMaker::decorateMatchedTruth() { + static const SG::AuxElement::Decorator<float> matchedPt("AnalysisTop_MatchedTruthJetPt"); + // retrieve small-R jets collection + const xAOD::JetContainer* jets(nullptr); + + top::check(evtStore()->retrieve(jets, + m_config->sgKeyJets()), + "Failed to retrieve small-R jet collection" + m_config->sgKeyJets()); + + const xAOD::JetContainer* truthJets = nullptr; + top::check(asg::AsgTool::evtStore()->retrieve(truthJets, m_config->sgKeyTruthJets()), "Failed to retrieve the truth jets"); + + const xAOD::Jet* matchedTruthJet = nullptr; + double deltaR(9999); + + for (const auto& jet : *jets) { + // loop over truth jets + for (const auto& iTruthJet : *truthJets) { + TLorentzVector truthJetTLV; + truthJetTLV.SetPtEtaPhiE(iTruthJet->pt(),iTruthJet->eta(),iTruthJet->phi(),iTruthJet->e()); + + // do the matching + if(!matchedTruthJet) { + matchedTruthJet = iTruthJet; + } else { + const double newdR = jet->p4().DeltaR(iTruthJet->p4()); + if(newdR < deltaR) { + deltaR = newdR; + matchedTruthJet = iTruthJet; + } + } + } + if (deltaR > m_config->jetResponseMatchingDeltaR()) { + matchedPt(*jet) = -9999; + continue; + } + if (!matchedTruthJet) { + matchedPt(*jet) = -9999; + continue; + } + matchedPt(*jet) = matchedTruthJet->pt(); } - isHS(*jet)=ishs; + + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} - -void JetObjectCollectionMaker::addCorrelation(const std::string& name, - systMap& map_one, - const std::string& syst_one_name, - systMap& map_two, - const std::string& syst_two_name) { - - std::vector<std::string> directions = {"__1up", "__1down"}; - for (const std::string& d : directions) { - std::string tree_name = name+d; - map_one.insert(std::make_pair(CP::SystematicSet(tree_name), - CP::SystematicSet(syst_one_name+d))); - map_two.insert(std::make_pair(CP::SystematicSet(tree_name), - CP::SystematicSet(syst_two_name+d))); - - m_specifiedSystematics.push_back(tree_name); - m_specifiedSystematicsLargeR.push_back(tree_name); - - } // loop through up and down + StatusCode JetObjectCollectionMaker::decorateDL1(bool trackJets) { + // retrieve small-R jets collection -- either calo or track jets + const xAOD::JetContainer* jets(nullptr); + + if (trackJets) { + top::check(evtStore()->retrieve(jets, + m_config->sgKeyTrackJets()), + "Failed to retrieve track jet collection" + m_config->sgKeyTrackJets()); + } else { + top::check(evtStore()->retrieve(jets, + m_config->sgKeyJets()), + "Failed to retrieve small-R jet collection" + m_config->sgKeyJets()); + } - m_specifiedSystematics.sort(); - m_specifiedSystematics.unique(); - - m_specifiedSystematicsLargeR.sort(); - m_specifiedSystematicsLargeR.unique(); - -} - -void JetObjectCollectionMaker::addCorrelation(const std::string& name, - systMap& map_one, - const std::string& syst_one_name, - std::list<CP::SystematicSet>& jet_specified) { - - map_one.insert(std::make_pair(CP::SystematicSet(name), - CP::SystematicSet(syst_one_name))); + for (const auto& jet : *jets) { + // loop over either calo or track jet btag selection tools to calculate the DL1x scores + const std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool>>& m_btagDecorTools \ + = (trackJets ? m_btagSelToolsDL1Decor_trkJet : m_btagSelToolsDL1Decor); + for (std::pair<std::string, ToolHandle<IBTaggingSelectionTool>> algo : m_btagDecorTools) { + double DL1_weight = -999., dl1_pb = -10., dl1_pc = -10., dl1_pu = -10.; + if (jet->btagging()->pb(algo.first, dl1_pb) + && jet->btagging()->pc(algo.first, dl1_pc) + && jet->btagging()->pu(algo.first, dl1_pu)) { + if (!algo.second->getTaggerWeight(dl1_pb, dl1_pc, dl1_pu, DL1_weight)) { + DL1_weight = -999.; // value for errors from retrieving DL1x weight + } + } else { + DL1_weight = -100.; // value for errors from nonexistence of probabilities + } + DLx.at(algo.first)(*jet) = DL1_weight; + } + } - jet_specified.push_back(name); - - jet_specified.sort(); - jet_specified.unique(); - -} - + return StatusCode::SUCCESS; + } } // namespace top diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MissingETObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MissingETObjectCollectionMaker.cxx index d82fe4cb5f54..33aebfc7886f 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MissingETObjectCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MissingETObjectCollectionMaker.cxx @@ -1,10 +1,11 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ -// $Id: MissingETObjectCollectionMaker.cxx 792986 2017-01-19 11:10:37Z grancagn $ +// $Id: MissingETObjectCollectionMaker.cxx 806051 2017-06-07 00:32:41Z tpelzer $ #include "TopSystematicObjectMaker/MissingETObjectCollectionMaker.h" #include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/TreeFilter.h" #include "TopEvent/EventTools.h" #include "TopEvent/SystematicEvent.h" @@ -20,311 +21,334 @@ #include "xAODCore/ShallowCopy.h" #include "PATInterfaces/SystematicsUtil.h" -namespace top{ - - MissingETObjectCollectionMaker::MissingETObjectCollectionMaker( const std::string& name ) : - asg::AsgTool( name ), - m_config( nullptr ), +namespace top { + MissingETObjectCollectionMaker::MissingETObjectCollectionMaker(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), m_specifiedSystematics(), m_recommendedSystematics(), - - m_MET_core( "setMe" ), - m_MET_map( "setMe" ), + + m_MET_core("setMe"), + m_MET_map("setMe"), m_met_maker("met::METMaker"), - m_met_systematics("met::METSystematicsTool") - { - declareProperty( "config" , m_config ); - declareProperty( "METMaker" , m_met_maker ); - declareProperty( "met_systematics" , m_met_systematics ); + m_met_systematics("met::METSystematicsTool") { + declareProperty("config", m_config); + declareProperty("METMaker", m_met_maker); + declareProperty("met_systematics", m_met_systematics); } - StatusCode MissingETObjectCollectionMaker::initialize() - { - ATH_MSG_INFO(" top::MissingETObjectCollectionMaker initialize" ); + StatusCode MissingETObjectCollectionMaker::initialize() { + ATH_MSG_INFO(" top::MissingETObjectCollectionMaker initialize"); - top::check( m_met_maker.retrieve() , "Failed to retrieve met maker tool" ); - top::check( m_met_systematics.retrieve() , "Failed to retrieve met systematic tool" ); + top::check(m_met_maker.retrieve(), "Failed to retrieve met maker tool"); + top::check(m_met_systematics.retrieve(), "Failed to retrieve met systematic tool"); - std::string jet_collection = m_config->sgKeyJets(); + std::string jet_collection = m_config->sgKeyJetsType(); jet_collection.erase(jet_collection.length() - 4); //erase "Jets" from jet collection name - m_MET_core = "MET_Core_"+jet_collection; - m_MET_map = "METAssoc_"+jet_collection; - + m_MET_core = "MET_Core_" + jet_collection; + m_MET_map = "METAssoc_" + jet_collection; + ///-- Set Systematics Information --/// const std:: string& syststr = m_config->systematics(); - std::set<std::string> syst; + std::set<std::string> syst; - if( !m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)){ + if (!m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)) { bool ok = m_config->getSystematicsList(syststr, syst); if (!ok) { - ATH_MSG_ERROR(" top::MissingETObjectCollectionMaker could not determine systematic list" ); + ATH_MSG_ERROR(" top::MissingETObjectCollectionMaker could not determine systematic list"); return StatusCode::FAILURE; } + //here the idea is that if the user specifies AllXXX, we leave syst as an empty string, so that all recommended CP + // systematics are then used if (m_config->contains(syst, "AllMET")) { syst.clear(); } } - - specifiedSystematics( syst ); - - m_config->systematicsMET( specifiedSystematics() ); + + specifiedSystematics(syst); + + m_config->systematicsMET(specifiedSystematics()); return StatusCode::SUCCESS; } - StatusCode MissingETObjectCollectionMaker::recalculateMET() - { - + StatusCode MissingETObjectCollectionMaker::recalculateMET(bool executeNominal) { // met core contains the soft terms we need to add to our met calculation const xAOD::MissingETContainer* xaod_met_core(nullptr); - top::check( evtStore()->retrieve( xaod_met_core , m_MET_core ) , "Failed to retrieve MET Core" ); + + top::check(evtStore()->retrieve(xaod_met_core, m_MET_core), "Failed to retrieve MET Core"); // This maps the met terms to objects - const xAOD::MissingETAssociationMap* xaod_met_map(nullptr); - top::check( evtStore()->retrieve( xaod_met_map , m_MET_map ) , "Failed to retrieve MET Association Map" ); + const xAOD::MissingETAssociationMap* xaod_met_map(nullptr); + top::check(evtStore()->retrieve(xaod_met_map, m_MET_map), "Failed to retrieve MET Association Map"); - if (!m_config->doLooseTreeOnly()) { + if (m_config->doTightEvents()) { // All the tight systematic events const xAOD::SystematicEventContainer* systEvents(nullptr); - top::check( evtStore()->retrieve(systEvents,m_config->sgKeyTopSystematicEvents()) , "Failed to retrieve TopEvents" ); - - for (auto x : *systEvents) - top::check( recalculateEventMET( x, xaod_met_core, xaod_met_map ), - "Failed to recalculate MET for event"); + if (executeNominal) { + top::check(evtStore()->retrieve(systEvents, + m_config->sgKeyTopSystematicEvents() + "Nominal"), + "Failed to retrieve nominal TopEvents"); + } else { + top::check(evtStore()->retrieve(systEvents, + m_config->sgKeyTopSystematicEvents()), "Failed to retrieve TopEvents"); + } + for (auto x : *systEvents) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(x->hashValue()))) continue; + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(x->hashValue()))) continue; + top::check(recalculateEventMET(x, xaod_met_core, xaod_met_map), "Failed to recalculate MET for event"); + if(m_config->writeMETBuiltWithLooseObjects()) top::check(recalculateEventMET(x, xaod_met_core, xaod_met_map, true, "WithLooseObjects"), "Failed to recalculate MET using loose leptons for event"); + } } // tight events if (m_config->doLooseEvents()) { // All the loose systematic events const xAOD::SystematicEventContainer* systEventsLoose(nullptr); - top::check( evtStore()->retrieve(systEventsLoose,m_config->sgKeyTopSystematicEventsLoose()) , "Failed to retrieve TopEventsLoose" ); + if (executeNominal) { + top::check(evtStore()->retrieve(systEventsLoose, + m_config->sgKeyTopSystematicEventsLoose() + "Nominal"), + "Failed to retrieve nominal TopEventsLoose"); + } else { + top::check(evtStore()->retrieve(systEventsLoose, + m_config->sgKeyTopSystematicEventsLoose()), + "Failed to retrieve TopEventsLoose"); + } - for (auto x : *systEventsLoose) - top::check( recalculateEventMET( x, xaod_met_core, xaod_met_map ), - "Failed to recalculate MET for loose event"); + for (auto x : *systEventsLoose) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(x->hashValue()))) continue; + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(x->hashValue()))) continue; + top::check(recalculateEventMET(x, xaod_met_core, xaod_met_map), "Failed to recalculate MET for loose event"); + if(m_config->writeMETBuiltWithLooseObjects()) top::check(recalculateEventMET(x, xaod_met_core, xaod_met_map, true, "WithLooseObjects"), "Failed to recalculate MET using loose leptons for event"); + } } // Loose events return StatusCode::SUCCESS; } - StatusCode MissingETObjectCollectionMaker::recalculateEventMET(xAOD::SystematicEvent* event, - const xAOD::MissingETContainer* xaod_met_core, - const xAOD::MissingETAssociationMap* xaod_met_map) { - - // decoration for objects that pass pre OR selection - std::string passPreORSelection = "passPreORSelection"; - - bool is_loose_event = (event->isLooseEvent() == 1 ? true : false); - - // default behaviour for top analysis - use the "Tight" definitions - bool looseLeptonOR(is_loose_event); - if (m_config->doOverlapRemovalOnLooseLeptonDef()) { - looseLeptonOR = true; - // change decoration we check - passPreORSelection = "passPreORSelectionLoose"; - } - - std::size_t hash = event->hashValue(); - - // Make a new MET container that we are going to use - xAOD::MissingETContainer * new_met_container = new xAOD::MissingETContainer(); - xAOD::MissingETAuxContainer * new_met_aux_container = new xAOD::MissingETAuxContainer(); - new_met_container->setStore(new_met_aux_container); - - // Reset all the met map associations - xaod_met_map->resetObjSelectionFlags(); - - // Apparently we need to add objects to the METMaker in a specific order - // Start by retrieving jet container, we need it to perform e-jet ghost-matching - xAOD::JetContainer* xaod_jet(nullptr); - top::check( evtStore()->retrieve( xaod_jet , m_config->sgKeyJets(hash,looseLeptonOR) ), "Failed to retrieve Jets" ); - // 1. Electrons - const xAOD::ElectronContainer* xaod_el(nullptr); - if(m_config->useElectrons()){ - // Get all calibrated electrons - top::check( evtStore()->retrieve( xaod_el , m_config->sgKeyElectrons(hash) ), "Failed to retrieve Electrons" ); - - // Add those that pass pre-overlap removal selection to met_electrons - ConstDataVector<xAOD::ElectronContainer> met_electrons(SG::VIEW_ELEMENTS); - for( const auto& el: *xaod_el ) - if ( el->isAvailable<char>(passPreORSelection) - && el->auxdata<char>(passPreORSelection) == 1 ) - met_electrons.push_back(el); - - // Recalculate electron MET term using electrons that pass overlap removal - top::check( m_met_maker->rebuildMET("RefEle", xAOD::Type::Electron, - new_met_container, met_electrons.asDataVector(), - xaod_met_map), "Failed to rebuild electron MET term"); - } - - // 2. Photons - if(m_config->usePhotons()){ - - // Get calibrated photons - const xAOD::PhotonContainer* xaod_photon(nullptr); - top::check( evtStore()->retrieve( xaod_photon , m_config->sgKeyPhotons(hash) ), "Failed to retrieve Photons" ); - - // Add those that pass pre-overlap removal to met_photons - ConstDataVector<xAOD::PhotonContainer> met_photons(SG::VIEW_ELEMENTS); - for( const auto& photon: *xaod_photon ) - if ( photon->isAvailable<char>(passPreORSelection) - && photon->auxdata<char>(passPreORSelection) == 1 ) - met_photons.push_back(photon); - - top::check( m_met_maker->rebuildMET("RefPhoton", xAOD::Type::Photon, - new_met_container, met_photons.asDataVector(), - xaod_met_map), "Failed to rebuild photon MET term" ); - } - - // 3. Taus - if(m_config->useTaus()){ - - // Get calibrated taus - const xAOD::TauJetContainer* xaod_tau(nullptr); - top::check( evtStore()->retrieve( xaod_tau , m_config->sgKeyTaus(hash) ), "Failed to retrieve Taus" ); - - // Add those that pass pre-overlap removal to met_taus - ConstDataVector<xAOD::TauJetContainer> met_taus(SG::VIEW_ELEMENTS); - for( const auto& tau: *xaod_tau ) - if ( tau->isAvailable<char>(passPreORSelection) - && tau->auxdata<char>(passPreORSelection) == 1 ) - met_taus.push_back(tau); - - top::check( m_met_maker->rebuildMET("RefTau", xAOD::Type::Tau, - new_met_container, met_taus.asDataVector(), - xaod_met_map), "Failed to rebuild tau MET term" ); - } - - // 4. Muons - const xAOD::MuonContainer* xaod_mu(nullptr); // Need these for ghost matching - if(m_config->useMuons()){ - // Get calibrated muons - top::check( evtStore()->retrieve( xaod_mu , m_config->sgKeyMuons(hash) ), "Failed to retrieve Muons" ); - - // Add those that pass pre-overlap removal to met_muons - ConstDataVector<xAOD::MuonContainer> met_muons(SG::VIEW_ELEMENTS); - for( const auto& mu: *xaod_mu ) - if ( mu->isAvailable<char>(passPreORSelection) - && mu->auxdata<char>(passPreORSelection) == 1 ) - met_muons.push_back(mu); - - // Recalculate muon MET term using muons that pass overlap removal - top::check( m_met_maker->rebuildMET("RefMuon", xAOD::Type::Muon, - new_met_container, met_muons.asDataVector(), - xaod_met_map), "Failed to rebuild muon MET term"); - - // Muon-jet ghost association - // performed after muon handing to METUtility, but before jets - if (xaod_mu) { - met::addGhostMuonsToJets(*xaod_mu, *xaod_jet); - } - } - - - // 5. Jets - // We do not perfom any selection on jets here. Give them all to the METMaker, it does its own thing - top::check( m_met_maker->rebuildJetMET("RefJet", "SoftClus", "PVSoftTrk", - new_met_container, xaod_jet, - xaod_met_core, xaod_met_map, - m_config->doJVTinMET() ), "Failed to rebuild jet MET term" ); - - - ///-- John thinks that the systematics go here --/// - ///-- This may well be wrong --/// - - for (auto systematic : m_specifiedSystematics) { - if (systematic.hash() == event->hashValue() && systematic.hash() != m_config->nominalHashValue() ){ - ///-- Tell tool which systematic to use --/// - top::check( m_met_systematics->applySystematicVariation( systematic ) , "Failed to applySystematicVariation" ); - - // code lifted and modified from: - // https://svnweb.cern.ch/trac/atlasoff/browser/Reconstruction/MET/METUtilities/tags/METUtilities-00-01-43/util/example_METMaker_METSystematicsTool.cxx - - //get the soft cluster term, and applyCorrection - xAOD::MissingET * softClusMet = (*new_met_container)["SoftClus"]; - if (softClusMet != nullptr) { //check we retrieved the clust term - top::check( m_met_systematics->applyCorrection(*softClusMet) , "Failed to applyCorrection" ); - } - - xAOD::MissingET * softTrkMet = (*new_met_container)["PVSoftTrk"]; - if (softTrkMet != nullptr) { //check we retrieved the soft trk - top::check( m_met_systematics->applyCorrection(*softTrkMet) , "Failed to applyCorrection" ); - } - - } - } - - /************************************************************ - We could use this to build TrackMET but should be careful as we would probably - want a different met_container and it shouldn't contain photons (and I don't think taus either...) - This function should NOT be used with the previous rebuildJetMET (one or the other) - - top::check( m_met_maker->rebuildTrackMET("RefJetTrk", "PVSoftTrk", - new_met_container, xaod_jet, - xaod_met_core, xaod_met_map, - false), "Failed to rebuild track MET term" ); - ************************************************************/ - - - // This will sum up all the contributions we've made so far e.g. - // Total MET = RefEle + RefPhoton + RefTau + RefMuon + RefJet + PVSoftTrk (Track Soft Term) - - top::check( m_met_maker->buildMETSum("FinalTrk" , new_met_container, MissingETBase::Source::Track), - "Failed to rebuild Final Track MET"); - - /************************************************************ - // We are only going to build a single MET Sum now for clarity. The final argument is the soft term we - // want to use. The recommended one is the track soft term (TST) as above. - - top::check( m_met_maker->buildMETSum("FinalClus", new_met_container, MissingETBase::Source::EMTopo), - "Failed to rebuild Final Cluster MET"); - ************************************************************/ - - // Save corrected xAOD Container to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyMissingEt(hash); - if( is_loose_event ) outputSGKey = m_config->sgKeyMissingEtLoose(hash); - std::string outputSGKeyAux = outputSGKey + "Aux."; - - xAOD::TReturnCode save = evtStore()->tds()->record( new_met_container, outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( new_met_aux_container, outputSGKeyAux ); - - if( !save || !saveAux ){ - return StatusCode::FAILURE; - } + StatusCode MissingETObjectCollectionMaker::recalculateEventMET(const xAOD::SystematicEvent* event, + const xAOD::MissingETContainer* xaod_met_core, + const xAOD::MissingETAssociationMap* xaod_met_map, + bool forceUseLooseObjects, + std::string outputContainerSuffix) { +// // decoration for objects that pass pre OR selection +// std::string passPreORSelection = "passPreORSelection"; +// +// bool is_loose_event = (event->isLooseEvent() == 1 ? true : false); +// +// // default behaviour for top analysis - use the "Tight" definitions +// bool looseLeptonOR(is_loose_event); +// if (m_config->doOverlapRemovalOnLooseLeptonDef() || (is_loose_event && m_config->useLooseObjectsInMETInLooseTree()) || (!is_loose_event && m_config->useLooseObjectsInMETInNominalTree()) || forceUseLooseObjects) { +// looseLeptonOR = true; +// // change decoration we check +// passPreORSelection = "passPreORSelectionLoose"; +// } +// +// std::size_t hash = event->hashValue(); +// +// // Make a new MET container that we are going to use +// xAOD::MissingETContainer* new_met_container = new xAOD::MissingETContainer(); +// xAOD::MissingETAuxContainer* new_met_aux_container = new xAOD::MissingETAuxContainer(); +// new_met_container->setStore(new_met_aux_container); +// +// // Reset all the met map associations +// //xaod_met_map->resetObjSelectionFlags(); +// +// // Apparently we need to add objects to the METMaker in a specific order +// // Start by retrieving jet container, we need it to perform e-jet ghost-matching +// xAOD::JetContainer* xaod_jet(nullptr); +// top::check(evtStore()->retrieve(xaod_jet, m_config->sgKeyJets(hash, looseLeptonOR)), "Failed to retrieve Jets"); +// // 1. Electrons +// const xAOD::ElectronContainer* xaod_el(nullptr); +// if (m_config->useElectrons()) { +// // Get all calibrated electrons +// top::check(evtStore()->retrieve(xaod_el, m_config->sgKeyElectrons(hash)), "Failed to retrieve Electrons"); +// +// // Add those that pass pre-overlap removal selection to met_electrons +// ConstDataVector<xAOD::ElectronContainer> met_electrons(SG::VIEW_ELEMENTS); +// for (const auto& el: *xaod_el) +// if (el->isAvailable<char>(passPreORSelection) +// && el->auxdata<char>(passPreORSelection) == 1) met_electrons.push_back(el); +// +// // Recalculate electron MET term using electrons that pass overlap removal +// top::check(m_met_maker->rebuildMET("RefEle", xAOD::Type::Electron, +// new_met_container, met_electrons.asDataVector(), +// xaod_met_map), "Failed to rebuild electron MET term"); +// } +// +// // 2. Photons +// if (m_config->usePhotons()) { +// // Get calibrated photons +// const xAOD::PhotonContainer* xaod_photon(nullptr); +// top::check(evtStore()->retrieve(xaod_photon, m_config->sgKeyPhotons(hash)), "Failed to retrieve Photons"); +// +// // Add those that pass pre-overlap removal to met_photons +// ConstDataVector<xAOD::PhotonContainer> met_photons(SG::VIEW_ELEMENTS); +// for (const auto& photon: *xaod_photon) +// if (photon->isAvailable<char>(passPreORSelection) +// && photon->auxdata<char>(passPreORSelection) == 1) met_photons.push_back(photon); +// +// top::check(m_met_maker->rebuildMET("RefPhoton", xAOD::Type::Photon, +// new_met_container, met_photons.asDataVector(), +// xaod_met_map), "Failed to rebuild photon MET term"); +// } +// +// // 3. Taus +// if (m_config->useTaus()) { +// // Get calibrated taus +// const xAOD::TauJetContainer* xaod_tau(nullptr); +// top::check(evtStore()->retrieve(xaod_tau, m_config->sgKeyTaus(hash)), "Failed to retrieve Taus"); +// +// // Add those that pass pre-overlap removal to met_taus +// ConstDataVector<xAOD::TauJetContainer> met_taus(SG::VIEW_ELEMENTS); +// for (const auto& tau: *xaod_tau) +// if (tau->isAvailable<char>(passPreORSelection) +// && tau->auxdata<char>(passPreORSelection) == 1) met_taus.push_back(tau); +// +// top::check(m_met_maker->rebuildMET("RefTau", xAOD::Type::Tau, +// new_met_container, met_taus.asDataVector(), +// xaod_met_map), "Failed to rebuild tau MET term"); +// } +// +// // 4. Muons +// const xAOD::MuonContainer* xaod_mu(nullptr); // Need these for ghost matching +// if (m_config->useMuons()) { +// // Get calibrated muons +// top::check(evtStore()->retrieve(xaod_mu, m_config->sgKeyMuons(hash)), "Failed to retrieve Muons"); +// +// // Add those that pass pre-overlap removal to met_muons +// ConstDataVector<xAOD::MuonContainer> met_muons(SG::VIEW_ELEMENTS); +// for (const auto& mu: *xaod_mu) +// if (mu->isAvailable<char>(passPreORSelection) +// && mu->auxdata<char>(passPreORSelection) == 1) met_muons.push_back(mu); +// +// // Recalculate muon MET term using muons that pass overlap removal +// top::check(m_met_maker->rebuildMET("RefMuon", xAOD::Type::Muon, +// new_met_container, met_muons.asDataVector(), +// xaod_met_map), "Failed to rebuild muon MET term"); +// +// // Muon-jet ghost association +// // performed after muon handing to METUtility, but before jets +// if (xaod_mu) { +// met::addGhostMuonsToJets(*xaod_mu, *xaod_jet); +// } +// } +// else +// { +// ConstDataVector<xAOD::MuonContainer> met_muons(SG::VIEW_ELEMENTS); +// top::check(m_met_maker->rebuildMET("RefMuon", xAOD::Type::Muon, +// new_met_container, met_muons.asDataVector(), +// xaod_met_map), "Failed to rebuild muon MET term"); +// } +// +// +// // 5. Jets +// // We do not perfom any selection on jets here. Give them all to the METMaker, it does its own thing +// top::check(m_met_maker->rebuildJetMET("RefJet", "SoftClus", "PVSoftTrk", +// new_met_container, xaod_jet, +// xaod_met_core, xaod_met_map, +// m_config->doJVTinMET()), "Failed to rebuild jet MET term"); +// +// +// ///-- John thinks that the systematics go here --/// +// ///-- This may well be wrong --/// +// +// for (auto systematic : m_specifiedSystematics) { +// if (systematic.hash() == event->hashValue() && systematic.hash() != m_config->nominalHashValue()) { +// ///-- Tell tool which systematic to use --/// +// top::check(m_met_systematics->applySystematicVariation(systematic), "Failed to applySystematicVariation"); +// +// // code lifted and modified from: +// // https://svnweb.cern.ch/trac/atlasoff/browser/Reconstruction/MET/METUtilities/tags/METUtilities-00-01-43/util/example_METMaker_METSystematicsTool.cxx +// +// //get the soft cluster term, and applyCorrection +// xAOD::MissingET* softClusMet = (*new_met_container)["SoftClus"]; +// if (softClusMet != nullptr) { //check we retrieved the clust term +// top::check(m_met_systematics->applyCorrection(*softClusMet), "Failed to applyCorrection"); +// } +// +// xAOD::MissingET* softTrkMet = (*new_met_container)["PVSoftTrk"]; +// if (softTrkMet != nullptr) { //check we retrieved the soft trk +// top::check(m_met_systematics->applyCorrection(*softTrkMet), "Failed to applyCorrection"); +// } +// } +// } +// +// /************************************************************ +// We could use this to build TrackMET but should be careful as we would probably +// want a different met_container and it shouldn't contain photons (and I don't think taus either...) +// This function should NOT be used with the previous rebuildJetMET (one or the other) +// +// top::check( m_met_maker->rebuildTrackMET("RefJetTrk", "PVSoftTrk", +// new_met_container, xaod_jet, +// xaod_met_core, xaod_met_map, +// false), "Failed to rebuild track MET term" ); +// ************************************************************/ +// +// +// // This will sum up all the contributions we've made so far e.g. +// // Total MET = RefEle + RefPhoton + RefTau + RefMuon + RefJet + PVSoftTrk (Track Soft Term) +// +// top::check(m_met_maker->buildMETSum("FinalTrk", new_met_container, MissingETBase::Source::Track), +// "Failed to rebuild Final Track MET"); +// +// /************************************************************ +// // We are only going to build a single MET Sum now for clarity. The final argument is the soft term we +// // want to use. The recommended one is the track soft term (TST) as above. +// +// top::check( m_met_maker->buildMETSum("FinalClus", new_met_container, MissingETBase::Source::EMTopo), +// "Failed to rebuild Final Cluster MET"); +// ************************************************************/ +// +// // Save corrected xAOD Container to StoreGate / TStore +// std::string outputSGKey = m_config->sgKeyMissingEt(hash); +// if (is_loose_event) outputSGKey = m_config->sgKeyMissingEtLoose(hash); +// +// outputSGKey+=outputContainerSuffix; +// std::string outputSGKeyAux = outputSGKey + "Aux."; +// +// xAOD::TReturnCode save = evtStore()->tds()->record(new_met_container, outputSGKey); +// xAOD::TReturnCode saveAux = evtStore()->tds()->record(new_met_aux_container, outputSGKeyAux); +// +// if (!save || !saveAux) { +// return StatusCode::FAILURE; +// } return StatusCode::SUCCESS; - } - - - void MissingETObjectCollectionMaker::specifiedSystematics( const std::set<std::string>& specifiedSystematics ) - { + + void MissingETObjectCollectionMaker::specifiedSystematics(const std::set<std::string>& specifiedSystematics) { ///-- Get the recommended systematics from the tool, in std::vector format --/// - const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( m_met_systematics->recommendedSystematics() ); - + const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( + m_met_systematics->recommendedSystematics()); + for (auto s : systList) { + if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter + ///-- Recommendation is to use soft track terms and not soft calo terms --/// ///-- Soft calo systematics are irrelevant, let's ignore them --/// if (s.name().find("SoftCalo") == std::string::npos) { - m_recommendedSystematics.push_back(s); if (s.name() == "") { m_specifiedSystematics.push_back(s); } - + ///-- MC only --/// if (m_config->isMC()) { ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// - if (!m_config->isSystNominal( m_config->systematics() )) { + if (!m_config->isSystNominal(m_config->systematics())) { if (specifiedSystematics.size() == 0) { m_specifiedSystematics.push_back(s); } - if (specifiedSystematics.size() > 0) { + if (specifiedSystematics.size() > 0) { for (auto i : specifiedSystematics) { - if ( i == s.name() ) { - m_specifiedSystematics.push_back(s); + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematics.push_back(s); } } } @@ -332,11 +356,9 @@ namespace top{ } } } - m_recommendedSystematics.sort(); + m_recommendedSystematics.sort(); m_recommendedSystematics.unique(); m_specifiedSystematics.sort(); - m_specifiedSystematics.unique(); - - } - + m_specifiedSystematics.unique(); + } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MuonObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MuonObjectCollectionMaker.cxx index 737654d44923..54744c284b20 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MuonObjectCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MuonObjectCollectionMaker.cxx @@ -1,12 +1,14 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ -// $Id: MuonObjectCollectionMaker.cxx 799839 2017-03-08 11:07:28Z grancagn $ +// $Id: MuonObjectCollectionMaker.cxx 810751 2017-09-29 14:41:39Z iconnell $ #include "TopSystematicObjectMaker/MuonObjectCollectionMaker.h" #include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/TreeFilter.h" #include "TopEvent/EventTools.h" +#include "AthContainers/AuxElement.h" #include "xAODEventInfo/EventInfo.h" #include "xAODMuon/MuonContainer.h" #include "xAODMuon/MuonAuxContainer.h" @@ -15,205 +17,380 @@ #include "xAODTracking/TrackParticlexAODHelpers.h" #include "PATInterfaces/SystematicsUtil.h" -namespace top{ - - MuonObjectCollectionMaker::MuonObjectCollectionMaker( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + MuonObjectCollectionMaker::MuonObjectCollectionMaker(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), m_specifiedSystematics(), m_recommendedSystematics(), - m_calibrationTool("CP::MuonCalibrationAndSmearingTool"), - m_isolationTool_LooseTrackOnly("CP::IsolationTool_LooseTrackOnly"), - m_isolationTool_Loose("CP::IsolationTool_Loose"), - m_isolationTool_Gradient("CP::IsolationTool_Gradient"), - m_isolationTool_GradientLoose("CP::IsolationTool_GradientLoose"), - m_isolationTool_FixedCutTightTrackOnly("CP::IsolationTool_FixedCutTightTrackOnly"), - m_isolationTool_FixedCutLoose("CP::IsolationTool_FixedCutLoose"), - m_muonSelectionToolVeryLooseVeto("CP::MuonSelectionToolVeryLooseVeto") - { - declareProperty( "config" , m_config ); - - declareProperty( "MuonCalibrationAndSmearingTool" , m_calibrationTool ); - declareProperty( "IsolationTool_LooseTrackOnly" , m_isolationTool_LooseTrackOnly ); - declareProperty( "IsolationTool_Loose" , m_isolationTool_Loose ); - declareProperty( "IsolationTool_Gradient" , m_isolationTool_Gradient ); - declareProperty( "IsolationTool_GradientLoose" , m_isolationTool_GradientLoose ); - declareProperty( "IsolationTool_FixedCutTightTrackOnly" , m_isolationTool_FixedCutTightTrackOnly ); - declareProperty( "IsolationTool_FixedCutLoose" , m_isolationTool_FixedCutLoose ); - declareProperty( "MuonSelectionToolVeryLooseVeto" , m_muonSelectionToolVeryLooseVeto ); + m_calibrationPeriodTool("CP::MuonCalibrationPeriodTool"), + m_isolationTool_FCTight("CP::IsolationTool_FCTight"), + m_isolationTool_FCLoose("CP::IsolationTool_FCLoose"), + m_isolationTool_FCTightTrackOnly("CP::IsolationTool_FCTightTrackOnly"), + m_isolationTool_FCTightTrackOnly_FixedRad("CP::IsolationTool_FCTightTrackOnly_FixedRad"), + m_isolationTool_FCLoose_FixedRad("CP::IsolationTool_FCLoose_FixedRad"), + m_isolationTool_FCTight_FixedRad("CP::IsolationTool_FCTight_FixedRad"), + m_isolationTool_FixedCutPflowTight("CP::IsolationTool_FixedCutPflowTight"), + m_isolationTool_FixedCutPflowLoose("CP::IsolationTool_FixedCutPflowLoose"), + + m_isolationTool_PflowTight_FixedRad("CP::IsolationTool_PflowTight_FixedRad"), + m_isolationTool_PflowLoose_FixedRad("CP::IsolationTool_PflowLoose_FixedRad"), + m_isolationTool_PflowTight_VarRad("CP::IsolationTool_PflowTight_VarRad"), + m_isolationTool_PflowLoose_VarRad("CP::IsolationTool_PflowLoose_VarRad"), + m_isolationTool_HighPtTrackOnly("CP::IsolationTool_HighPtTrackOnly"), + m_isolationTool_TightTrackOnly_VarRad("CP::IsolationTool_TightTrackOnly_VarRad"), + m_isolationTool_TightTrackOnly_FixedRad("CP::IsolationTool_TightTrackOnly_FixedRad"), + m_isolationTool_PLVTight("CP::IsolationTool_PLVTight"), + m_isolationTool_PLVLoose("CP::IsolationTool_PLVLoose"), + m_isolationTool_Tight_VarRad("CP::IsolationTool_Tight_VarRad"), + m_isolationTool_Tight_FixedRad("CP::IsolationTool_Tight_FixedRad"), + m_isolationTool_Loose_VarRad("CP::IsolationTool_Loose_VarRad"), + m_isolationTool_Loose_FixedRad("CP::IsolationTool_Loose_FixedRad"), +// m_isolationTool_LowPtPLV("CP::IsolationTool_LowPtPLV"), + + m_muonSelectionToolVeryLooseVeto("CP::MuonSelectionToolVeryLooseVeto") { + declareProperty("config", m_config); + + declareProperty("MuonCalibrationPeriodTool", m_calibrationPeriodTool); + declareProperty("IsolationTool_FCTight", m_isolationTool_FCTight); + declareProperty("IsolationTool_FCLoose", m_isolationTool_FCLoose); + declareProperty("IsolationTool_FCTightTrackOnly", m_isolationTool_FCTightTrackOnly); + declareProperty("IsolationTool_FCTightTrackOnly_FixedRad", m_isolationTool_FCTightTrackOnly_FixedRad); + declareProperty("IsolationTool_FCLoose_FixedRad", m_isolationTool_FCLoose_FixedRad); + declareProperty("IsolationTool_FCTight_FixedRad", m_isolationTool_FCTight_FixedRad); + declareProperty("IsolationTool_FixedCutPflowTight", m_isolationTool_FixedCutPflowTight); + declareProperty("IsolationTool_FixedCutPflowLoose", m_isolationTool_FixedCutPflowLoose); + declareProperty("IsolationTool_PflowTight_FixedRad", m_isolationTool_PflowTight_FixedRad); + declareProperty("IsolationTool_PflowLoose_FixedRad", m_isolationTool_PflowLoose_FixedRad); + declareProperty("IsolationTool_PflowTight_VarRad", m_isolationTool_PflowTight_VarRad); + declareProperty("IsolationTool_PflowLoose_VarRad", m_isolationTool_PflowLoose_VarRad); + declareProperty("IsolationTool_HighPtTrackOnly", m_isolationTool_HighPtTrackOnly); + declareProperty("IsolationTool_TightTrackOnly_VarRad", m_isolationTool_TightTrackOnly_VarRad); + declareProperty("IsolationTool_TightTrackOnly_FixedRad", m_isolationTool_TightTrackOnly_FixedRad); + declareProperty("IsolationTool_PLVTight", m_isolationTool_PLVTight); + declareProperty("IsolationTool_PLVLoose", m_isolationTool_PLVLoose); + declareProperty("IsolationTool_Tight_VarRad", m_isolationTool_Tight_VarRad); + declareProperty("IsolationTool_Tight_FixedRad", m_isolationTool_Tight_FixedRad); + declareProperty("IsolationTool_Loose_VarRad", m_isolationTool_Loose_VarRad); + declareProperty("IsolationTool_Loose_FixedRad", m_isolationTool_Loose_FixedRad); +// declareProperty("IsolationTool_LowPtPLV", m_isolationTool_LowPtPLV); + declareProperty("MuonSelectionToolVeryLooseVeto", m_muonSelectionToolVeryLooseVeto); } - StatusCode MuonObjectCollectionMaker::initialize() - { - ATH_MSG_INFO(" top::MuonObjectCollectionMaker initialize" ); - - top::check( m_calibrationTool.retrieve() , "Failed to retrieve muon calibration tool" ); - top::check( m_isolationTool_LooseTrackOnly.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_Loose.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_Gradient.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_GradientLoose.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_FixedCutTightTrackOnly.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_isolationTool_FixedCutLoose.retrieve() , "Failed to retrieve Isolation Tool" ); - top::check( m_muonSelectionToolVeryLooseVeto.retrieve() , "Failed to retrieve Selection Tool" ); + StatusCode MuonObjectCollectionMaker::initialize() { + ATH_MSG_INFO(" top::MuonObjectCollectionMaker initialize"); + + top::check(m_calibrationPeriodTool.retrieve(), "Failed to retrieve muon calibration tool"); + top::check(m_isolationTool_FCTight.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FCLoose.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FCTightTrackOnly.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FCTightTrackOnly_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FCLoose_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FCTight_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FixedCutPflowTight.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_FixedCutPflowLoose.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PflowTight_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PflowLoose_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PflowTight_VarRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PflowLoose_VarRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_HighPtTrackOnly.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_TightTrackOnly_VarRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_TightTrackOnly_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PLVTight.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_PLVLoose.retrieve(), "Failed to retrieve Isolation Tool"); +// top::check(m_isolationTool_LowPtPLV.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_Tight_VarRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_Tight_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_Loose_VarRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_isolationTool_Loose_FixedRad.retrieve(), "Failed to retrieve Isolation Tool"); + top::check(m_muonSelectionToolVeryLooseVeto.retrieve(), "Failed to retrieve Selection Tool"); ///-- Set Systematics Information --/// const std:: string& syststr = m_config->systematics(); - std::set<std::string> syst; + std::set<std::string> syst; - if( !m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)){ + if (!m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)) { bool ok = m_config->getSystematicsList(syststr, syst); if (!ok) { - ATH_MSG_ERROR(" top::MuonObjectCollectionMaker could not determine systematic list" ); - return StatusCode::FAILURE; + ATH_MSG_ERROR(" top::MuonObjectCollectionMaker could not determine systematic list"); + return StatusCode::FAILURE; } + //here the idea is that if the user specifies AllXXX, we leave syst as an empty string, so that all recommended CP + // systematics are then used if (m_config->contains(syst, "AllMuons")) { - syst.clear(); + syst.clear(); } } - - specifiedSystematics( syst ); - - m_config->systematicsMuons( specifiedSystematics() ); - - ATH_MSG_INFO(" top::MuonObjectCollectionMaker completed initialize" ); + + specifiedSystematics(syst); + + m_config->systematicsMuons(specifiedSystematics()); + + m_isFirstEvent = true; + + ATH_MSG_INFO(" top::MuonObjectCollectionMaker completed initialize"); return StatusCode::SUCCESS; } - - StatusCode MuonObjectCollectionMaker::execute() - { + + StatusCode MuonObjectCollectionMaker::execute(bool executeNominal) { + + static const SG::AuxElement::ConstAccessor<float> ptvarcone30_TightTTVA_pt1000("ptvarcone30_TightTTVA_pt1000"); + static const SG::AuxElement::ConstAccessor<float> ptcone20_TightTTVA_pt1000("ptcone20_TightTTVA_pt1000"); + static const SG::AuxElement::ConstAccessor<float> ptcone20_TightTTVA_pt500("ptcone20_TightTTVA_pt500"); + static const SG::AuxElement::ConstAccessor<float> ptvarcone30_TightTTVA_pt500("ptvarcone30_TightTTVA_pt500"); + static const SG::AuxElement::ConstAccessor<float> neflowisol20("neflowisol20"); + static const SG::AuxElement::ConstAccessor<float> ptvarcone30_TightTTVALooseCone_pt1000("ptvarcone30_TightTTVALooseCone_pt1000"); + static const SG::AuxElement::ConstAccessor<int> chamberIndex("chamberIndex"); + static const SG::AuxElement::ConstAccessor<short> PLV_TrackJetNTrack("PromptLeptonInput_TrackJetNTrack"); + static const SG::AuxElement::ConstAccessor<float> PLV_DRlj("PromptLeptonInput_DRlj"); + static const SG::AuxElement::ConstAccessor<float> PLV_PtRel("PromptLeptonInput_PtRel"); + static const SG::AuxElement::ConstAccessor<float> PLV_PtFrac("PromptLeptonInput_PtFrac"); + static const SG::AuxElement::ConstAccessor<float> PLV_PromptLeptonVeto("PromptLeptonVeto"); +// static SG::AuxElement::Decorator<float> byhand_LowPtPLV("LowPtPLV"); const xAOD::EventInfo* eventInfo(nullptr); - top::check( evtStore()->retrieve( eventInfo, m_config->sgKeyEventInfo() ), "Failed to retrieve EventInfo"); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); float beam_pos_sigma_x = eventInfo->beamPosSigmaX(); float beam_pos_sigma_y = eventInfo->beamPosSigmaY(); float beam_pos_sigma_xy = eventInfo->beamPosSigmaXY(); - ///-- Get base muons and tracks from xAOD --/// + ///-- Get base muons and tracks from xAOD --/// const xAOD::MuonContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyMuons() ) , "Failed to retrieve Muons" ); - + top::check(evtStore()->retrieve(xaod, m_config->sgKeyMuons()), "Failed to retrieve Muons"); + ///-- Loop over all systematics --/// - for( auto systematic : m_specifiedSystematics ){ + for (auto systematic : m_specifiedSystematics) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; ///-- Tell tool which systematic to use --/// - top::check( m_calibrationTool->applySystematicVariation( systematic ) , "Failed to applySystematicVariation" ); - + top::check(m_calibrationPeriodTool->applySystematicVariation(systematic), "Failed to applySystematicVariation"); + ///-- Shallow copy of the xAOD --/// - std::pair< xAOD::MuonContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *xaod ); - + std::pair< xAOD::MuonContainer*, + xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer(*xaod); + ///-- Loop over the xAOD Container and apply corrections--/// - for( auto muon : *(shallow_xaod_copy.first) ){ + for (auto muon : *(shallow_xaod_copy.first)) { + + ///-- Check if chamberIndex is Available if UseMVALowPt is On in order to print some useful message before the crash + if ( m_isFirstEvent ) { + if ( (m_config->muonUseMVALowPt() || m_config->muonUseMVALowPtLoose() || m_config->softmuonUseMVALowPt()) && !chamberIndex.isAvailable(*muon) ) { + ATH_MSG_ERROR("MuonSegmentsAux.chamberIndex is not available in yout derivation so UseMVALowPt cannot be performed."); + ATH_MSG_ERROR("Please turn OFF UseMVALowPt or use more recent p-tag"); + ATH_MSG_ERROR("AnalysisTop will crash soon..."); + throw std::runtime_error("Missing MuonSegmentsAux.chamberIndex variable"); + } + m_isFirstEvent = false; + } - ///-- Apply momentum correction --/// + ///-- Apply momentum correction --/// if (muon->primaryTrackParticle()) { - top::check( m_calibrationTool->applyCorrection( *muon ) , "Failed to applyCorrection" ); - + top::check(m_calibrationPeriodTool->applyCorrection(*muon), "Failed to applyCorrection"); + // don't do the decorations unless the muons are at least Loose // this is because it may fail if the muons are at just VeryLoose if (m_muonSelectionToolVeryLooseVeto->accept(*muon)) { - double d0sig = xAOD::TrackingHelpers::d0significance( muon->primaryTrackParticle(), - beam_pos_sigma_x, - beam_pos_sigma_y, - beam_pos_sigma_xy ); + double d0sig = xAOD::TrackingHelpers::d0significance(muon->primaryTrackParticle(), + beam_pos_sigma_x, + beam_pos_sigma_y, + beam_pos_sigma_xy); muon->auxdecor<float>("d0sig") = d0sig; - if( eventInfo->isAvailable<float>("AnalysisTop_PRIVTX_z_position") ){ + if (eventInfo->isAvailable<float>("AnalysisTop_PRIVTX_z_position")) { float vtx_z = eventInfo->auxdata<float>("AnalysisTop_PRIVTX_z_position"); float delta_z0 = muon->primaryTrackParticle()->z0() + muon->primaryTrackParticle()->vz() - vtx_z; muon->auxdecor<float>("delta_z0") = delta_z0; - muon->auxdecor<float>("delta_z0_sintheta") = delta_z0*std::sin( muon->primaryTrackParticle()->theta() ); + muon->auxdecor<float>("delta_z0_sintheta") = delta_z0 * std::sin(muon->primaryTrackParticle()->theta()); } } - } - + } + ///-- Isolation selection --/// - char passIsol_LooseTrackOnly(0),passIsol_Loose(0),passIsol_FixedCutTightTrackOnly(0); - char passIsol_Gradient(0),passIsol_GradientLoose(0),passIsol_FixedCutLoose(0); - if (m_isolationTool_LooseTrackOnly->accept( *muon )) {passIsol_LooseTrackOnly = 1;} - if (m_isolationTool_Loose->accept( *muon )) {passIsol_Loose = 1;} - if (m_isolationTool_Gradient->accept( *muon )) {passIsol_Gradient = 1;} - if (m_isolationTool_GradientLoose->accept( *muon )) {passIsol_GradientLoose = 1;} - if (m_isolationTool_FixedCutTightTrackOnly->accept( *muon )) {passIsol_FixedCutTightTrackOnly = 1;} - if (m_isolationTool_FixedCutLoose->accept( *muon )) {passIsol_FixedCutLoose = 1;} - - muon->auxdecor<char>("AnalysisTop_Isol_LooseTrackOnly") = passIsol_LooseTrackOnly; - muon->auxdecor<char>("AnalysisTop_Isol_Loose") = passIsol_Loose; - muon->auxdecor<char>("AnalysisTop_Isol_Gradient") = passIsol_Gradient; - muon->auxdecor<char>("AnalysisTop_Isol_GradientLoose") = passIsol_GradientLoose; - muon->auxdecor<char>("AnalysisTop_Isol_FixedCutTightTrackOnly") = passIsol_FixedCutTightTrackOnly; - muon->auxdecor<char>("AnalysisTop_Isol_FixedCutLoose") = passIsol_FixedCutLoose; + char passIsol_FCTight(0), passIsol_FCLoose(0), passIsol_FCTightTrackOnly(0); + char passIsol_FCTightTrackOnly_FixedRad(0), passIsol_FCLoose_FixedRad(0), passIsol_FCTight_FixedRad(0); + char passIsol_FixedCutPflowTight(0), passIsol_FixedCutPflowLoose(0); + + char passIsol_PflowTight_FixedRad(0), passIsol_PflowLoose_FixedRad(0), passIsol_PflowTight_VarRad(0), passIsol_PflowLoose_VarRad(0); + char passIsol_HighPtTrackOnly(0), passIsol_TightTrackOnly_VarRad(0), passIsol_TightTrackOnly_FixedRad(0); + char passIsol_PLVTight(0), passIsol_PLVLoose(0); + char passIsol_Tight_VarRad(0), passIsol_Tight_FixedRad(0), passIsol_Loose_VarRad(0), passIsol_Loose_FixedRad(0); + + //initializing al the passIsol_* variable to -1 + passIsol_FCTight = -1; + passIsol_FCLoose = -1; + passIsol_FCTightTrackOnly = -1; + passIsol_FCTightTrackOnly_FixedRad = -1; + passIsol_FCLoose_FixedRad = -1; + passIsol_FCTight_FixedRad = -1; + passIsol_FixedCutPflowTight = -1; + passIsol_FixedCutPflowLoose = -1; + passIsol_PflowTight_FixedRad = -1; + passIsol_PflowLoose_FixedRad = -1; + passIsol_PflowTight_VarRad = -1; + passIsol_PflowLoose_VarRad = -1; + passIsol_HighPtTrackOnly = -1; + passIsol_TightTrackOnly_VarRad = -1; + passIsol_TightTrackOnly_FixedRad = -1; + passIsol_PLVTight = -1; + passIsol_PLVLoose = -1; + passIsol_Tight_FixedRad = -1; + passIsol_Loose_FixedRad = -1; + passIsol_Tight_VarRad = -1; + passIsol_Loose_VarRad = -1; + + passIsol_FCTight = m_isolationTool_FCTight->accept(*muon) ? 1 : 0; + passIsol_FCLoose = m_isolationTool_FCLoose->accept(*muon) ? 1 : 0; + passIsol_FCTightTrackOnly = m_isolationTool_FCTightTrackOnly->accept(*muon) ? 1 : 0; + passIsol_FCTightTrackOnly_FixedRad = m_isolationTool_FCTightTrackOnly_FixedRad->accept(*muon) ? 1 : 0; + passIsol_FCLoose_FixedRad = m_isolationTool_FCLoose_FixedRad->accept(*muon) ? 1 : 0; + passIsol_FCTight_FixedRad = m_isolationTool_FCTight_FixedRad->accept(*muon) ? 1 : 0; + passIsol_FixedCutPflowTight = m_isolationTool_FixedCutPflowTight->accept(*muon) ? 1 : 0; + passIsol_FixedCutPflowLoose = m_isolationTool_FixedCutPflowLoose->accept(*muon) ? 1 : 0; + + //new Iso WPs + if (ptvarcone30_TightTTVA_pt500.isAvailable(*muon) && neflowisol20.isAvailable(*muon) && ptcone20_TightTTVA_pt500.isAvailable(*muon)) { + passIsol_PflowTight_FixedRad = m_isolationTool_PflowTight_FixedRad->accept(*muon) ? 1 : 0; + passIsol_PflowLoose_FixedRad = m_isolationTool_PflowLoose_FixedRad->accept(*muon) ? 1 : 0; + } + if (ptvarcone30_TightTTVA_pt500.isAvailable(*muon) && neflowisol20.isAvailable(*muon)) { + passIsol_PflowTight_VarRad = m_isolationTool_PflowTight_VarRad->accept(*muon) ? 1 : 0; + passIsol_PflowLoose_VarRad = m_isolationTool_PflowLoose_VarRad->accept(*muon) ? 1 : 0; + } + if (ptcone20_TightTTVA_pt1000.isAvailable(*muon)) { + passIsol_HighPtTrackOnly = m_isolationTool_HighPtTrackOnly->accept(*muon) ? 1 : 0; + } + if (ptvarcone30_TightTTVA_pt500.isAvailable(*muon)) { + passIsol_TightTrackOnly_VarRad = m_isolationTool_TightTrackOnly_VarRad->accept(*muon) ? 1 : 0; + } + if (ptvarcone30_TightTTVA_pt500.isAvailable(*muon) && ptcone20_TightTTVA_pt500.isAvailable(*muon)) { + passIsol_TightTrackOnly_FixedRad = m_isolationTool_TightTrackOnly_FixedRad->accept(*muon) ? 1 : 0; + } + if (ptvarcone30_TightTTVA_pt500.isAvailable(*muon)) { +// if ( PLV_TrackJetNTrack.isAvailable(*muon) && +// PLV_DRlj.isAvailable(*muon) && +// PLV_PtRel.isAvailable(*muon) && +// PLV_PtFrac.isAvailable(*muon) ) +// top::check(m_isolationTool_LowPtPLV->augmentPLV(*muon), "Failed to agument muon with LowPtPLV decorations"); +// else +// byhand_LowPtPLV(*muon) = 1.1; + if (PLV_PromptLeptonVeto.isAvailable(*muon)) { + passIsol_PLVTight = m_isolationTool_PLVTight->accept(*muon) ? 1 : 0; + passIsol_PLVLoose = m_isolationTool_PLVLoose->accept(*muon) ? 1 : 0; + } + } + if (ptvarcone30_TightTTVA_pt1000.isAvailable(*muon) && ptcone20_TightTTVA_pt1000.isAvailable(*muon)) { + passIsol_Tight_FixedRad = m_isolationTool_Tight_FixedRad->accept(*muon) ? 1 : 0; + passIsol_Loose_FixedRad = m_isolationTool_Loose_FixedRad->accept(*muon) ? 1 : 0; + } + if (ptvarcone30_TightTTVA_pt1000.isAvailable(*muon)) { + passIsol_Tight_VarRad = m_isolationTool_Tight_VarRad->accept(*muon) ? 1 : 0; + passIsol_Loose_VarRad = m_isolationTool_Loose_VarRad->accept(*muon) ? 1 : 0; + } + + muon->auxdecor<char>("AnalysisTop_Isol_FCTight") = passIsol_FCTight; + muon->auxdecor<char>("AnalysisTop_Isol_FCLoose") = passIsol_FCLoose; + muon->auxdecor<char>("AnalysisTop_Isol_FCTightTrackOnly") = passIsol_FCTightTrackOnly; + muon->auxdecor<char>("AnalysisTop_Isol_FCTightTrackOnly_FixedRad") = passIsol_FCTightTrackOnly_FixedRad; + muon->auxdecor<char>("AnalysisTop_Isol_FCLoose_FixedRad") = passIsol_FCLoose_FixedRad; + muon->auxdecor<char>("AnalysisTop_Isol_FCTight_FixedRad") = passIsol_FCTight_FixedRad; + muon->auxdecor<char>("AnalysisTop_Isol_FixedCutPflowTight") = passIsol_FixedCutPflowTight; + muon->auxdecor<char>("AnalysisTop_Isol_FixedCutPflowLoose") = passIsol_FixedCutPflowLoose; + + muon->auxdecor<char>("AnalysisTop_Isol_PflowTight_FixedRad") = passIsol_PflowTight_FixedRad; + muon->auxdecor<char>("AnalysisTop_Isol_PflowLoose_FixedRad") = passIsol_PflowLoose_FixedRad; + muon->auxdecor<char>("AnalysisTop_Isol_PflowTight_VarRad") = passIsol_PflowTight_VarRad; + muon->auxdecor<char>("AnalysisTop_Isol_PflowLoose_VarRad") = passIsol_PflowLoose_VarRad; + muon->auxdecor<char>("AnalysisTop_Isol_HighPtTrackOnly") = passIsol_HighPtTrackOnly; + muon->auxdecor<char>("AnalysisTop_Isol_TightTrackOnly_VarRad") = passIsol_TightTrackOnly_VarRad; + muon->auxdecor<char>("AnalysisTop_Isol_TightTrackOnly_FixedRad") = passIsol_TightTrackOnly_FixedRad; + muon->auxdecor<char>("AnalysisTop_Isol_PLVTight") = passIsol_PLVTight; + muon->auxdecor<char>("AnalysisTop_Isol_PLVLoose") = passIsol_PLVLoose; + muon->auxdecor<char>("AnalysisTop_Isol_Tight_VarRad") = passIsol_Tight_VarRad; + muon->auxdecor<char>("AnalysisTop_Isol_Tight_FixedRad") = passIsol_Tight_FixedRad; + muon->auxdecor<char>("AnalysisTop_Isol_Loose_VarRad") = passIsol_Loose_VarRad; + muon->auxdecor<char>("AnalysisTop_Isol_Loose_FixedRad") = passIsol_Loose_FixedRad; + + // PromptLeptonIsolation - Some protection incase things change in R21 + if (muon->isAvailable<float>("PromptLeptonIso_TagWeight")) { + muon->auxdecor<char>("AnalysisTop_Isol_PromptLepton") = + (muon->auxdata<float>("PromptLeptonIso_TagWeight") < -0.5) ? 1 : 0; + } else { + muon->auxdecor<char>("AnalysisTop_Isol_PromptLepton") = 0; + } } ///-- set links to original objects- needed for MET calculation --/// - bool setLinks = xAOD::setOriginalObjectLink( *xaod, *shallow_xaod_copy.first ); - if (!setLinks) - ATH_MSG_ERROR(" Cannot set original object links for muons, MET recalculation may struggle" ); - + bool setLinks = xAOD::setOriginalObjectLink(*xaod, *shallow_xaod_copy.first); + if (!setLinks) ATH_MSG_ERROR(" Cannot set original object links for muons, MET recalculation may struggle"); + ///-- Save corrected xAOD Container to StoreGate / TStore --/// - std::string outputSGKey = m_config->sgKeyMuons( systematic.hash() ); + std::string outputSGKey = m_config->sgKeyMuons(systematic.hash()); std::string outputSGKeyAux = outputSGKey + "Aux."; - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_xaod_copy.first , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_xaod_copy.second , outputSGKeyAux ); - if( !save || !saveAux ){ + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + if (!save || !saveAux) { return StatusCode::FAILURE; - } - } // Loop over all systematics - + } + } // Loop over all systematics + return StatusCode::SUCCESS; } - - StatusCode MuonObjectCollectionMaker::printout() - { + + StatusCode MuonObjectCollectionMaker::printout() { ///-- Loop over all systematics --/// - for( auto systematic : m_specifiedSystematics ){ + for (auto systematic : m_specifiedSystematics) { const xAOD::MuonContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyMuons( systematic.hash() ) ) , "Failed to retrieve Muons" ); - - ATH_MSG_INFO(" Muons with sgKey = "<< m_config->sgKeyMuons( systematic.hash() ) ); - for( auto muon : *xaod ){ - ATH_MSG_INFO(" MU pT , eta = "<< muon->pt() <<" , "<< muon->eta() ); + top::check(evtStore()->retrieve(xaod, m_config->sgKeyMuons(systematic.hash())), "Failed to retrieve Muons"); + + ATH_MSG_INFO(" Muons with sgKey = " << m_config->sgKeyMuons(systematic.hash())); + for (auto muon : *xaod) { + ATH_MSG_INFO(" MU pT , eta = " << muon->pt() << " , " << muon->eta()); } } - - return StatusCode::SUCCESS; + + return StatusCode::SUCCESS; } - - - void MuonObjectCollectionMaker::specifiedSystematics( const std::set<std::string>& specifiedSystematics ) - { + + void MuonObjectCollectionMaker::specifiedSystematics(const std::set<std::string>& specifiedSystematics) { ///-- Get the recommended systematics from the tool, in std::vector format --/// - const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( m_calibrationTool->recommendedSystematics() ); - + const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( + m_calibrationPeriodTool->recommendedSystematics()); + for (auto s : systList) { + + if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter m_recommendedSystematics.push_back(s); if (s.name() == "") { m_specifiedSystematics.push_back(s); } - + ///-- MC only --/// if (m_config->isMC()) { ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// - if (!m_config->isSystNominal( m_config->systematics() )) { + if (!m_config->isSystNominal(m_config->systematics())) { if (specifiedSystematics.size() == 0) { m_specifiedSystematics.push_back(s); } - if (specifiedSystematics.size() > 0) { + if (specifiedSystematics.size() > 0) { for (auto i : specifiedSystematics) { - if ( i == s.name() ) { - m_specifiedSystematics.push_back(s); + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematics.push_back(s); } } } } } } - m_recommendedSystematics.sort(); + m_recommendedSystematics.sort(); m_recommendedSystematics.unique(); m_specifiedSystematics.sort(); - m_specifiedSystematics.unique(); + m_specifiedSystematics.unique(); } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/ObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/ObjectCollectionMaker.cxx index fd1bfbf2b435..a3a889298737 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/ObjectCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/ObjectCollectionMaker.cxx @@ -1,6 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: ObjectCollectionMaker.cxx 790414 2016-12-19 00:49:08Z tpelzer $ #include "TopSystematicObjectMaker/ObjectCollectionMaker.h" @@ -13,139 +13,270 @@ #include "xAODMuon/MuonContainer.h" #include "xAODTau/TauJetContainer.h" #include "xAODJet/JetContainer.h" +#include "xAODTracking/TrackParticleContainer.h" -namespace top{ - ObjectCollectionMaker::ObjectCollectionMaker( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + ObjectCollectionMaker::ObjectCollectionMaker(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), m_egammaMaker(nullptr), m_muonMaker(nullptr), + m_softmuonMaker(nullptr), m_tauMaker(nullptr), m_jetMaker(nullptr), - m_metMaker(nullptr) + m_metMaker(nullptr), + m_trackSystMaker(nullptr) { - declareProperty( "config" , m_config ); + declareProperty("config", m_config); } - StatusCode ObjectCollectionMaker::initialize() - { - ATH_MSG_INFO(" top::ObjectCollectionMaker initialize" ); + StatusCode ObjectCollectionMaker::initialize() { + ATH_MSG_INFO(" top::ObjectCollectionMaker initialize"); + + m_egammaMaker = + std::unique_ptr<top::EgammaObjectCollectionMaker> (new top::EgammaObjectCollectionMaker( + "top::EgammaObjectCollectionMaker")); + m_muonMaker = + std::unique_ptr<top::MuonObjectCollectionMaker> (new top::MuonObjectCollectionMaker( + "top::MuonObjectCollectionMaker")); + m_softmuonMaker = + std::unique_ptr<top::SoftMuonObjectCollectionMaker> (new top::SoftMuonObjectCollectionMaker( + "top::SoftMuonObjectCollectionMaker")); + m_tauMaker = + std::unique_ptr<top::TauObjectCollectionMaker> (new top::TauObjectCollectionMaker( + "top::TauObjectCollectionMaker")); + m_jetMaker = + std::unique_ptr<top::JetObjectCollectionMaker> (new top::JetObjectCollectionMaker( + "top::JetObjectCollectionMaker")); + m_metMaker = + std::unique_ptr<top::MissingETObjectCollectionMaker> (new top::MissingETObjectCollectionMaker( + "top::MissingETObjectCollectionMaker")); + m_ghostTrackSystMaker = + std::unique_ptr<top::GhostTrackSystematicsMaker> (new top::GhostTrackSystematicsMaker( + "top::GhostTrackSystematicsMaker")); + + m_trackSystMaker = + std::unique_ptr<top::TrackSystematicsMaker> (new top::TrackSystematicsMaker( + "top::TrackSystematicsMaker")); - m_egammaMaker = std::unique_ptr<top::EgammaObjectCollectionMaker> ( new top::EgammaObjectCollectionMaker ( "top::EgammaObjectCollectionMaker" ) ); - m_muonMaker = std::unique_ptr<top::MuonObjectCollectionMaker> ( new top::MuonObjectCollectionMaker ( "top::MuonObjectCollectionMaker" ) ); - m_tauMaker = std::unique_ptr<top::TauObjectCollectionMaker> ( new top::TauObjectCollectionMaker ( "top::TauObjectCollectionMaker" ) ); - m_jetMaker = std::unique_ptr<top::JetObjectCollectionMaker> ( new top::JetObjectCollectionMaker ( "top::JetObjectCollectionMaker" ) ); - m_metMaker = std::unique_ptr<top::MissingETObjectCollectionMaker> ( new top::MissingETObjectCollectionMaker( "top::MissingETObjectCollectionMaker" ) ); - m_ghostTrackSystMaker = std::unique_ptr<top::GhostTrackSystematicsMaker> ( new top::GhostTrackSystematicsMaker("top::GhostTrackSystematicsMaker") ); - if( m_config->usePhotons() || m_config->useElectrons() ){ - top::check( m_egammaMaker->setProperty( "config" , m_config ) , "Failed to setProperty" ); - top::check( m_egammaMaker->initialize() , "Failed to initialize" ); + if (m_config->usePhotons() || m_config->useElectrons() || m_config->useFwdElectrons()) { + top::check(m_egammaMaker->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_egammaMaker->initialize(), "Failed to initialize"); } - if( m_config->useMuons() ){ - top::check( m_muonMaker->setProperty( "config" , m_config ) , "Failed to setProperty" ); - top::check( m_muonMaker->initialize() , "Failed to initialize" ); + if (m_config->useMuons()) { + top::check(m_muonMaker->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_muonMaker->initialize(), "Failed to initialize"); } - if( m_config->useTaus() ){ - top::check( m_tauMaker->setProperty( "config" , m_config ) , "Failed to setProperty" ); - top::check( m_tauMaker->initialize() , "Failed to initialize" ); + if (m_config->useSoftMuons()) { + top::check(m_softmuonMaker->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_softmuonMaker->initialize(), "Failed to initialize"); } - if( m_config->useJets() || m_config->useLargeRJets() ){ - top::check( m_jetMaker->setProperty( "config" , m_config ) , "Failed to setProperty" ); - top::check( m_jetMaker->initialize() , "Failed to initialize" ); + if (m_config->useTaus()) { + top::check(m_tauMaker->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_tauMaker->initialize(), "Failed to initialize"); } - if( m_config->useJets() && m_config->useJetGhostTrack() ){ - top::check( m_ghostTrackSystMaker->setProperty( "config" , m_config ), - "Failed to setProperty" ); + if (m_config->useJets() || m_config->useLargeRJets()) { + top::check(m_jetMaker->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_jetMaker->initialize(), "Failed to initialize"); + } - top::check( m_ghostTrackSystMaker->initialize() , - "Failed to initialize" ); + if (m_config->useJets() && m_config->useJetGhostTrack()) { + top::check(m_ghostTrackSystMaker->setProperty("config", m_config), + "Failed to setProperty"); + + top::check(m_ghostTrackSystMaker->initialize(), + "Failed to initialize"); } - top::check( m_metMaker->setProperty( "config" , m_config ) , "Failed to setProperty" ); - top::check( m_metMaker->initialize() , "Failed to initialize" ); + if (m_config->useTracks()) { + top::check(m_trackSystMaker->setProperty("config", m_config), + "Failed to setProperty"); + + top::check(m_trackSystMaker->initialize(), + "Failed to initialize"); + } + + + top::check(m_metMaker->setProperty("config", m_config), "Failed to setProperty"); + top::check(m_metMaker->initialize(), "Failed to initialize"); return StatusCode::SUCCESS; } - StatusCode ObjectCollectionMaker::execute() - { + StatusCode ObjectCollectionMaker::execute(bool executeNominal) { + if (executeNominal) { + top::check(this->executeNominal(), "Failed to executeNominal()"); + } else { + top::check(this->executeSystematics(), "Failed to executeSystematics()"); + } + return StatusCode::SUCCESS; + } - if( m_config->usePhotons() ){ top::check( m_egammaMaker->executePhotons() , "Failed to executePhotons()" ); } - if( m_config->useElectrons() ){ top::check( m_egammaMaker->executeElectrons() , "Failed to executeElectrons()" ); } - if( m_config->useMuons() ){ top::check( m_muonMaker->execute() , "Failed to executeMuons()" ); } - if( m_config->useTaus() ){ top::check( m_tauMaker->execute() , "Failed to executeTaus()" ); } - if( m_config->useJets() ){ top::check( m_jetMaker->executeJets() , "Failed to executeJets()" ); } - if( m_config->useLargeRJets() ){ top::check( m_jetMaker->executeLargeRJets() , "Failed to executeLargeRJets()" ); } - if( m_config->useTrackJets() ){ top::check( m_jetMaker->executeTrackJets() , "Failed to executeTrackJets() " ); } + StatusCode ObjectCollectionMaker::executeNominal() { + if (m_config->usePhotons()) { + top::check(m_egammaMaker->executePhotons(true), "Failed to executePhotons()"); + } + if (m_config->useElectrons()) { + top::check(m_egammaMaker->executeElectrons(true), "Failed to executeElectrons()"); + } + if (m_config->useFwdElectrons()) { + top::check(m_egammaMaker->executeFwdElectrons(true), "Failed to executeFwdElectrons()"); + } + if (m_config->useMuons()) { + top::check(m_muonMaker->execute(true), "Failed to executeMuons()"); + } + if (m_config->useSoftMuons()) { + top::check(m_softmuonMaker->execute(true), "Failed to executeSoftMuons()"); + } + if (m_config->useTaus()) { + top::check(m_tauMaker->execute(true), "Failed to executeTaus()"); + } + if (m_config->useJets()) { + top::check(m_jetMaker->executeJets(true), "Failed to executeJets()"); + } + if (m_config->useLargeRJets()) { + top::check(m_jetMaker->executeLargeRJets(true), "Failed to executeLargeRJets()"); + } + if (m_config->useTrackJets()) { + top::check(m_jetMaker->executeTrackJets(true), "Failed to executeTrackJets() "); + } + if (m_config->useTracks()) { + top::check(m_trackSystMaker->execute(true), "Failed to executeTracks() "); + } // This must come _AFTER_ the jets have been calibrated! - if( m_config->useJets() && m_config->useJetGhostTrack() ){ top::check( m_ghostTrackSystMaker->execute() , "Failed to executeGhostTrackSystematics() " ); } + if (m_config->useJets() && m_config->useJetGhostTrack()) { + top::check(m_ghostTrackSystMaker->execute(true), "Failed to executeGhostTrackSystematics() "); + } + + m_config->setNominalAvailable(true); - return StatusCode::SUCCESS; } - StatusCode ObjectCollectionMaker::recalculateMET() - { - top::check( m_metMaker->recalculateMET() , "Failed to recalculateMET()" ); + StatusCode ObjectCollectionMaker::executeSystematics() { + if (m_config->isNominalAvailable() == false) { + ATH_MSG_ERROR("ObjectCollectionMaker::executeNominal has not been called before executeSystematics"); + return StatusCode::FAILURE; + } + + if (m_config->usePhotons()) { + top::check(m_egammaMaker->executePhotons(false), "Failed to executePhotons()"); + } + if (m_config->useElectrons()) { + top::check(m_egammaMaker->executeElectrons(false), "Failed to executeElectrons()"); + } + if (m_config->useFwdElectrons()) { + top::check(m_egammaMaker->executeFwdElectrons(false), "Failed to executeFwdElectrons()"); + } + if (m_config->useMuons()) { + top::check(m_muonMaker->execute(false), "Failed to executeMuons()"); + } + if (m_config->useSoftMuons()) { + top::check(m_softmuonMaker->execute(false), "Failed to executeSoftMuons()"); + } + if (m_config->useTaus()) { + top::check(m_tauMaker->execute(false), "Failed to executeTaus()"); + } + if (m_config->useJets()) { + top::check(m_jetMaker->executeJets(false), "Failed to executeJets()"); + } + if (m_config->useLargeRJets()) { + top::check(m_jetMaker->executeLargeRJets(false), "Failed to executeLargeRJets()"); + } + if (m_config->useTrackJets()) { + top::check(m_jetMaker->executeTrackJets(false), "Failed to executeTrackJets() "); + } + + // This must come _AFTER_ the jets have been calibrated! + if (m_config->useJets() && m_config->useJetGhostTrack()) { + top::check(m_ghostTrackSystMaker->execute(false), "Failed to executeGhostTrackSystematics() "); + } + + + if (m_config->useTracks()) { + top::check(m_trackSystMaker->execute(false), "Failed to executeTracks() "); + } + + return StatusCode::SUCCESS; } - StatusCode ObjectCollectionMaker::printout() - { - if( m_config->usePhotons() ){ top::check( m_egammaMaker->printoutPhotons() , "Failed to printoutPhotons()" ); } - if( m_config->useElectrons() ){ top::check( m_egammaMaker->printoutElectrons() , "Failed to printoutElectrons()" ); } - if( m_config->useMuons() ){ top::check( m_muonMaker->printout() , "Failed to printoutMuons()" ); } - if( m_config->useTaus() ){ top::check( m_tauMaker->printout() , "Failed to printoutTaus()" ); } - if( m_config->useJets() ){ top::check( m_jetMaker->printoutJets() , "Failed to printoutJets()" ); } - if( m_config->useLargeRJets() ){ top::check( m_jetMaker->printoutLargeRJets() , "Failed to printoutLargeRJets()" ); } + StatusCode ObjectCollectionMaker::recalculateMET(bool executeNominal) { + top::check(m_metMaker->recalculateMET(executeNominal), "Failed to recalculateMET()"); + return StatusCode::SUCCESS; + } + + StatusCode ObjectCollectionMaker::printout() { + if (m_config->usePhotons()) { + top::check(m_egammaMaker->printoutPhotons(), "Failed to printoutPhotons()"); + } + if (m_config->useElectrons()) { + top::check(m_egammaMaker->printoutElectrons(), "Failed to printoutElectrons()"); + } + if (m_config->useFwdElectrons()) { + top::check(m_egammaMaker->printoutFwdElectrons(), "Failed to printoutFwdElectrons()"); + } + if (m_config->useMuons()) { + top::check(m_muonMaker->printout(), "Failed to printoutMuons()"); + } + if (m_config->useSoftMuons()) { + top::check(m_softmuonMaker->printout(), "Failed to printoutSoftMuons()"); + } + if (m_config->useTaus()) { + top::check(m_tauMaker->printout(), "Failed to printoutTaus()"); + } + if (m_config->useJets()) { + top::check(m_jetMaker->printoutJets(), "Failed to printoutJets()"); + } + if (m_config->useLargeRJets()) { + top::check(m_jetMaker->printoutLargeRJets(), "Failed to printoutLargeRJets()"); + } return StatusCode::SUCCESS; } - - bool ObjectCollectionMaker::isTruthDxAOD() const - { + + bool ObjectCollectionMaker::isTruthDxAOD() const { ///-- If any of the following aren't present, then assume we're running over a truth DxAOD --/// if (m_config->usePhotons()) { - if (!evtStore()->contains<xAOD::PhotonContainer>( m_config->sgKeyPhotons() )) { + if (!evtStore()->contains<xAOD::PhotonContainer>(m_config->sgKeyPhotons())) { return true; } } - + if (m_config->useElectrons()) { - if (!evtStore()->contains<xAOD::ElectronContainer>( m_config->sgKeyElectrons() )) { + if (!evtStore()->contains<xAOD::ElectronContainer>(m_config->sgKeyElectrons())) { return true; } } - + if (m_config->useMuons()) { - if (!evtStore()->contains<xAOD::MuonContainer>( m_config->sgKeyMuons() )) { + if (!evtStore()->contains<xAOD::MuonContainer>(m_config->sgKeyMuons())) { return true; } } - + if (m_config->useTaus()) { - if (!evtStore()->contains<xAOD::TauJetContainer>( m_config->sgKeyTaus() )) { + if (!evtStore()->contains<xAOD::TauJetContainer>(m_config->sgKeyTaus())) { return true; } - } - + } + if (m_config->useJets()) { - if (!evtStore()->contains<xAOD::JetContainer>( m_config->sgKeyJets() )) { + if (!evtStore()->contains<xAOD::JetContainer>(m_config->sgKeyJets())) { return true; } - } - + } + ///-- If we have made it this far, then all reco objects are available --/// ///-- Therefore we can't be running over a truth DxAOD --/// return false; } - } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/SoftMuonObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/SoftMuonObjectCollectionMaker.cxx new file mode 100644 index 000000000000..c9c3ff5a70fa --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/SoftMuonObjectCollectionMaker.cxx @@ -0,0 +1,196 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopSystematicObjectMaker/SoftMuonObjectCollectionMaker.h" +#include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/TreeFilter.h" +#include "TopEvent/EventTools.h" + +#include "AthContainers/AuxElement.h" +#include "xAODEventInfo/EventInfo.h" +#include "xAODMuon/MuonContainer.h" +#include "xAODMuon/MuonAuxContainer.h" +#include "xAODCore/ShallowCopy.h" +#include "xAODBase/IParticleHelpers.h" +#include "xAODTracking/TrackParticlexAODHelpers.h" +#include "PATInterfaces/SystematicsUtil.h" + +namespace top { + SoftMuonObjectCollectionMaker::SoftMuonObjectCollectionMaker(const std::string& name) : + asg::AsgTool(name), + m_config(nullptr), + + m_specifiedSystematics(), + m_recommendedSystematics(), + + m_calibrationPeriodTool("CP::MuonCalibrationPeriodTool"), + m_muonSelectionToolVeryLooseVeto("CP::MuonSelectionToolVeryLooseVeto") { + declareProperty("config", m_config); + + declareProperty("MuonCalibrationPeriodTool", m_calibrationPeriodTool); + declareProperty("MuonSelectionToolVeryLooseVeto", m_muonSelectionToolVeryLooseVeto); + } + + StatusCode SoftMuonObjectCollectionMaker::initialize() { + ATH_MSG_INFO(" top::SoftMuonObjectCollectionMaker initialize"); + + top::check(m_calibrationPeriodTool.retrieve(), "Failed to retrieve muon calibration tool"); + top::check(m_muonSelectionToolVeryLooseVeto.retrieve(), "Failed to retrieve Selection Tool"); + + ///-- Set Systematics Information --/// + const std:: string& syststr = m_config->systematics(); + std::set<std::string> syst; + + if (!m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)) { + bool ok = m_config->getSystematicsList(syststr, syst); + if (!ok) { + ATH_MSG_ERROR(" top::SoftMuonObjectCollectionMaker could not determine systematic list"); + return StatusCode::FAILURE; + } + //here the idea is that if the user specifies AllXXX, we leave syst as an empty string, so that all recommended CP + // systematics are then used + if (m_config->contains(syst, "AllMuons")) { + syst.clear(); + } + if (m_config->contains(syst, "AllSoftMuons")) { + syst.clear(); + } + } + + specifiedSystematics(syst); + + m_config->systematicsSoftMuons(specifiedSystematics()); + + ATH_MSG_INFO(" top::SoftMuonObjectCollectionMaker completed initialize"); + return StatusCode::SUCCESS; + } + + StatusCode SoftMuonObjectCollectionMaker::execute(bool executeNominal) { + const xAOD::EventInfo* eventInfo(nullptr); + + top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "Failed to retrieve EventInfo"); + const float beam_pos_sigma_x = eventInfo->beamPosSigmaX(); + const float beam_pos_sigma_y = eventInfo->beamPosSigmaY(); + const float beam_pos_sigma_xy = eventInfo->beamPosSigmaXY(); + + ///-- Get base muons and tracks from xAOD --/// + const xAOD::MuonContainer* xaod(nullptr); + + top::check(evtStore()->retrieve(xaod, m_config->sgKeyMuons()), "Failed to retrieve Soft Muons"); //we use sgKeyMuons and not sgKeySoftMuons on purpose to use the same collection for muons and soft muons + + ///-- Loop over all systematics --/// + for (auto systematic : m_specifiedSystematics) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + + ///-- Tell tool which systematic to use --/// + top::check(m_calibrationPeriodTool->applySystematicVariation(systematic), "Failed to applySystematicVariation"); + + ///-- Shallow copy of the xAOD --/// + std::pair< xAOD::MuonContainer*, + xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer(*xaod); + + ///-- Loop over the xAOD Container and apply corrections--/// + for (xAOD::Muon* muon : *(shallow_xaod_copy.first)) { + + ///-- Apply momentum correction --/// + if (muon->primaryTrackParticle()) { + top::check(m_calibrationPeriodTool->applyCorrection(*muon), "Failed to applyCorrection"); + + // don't do the decorations unless the muons are at least Loose + // this is because it may fail if the muons are at just VeryLoose + if (m_muonSelectionToolVeryLooseVeto->accept(*muon)) { + double d0sig = xAOD::TrackingHelpers::d0significance(muon->primaryTrackParticle(), + beam_pos_sigma_x, + beam_pos_sigma_y, + beam_pos_sigma_xy); + muon->auxdecor<float>("d0sig") = d0sig; + + if (eventInfo->isAvailable<float>("AnalysisTop_PRIVTX_z_position")) { + float vtx_z = eventInfo->auxdata<float>("AnalysisTop_PRIVTX_z_position"); + float delta_z0 = muon->primaryTrackParticle()->z0() + muon->primaryTrackParticle()->vz() - vtx_z; + muon->auxdecor<float>("delta_z0") = delta_z0; + muon->auxdecor<float>("delta_z0_sintheta") = delta_z0 * std::sin(muon->primaryTrackParticle()->theta()); + } + } + }//end of if (muon->primaryTrackParticle()) + + }//end of loop on muons + + ///-- set links to original objects /// + bool setLinks = xAOD::setOriginalObjectLink(*xaod, *shallow_xaod_copy.first); + if (!setLinks) { + ATH_MSG_ERROR(" Cannot set original object links for soft muons"); + return StatusCode::FAILURE; + } + + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + std::string outputSGKey = m_config->sgKeySoftMuons(systematic.hash()); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + } // Loop over all systematics + + return StatusCode::SUCCESS; + } + + StatusCode SoftMuonObjectCollectionMaker::printout() { + ///-- Loop over all systematics --/// + for (auto systematic : m_specifiedSystematics) { + const xAOD::MuonContainer* xaod(nullptr); + top::check(evtStore()->retrieve(xaod, m_config->sgKeySoftMuons( + systematic.hash())), "Failed to retrieve Soft Muons"); + + ATH_MSG_INFO(" Soft Muons with sgKey = " << m_config->sgKeySoftMuons(systematic.hash())); + for (auto muon : *xaod) { + ATH_MSG_INFO(" SOFT MU pT , eta = " << muon->pt() << " , " << muon->eta()); + } + } + + return StatusCode::SUCCESS; + } + + void SoftMuonObjectCollectionMaker::specifiedSystematics(const std::set<std::string>& specifiedSystematics) { + ///-- Get the recommended systematics from the tool, in std::vector format --/// + const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( + m_calibrationPeriodTool->recommendedSystematics()); + + for (const CP::SystematicSet& s : systList) { + + if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter + m_recommendedSystematics.push_back(s); + if (s.name() == "") { + m_specifiedSystematics.push_back(s); + } + + ///-- MC only --/// + if (m_config->isMC()) { + ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// + if (!m_config->isSystNominal(m_config->systematics())) { + if (specifiedSystematics.size() == 0) { + m_specifiedSystematics.push_back(s); + } + if (specifiedSystematics.size() > 0) { + for (auto i : specifiedSystematics) { + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematics.push_back(s); + } + } + } + } + } + } + m_recommendedSystematics.sort(); + m_recommendedSystematics.unique(); + m_specifiedSystematics.sort(); + m_specifiedSystematics.unique(); + } + +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/TauObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/TauObjectCollectionMaker.cxx index f091f6a7f73b..d1407b95d542 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/TauObjectCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/TauObjectCollectionMaker.cxx @@ -1,10 +1,11 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // $Id: TauObjectCollectionMaker.cxx $ #include "TopSystematicObjectMaker/TauObjectCollectionMaker.h" #include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/TreeFilter.h" #include "TopEvent/EventTools.h" #include "xAODTau/TauJetContainer.h" @@ -13,144 +14,147 @@ #include "xAODBase/IParticleHelpers.h" #include "PATInterfaces/SystematicsUtil.h" -namespace top{ - - TauObjectCollectionMaker::TauObjectCollectionMaker( const std::string& name ) : - asg::AsgTool( name ), +namespace top { + TauObjectCollectionMaker::TauObjectCollectionMaker(const std::string& name) : + asg::AsgTool(name), m_config(nullptr), - + m_specifiedSystematics(), m_recommendedSystematics(), - m_calibrationTool("TauAnalysisTools::TauSmearingTool") - - { - declareProperty( "config" , m_config ); - - declareProperty( "TauSmearingTool" , m_calibrationTool ); + m_calibrationTool("TauAnalysisTools::TauSmearingTool"), + m_truthMatchingTool("TauAnalysisTools::TauTruthMatchingTool") { + declareProperty("config", m_config); + + declareProperty("TauSmearingTool", m_calibrationTool); } - StatusCode TauObjectCollectionMaker::initialize() - { - ATH_MSG_INFO(" top::TauObjectCollectionMaker initialize" ); - - top::check( m_calibrationTool.retrieve() , "Failed to retrieve tau calibration tool" ); + StatusCode TauObjectCollectionMaker::initialize() { + ATH_MSG_INFO(" top::TauObjectCollectionMaker initialize"); + + top::check(m_calibrationTool.retrieve(), "Failed to retrieve tau calibration tool"); + top::check(m_truthMatchingTool.retrieve(), "Failed to retrieve tau truth matching tool"); ///-- Set Systematics Information --/// const std:: string& syststr = m_config->systematics(); - std::set<std::string> syst; + std::set<std::string> syst; - if( !m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)){ + if (!m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)) { bool ok = m_config->getSystematicsList(syststr, syst); if (!ok) { - ATH_MSG_ERROR(" top::TauObjectCollectionMaker could not determine systematic list" ); - return StatusCode::FAILURE; + ATH_MSG_ERROR(" top::TauObjectCollectionMaker could not determine systematic list"); + return StatusCode::FAILURE; } + //here the idea is that if the user specifies AllXXX, we leave syst as an empty string, so that all recommended CP + // systematics are then used if (m_config->contains(syst, "AllTaus")) { - syst.clear(); + syst.clear(); } } - specifiedSystematics( syst ); - - m_config->systematicsTaus( specifiedSystematics() ); - + specifiedSystematics(syst); + + m_config->systematicsTaus(specifiedSystematics()); + return StatusCode::SUCCESS; } - - StatusCode TauObjectCollectionMaker::execute() - { + + StatusCode TauObjectCollectionMaker::execute(bool executeNominal) { ///-- Get base taus from xAOD --/// const xAOD::TauJetContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyTaus() ) , "Failed to retrieve Taus" ); - + + top::check(evtStore()->retrieve(xaod, m_config->sgKeyTaus()), "Failed to retrieve Taus"); + ///-- Loop over all systematics --/// - for( auto systematic : m_specifiedSystematics ){ + for (auto systematic : m_specifiedSystematics) { + ///-- if executeNominal, skip other systematics (and vice-versa) --/// + if (executeNominal && !m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; + if (!executeNominal && m_config->isSystNominal(m_config->systematicName(systematic.hash()))) continue; ///-- Tell tool which systematic to use --/// - top::check( m_calibrationTool->applySystematicVariation( systematic ) , "Failed to applySystematicVariation" ); - + top::check(m_calibrationTool->applySystematicVariation(systematic), "Failed to applySystematicVariation"); + ///-- Shallow copy of the xAOD --/// - std::pair< xAOD::TauJetContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *xaod ); - + std::pair< xAOD::TauJetContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( + *xaod); + ///-- Loop over the xAOD Container and apply corrections--/// - for( auto tau : *(shallow_xaod_copy.first) ){ + for (auto tau : *(shallow_xaod_copy.first)) { + ///-- add the necessary decoration + m_truthMatchingTool->getTruth(*tau); + ///-- Apply momentum correction --/// - top::check( m_calibrationTool->applyCorrection( *tau ) , "Failed to applyCorrection" ); + top::check(m_calibrationTool->applyCorrection(*tau), "Failed to applyCorrection"); } - + ///-- set links to original objects- needed for MET calculation --/// - bool setLinks = xAOD::setOriginalObjectLink( *xaod, *shallow_xaod_copy.first ); - if (!setLinks) - ATH_MSG_ERROR(" Cannot set original object links for taus, MET recalculation may struggle" ); - + bool setLinks = xAOD::setOriginalObjectLink(*xaod, *shallow_xaod_copy.first); + if (!setLinks) ATH_MSG_ERROR(" Cannot set original object links for taus, MET recalculation may struggle"); + // Save corrected xAOD Container to StoreGate / TStore - std::string outputSGKey = m_config->sgKeyTaus( systematic.hash() ); + std::string outputSGKey = m_config->sgKeyTaus(systematic.hash()); std::string outputSGKeyAux = outputSGKey + "Aux."; - xAOD::TReturnCode save = evtStore()->tds()->record( shallow_xaod_copy.first , outputSGKey ); - xAOD::TReturnCode saveAux = evtStore()->tds()->record( shallow_xaod_copy.second , outputSGKeyAux ); - if( !save || !saveAux ){ + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + if (!save || !saveAux) { return StatusCode::FAILURE; } - - } // Loop over all systematics - + } // Loop over all systematics + return StatusCode::SUCCESS; } - - StatusCode TauObjectCollectionMaker::printout() - { + + StatusCode TauObjectCollectionMaker::printout() { ///-- Loop over all systematics --/// - for( auto s : m_specifiedSystematics ){ + for (auto s : m_specifiedSystematics) { const xAOD::TauJetContainer* xaod(nullptr); - top::check( evtStore()->retrieve( xaod , m_config->sgKeyTaus( s.hash() ) ) , "Failed to retrieve Taus" ); - - ATH_MSG_INFO(" Taus with sgKey = "<<m_config->sgKeyTaus( s.hash() ) ); - for( auto x : *xaod ){ - ATH_MSG_INFO(" TAU pT , eta = "<<x->pt()<<" , "<<x->eta() ); + top::check(evtStore()->retrieve(xaod, m_config->sgKeyTaus(s.hash())), "Failed to retrieve Taus"); + + ATH_MSG_INFO(" Taus with sgKey = " << m_config->sgKeyTaus(s.hash())); + for (auto x : *xaod) { + ATH_MSG_INFO(" TAU pT , eta = " << x->pt() << " , " << x->eta()); } } - - return StatusCode::SUCCESS; + + return StatusCode::SUCCESS; } - - - void TauObjectCollectionMaker::specifiedSystematics( const std::set<std::string>& specifiedSystematics ) - { + + void TauObjectCollectionMaker::specifiedSystematics(const std::set<std::string>& specifiedSystematics) { ///-- Get the recommended systematics from the tool, in std::vector format --/// - const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( m_calibrationTool->recommendedSystematics() ); - + const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector( + m_calibrationTool->recommendedSystematics()); + for (auto s : systList) { + + if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter m_recommendedSystematics.push_back(s); if (s.name() == "") { m_specifiedSystematics.push_back(s); } - + ///-- MC only --/// if (m_config->isMC()) { ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// - if (!m_config->isSystNominal( m_config->systematics() )) { + if (!m_config->isSystNominal(m_config->systematics())) { if (specifiedSystematics.size() == 0) { m_specifiedSystematics.push_back(s); } - if (specifiedSystematics.size() > 0) { + if (specifiedSystematics.size() > 0) { for (auto i : specifiedSystematics) { - if ( i == s.name() ) { - m_specifiedSystematics.push_back(s); + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematics.push_back(s); } } } } } - } - m_recommendedSystematics.sort(); + } + m_recommendedSystematics.sort(); m_recommendedSystematics.unique(); m_specifiedSystematics.sort(); - m_specifiedSystematics.unique(); + m_specifiedSystematics.unique(); } - } - - diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/TrackSystematicsMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/TrackSystematicsMaker.cxx new file mode 100644 index 000000000000..57f7e33281ae --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/TrackSystematicsMaker.cxx @@ -0,0 +1,487 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TopSystematicObjectMaker/TrackSystematicsMaker.h" + +#include <limits> + +#include "PATInterfaces/SystematicsUtil.h" + +#include "xAODEventInfo/EventInfo.h" +#include "xAODBase/IParticleHelpers.h" + +#include "xAODTracking/TrackParticle.h" +#include "xAODTracking/TrackParticleContainer.h" +#include "xAODTracking/TrackParticleAuxContainer.h" + +#include "TopEvent/EventTools.h" +#include "TopConfiguration/TopConfig.h" +#include "TopConfiguration/TreeFilter.h" + +#include "InDetTrackSystematicsTools/InDetTrackSystematics.h" +#include "InDetTrackSystematicsTools/InDetTrackSmearingTool.h" +#include "InDetTrackSystematicsTools/InDetTrackBiasingTool.h" +#include "InDetTrackSystematicsTools/InDetTrackTruthFilterTool.h" +#include "InDetTrackSystematicsTools/InDetTrackTruthOriginTool.h" + +// Other includes: +#include "xAODCore/ShallowCopy.h" + +namespace top { + /* explicit */ + TrackSystematicsMaker::TrackSystematicsMaker(const std::string& name) + : ::asg::AsgTool(name), + m_config(nullptr), + m_runPeriods(), + m_specifiedSystematics(), + m_recommendedSystematics(), + m_nominalSystematicSet(), + m_smearingTool("top::TrackCPTools::InDetTrackSmearingTool"), + m_truthOriginTool("top::TrackCPTools::InDetTrackTruthOriginTool"), + m_truthFilterTool("top::TrackCPTools::InDetTrackTruthFilterTool") + { + declareProperty("config", m_config); + } + + /* virtual */ TrackSystematicsMaker::~TrackSystematicsMaker() { + } + + StatusCode TrackSystematicsMaker::initialize() { + ATH_MSG_INFO(" top::TrackSystematicsMaker initialize"); + + ATH_MSG_WARNING("Usage of tracks in AnalysisTop is experimental for now!\n"); + + m_runPeriods = m_config->runPeriodsTrack(); + + m_specifiedSystematics.push_back(CP::SystematicSet()); + + // Retrieve the systematics tools. Each individual function will cause + // program abortion upon failure. This is intended as there's no + // meaningful method of recovery. + // These tools are setup and initialised in the TopCPTools package, and we just retrieve them here. + top::check(retrieveTrackCPTool(), "Failed to retrieve the track CP tools"); + + // Setup the recommended systematics. This utilises the tools that were + // setup before. + const std:: string& syststr = m_config->systematics(); + std::set<std::string> syst; + + if (m_config->isSystNominal(syststr)) { + + specifiedSystematics({}); + + + } else if (m_config->isSystAll(syststr)) { + + specifiedSystematics({"AllTracks"}); + + } else { + + std::set<std::string> syst; + bool ok = m_config->getSystematicsList(syststr, syst); + if (!ok) { + ATH_MSG_ERROR(" top::TrackSystematicsMaker could not determine systematic list"); + return StatusCode::FAILURE; + } + + + // No need to manually handle the AllTrack case in here. + specifiedSystematics(syst); + } + + + // Pass the systematics list back to the top::TopConfig object. + m_config->systematicsTracks(specifiedSystematics()); + + ATH_MSG_INFO(" top::TrackSystematicsMaker completed initialize"); + return StatusCode::SUCCESS; + } + + + + StatusCode TrackSystematicsMaker::applyTruthFilterSystematic(InDet::InDetTrackTruthFilterTool* tool, + const CP::SystematicSet& syst) const { + + if(m_config->sgKeyTracks(syst.hash()) == "InDetTrackParticles_") + return StatusCode::SUCCESS; + + // Create a shallow copy of InDetTrackParticles: + const xAOD::TrackParticleContainer *tp(nullptr); + top::check(evtStore()->retrieve(tp, "InDetTrackParticles"), "Retrieve InDetParticles"); + + std::pair< xAOD::TrackParticleContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *tp ); + + ///-- Inform the tool --/// + top::check(tool->applySystematicVariation(syst), + "Failed to configure tool for systematic variation"); + + + + for ( xAOD::TrackParticle* trkCpy : *(shallow_xaod_copy.first) ) { + + + if (not tool->accept(trkCpy)) trkCpy->auxdecor<char>("passTruthFilter") = 0; + else trkCpy->auxdecor<char>("passTruthFilter") = 1; + + + } + + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + std::string outputSGKey = m_config->sgKeyTracks(syst.hash()); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } + + + StatusCode TrackSystematicsMaker::applySmearingSystematic(InDet::InDetTrackSmearingTool* tool, + const CP::SystematicSet& syst) const { + + + if(m_config->sgKeyTracks(syst.hash()) == "InDetTrackParticles_") + return StatusCode::SUCCESS; + + // Create a shallow copy of InDetTrackParticles: + const xAOD::TrackParticleContainer *tp(nullptr); + top::check(evtStore()->retrieve(tp, "InDetTrackParticles"), "Retrieve InDetParticles"); + + std::pair< xAOD::TrackParticleContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *tp ); + + ///-- Inform the tool --/// + top::check(tool->applySystematicVariation(syst), "Failed to configure tool for systematic variation"); + + + for ( xAOD::TrackParticle* trkCpy : *(shallow_xaod_copy.first) ) { + + top::check(tool->applyCorrection(*trkCpy), "Failure to apply track systematic"); + + } + + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + std::string outputSGKey = m_config->sgKeyTracks(syst.hash()); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } + + StatusCode TrackSystematicsMaker::applyBiasingSystematic(InDet::InDetTrackBiasingTool* tool, + const CP::SystematicSet& syst) const { + + if(m_config->sgKeyTracks(syst.hash()) == "InDetTrackParticles_") + return StatusCode::SUCCESS; + + + // Create a shallow copy of InDetTrackParticles: + const xAOD::TrackParticleContainer *tp(nullptr); + top::check(evtStore()->retrieve(tp, "InDetTrackParticles"), "Retrieve InDetParticles"); + + std::pair< xAOD::TrackParticleContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *tp ); + + ///-- Inform the tool --/// + top::check(tool->applySystematicVariation(syst), + "Failed to configure tool for systematic variation"); + + for ( xAOD::TrackParticle* trkCpy : *(shallow_xaod_copy.first) ) { + + top::check(tool->applyCorrection(*trkCpy), "Failure to apply track systematic"); + + } + + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + std::string outputSGKey = m_config->sgKeyTracks(syst.hash()); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } + + StatusCode TrackSystematicsMaker::execute(bool executeNominal) { + ATH_MSG_DEBUG(" top::TrackSystematicsMaker execute:"); + + + if (!m_config->isMC() && executeNominal) { + + // Create a shallow copy of InDetTrackParticles: + const xAOD::TrackParticleContainer *tp(nullptr); + top::check(evtStore()->retrieve(tp, "InDetTrackParticles"), "Retrieve InDetParticles"); + + std::pair< xAOD::TrackParticleContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *tp ); + + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + std::string outputSGKey = m_config->sgKeyTracks(m_nominalSystematicSet.hash()); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + + return StatusCode::SUCCESS; + } + if (!m_config->isMC() && !executeNominal) { + return StatusCode::SUCCESS; + } + + + ///-- Only run this on the systematic execution --/// + if (executeNominal){ + + // Create a shallow copy of InDetTrackParticles: + const xAOD::TrackParticleContainer *tp(nullptr); + top::check(evtStore()->retrieve(tp, "InDetTrackParticles"), "Retrieve InDetParticles"); + + std::pair< xAOD::TrackParticleContainer*, xAOD::ShallowAuxContainer* > shallow_xaod_copy = xAOD::shallowCopyContainer( *tp ); + + ///-- Save corrected xAOD Container to StoreGate / TStore --/// + std::string outputSGKey = m_config->sgKeyTracks(m_nominalSystematicSet.hash()); + std::string outputSGKeyAux = outputSGKey + "Aux."; + + xAOD::TReturnCode save = evtStore()->tds()->record(shallow_xaod_copy.first, outputSGKey); + xAOD::TReturnCode saveAux = evtStore()->tds()->record(shallow_xaod_copy.second, outputSGKeyAux); + + if (!save || !saveAux) { + return StatusCode::FAILURE; + } + + + return StatusCode::SUCCESS; + + } + + ///-- SMEARING --/// + for (const auto& syst : m_systs.smearing) { + top::check(applySmearingSystematic(&(*m_smearingTool), syst), + "Failure to apply TrackSystematic"); + } + + ///-- BIASING --/// + InDet::InDetTrackBiasingTool* biasingTool { + nullptr + }; + + if (m_runPeriods.size() == 1) { + biasingTool = &(*m_biasTool[0]); + + top::check(biasingTool, "Failure to selected biasing tool"); + for (const auto& syst : m_systs.bias) { + top::check(applyBiasingSystematic(biasingTool, syst), + "Failure to apply TrackSystematic"); + } + } + else { + const xAOD::EventInfo* ei { + nullptr + }; + top::check(evtStore()->retrieve(ei, "EventInfo"), + "Failure to retrieve EventInfo"); + + top::check(ei->isAvailable<unsigned int>("RandomRunNumber"), + "Require that RandomRunNumber decoration is available."); + auto randomRunNumber = ei->auxdataConst<unsigned int>("RandomRunNumber"); + + if (randomRunNumber != 0 ){ + top::check(m_runPeriods[0] <= randomRunNumber, + "RandomRunNumber is below valid range."); + top::check(randomRunNumber < m_runPeriods[m_runPeriods.size() - 1], + "RandomRunNumber is above valid range."); + + for (std::size_t i = 1; i < m_runPeriods.size(); ++i) { + if (randomRunNumber < m_runPeriods[i]) { + biasingTool = &(*m_biasTool[i - 1]); + break; + } + } + top::check(biasingTool, "Failure to selected biasing tool"); + for (const auto& syst : m_systs.bias) { + top::check(applyBiasingSystematic(biasingTool, syst), + "Failure to apply TrackSystematic"); + } + } + } + + ///-- TRUTH FILTER --/// + for (const auto& syst : m_systs.truthFilter) { + + top::check(applyTruthFilterSystematic(&(*m_truthFilterTool), syst), + "Failure to apply TrackSystematic"); + } + + ATH_MSG_DEBUG(" top::TrackSystematicsMaker completed execute"); + return StatusCode::SUCCESS; + } + + void TrackSystematicsMaker::specifiedSystematics(const std::set<std::string>& specSys) { + + // NOTE: For this function -- unlike the "proper" ObjectCollectionMakers in AnalysisTop -- an empty + // specifiedSystematics input is considered to represent "No Systematics". All Track systematics can be + // requested with the string "AllTrack". + const bool allTrackSystematics = m_config->contains(specSys, "AllTracks"); + + // Acquire the recommended systematics from the various tools and put + // into containers that store the per-tool systematics as well as a + // global container. At a later point we'll make the per-tool containers + // unique and check that the containers for various tools are + // orthogonal. + std::set<CP::SystematicSet> systs; + + // SMEARING + m_systs.smearing = CP::make_systematics_vector(m_smearingTool->recommendedSystematics()); + systs.insert(m_systs.smearing.begin(), m_systs.smearing.end()); + + // BIAS + for (const auto& tool : m_biasTool) { + m_systs.bias = + CP::make_systematics_vector(tool->recommendedSystematics()); + systs.insert(m_systs.bias.begin(), m_systs.bias.end()); + } + + // TRUTH FILTER + m_systs.truthFilter = + CP::make_systematics_vector(m_truthFilterTool->recommendedSystematics()); + systs.insert(m_systs.truthFilter.begin(), m_systs.truthFilter.end()); + + // PUT INTO RECOMMENDED AND SPECIFIED + for (const auto& s : systs) { + + // We don't want nominal. + if (s.name() == "") { + continue; + } + + m_recommendedSystematics.push_back(s); + + ///-- MC only --/// + if (m_config->isMC()) { + ///-- Are we only doing Nominal? Did the user specify specific systematics to use? --/// + if (!m_config->isSystNominal(m_config->systematics())) { + if (allTrackSystematics) { + + m_specifiedSystematics.push_back(s); + continue; + } + + for (const auto& i : specSys) { + TreeFilter filter(i); + if (!filter.filterTree(s.name())) { + m_specifiedSystematics.push_back(s); + } + } + } + } + } + + m_recommendedSystematics.sort(); + m_recommendedSystematics.unique(); + + m_specifiedSystematics.sort(); + m_specifiedSystematics.unique(); + + // Make the sublists unique and remove any elements that have not "been specified". + m_systs.makeUnique(); + m_systs.removeNonSpecified(m_specifiedSystematics); + + // Lastly, let use introduce a safeguard which ensures that the + // systematics selected for the various tools are orthogonal. This is + // done by asserting that the sum of the sizes of the individual + // systematics lists equals the size of the list of specified + // systematics. We can do this because we've made the individual + // per-tool containers unique (in makeUnique). + if(m_specifiedSystematics.size() > 1) + top::check(systs.size() == m_specifiedSystematics.size(), "Sanity check failed"); + else + top::check(m_specifiedSystematics.size() == 1, "Sanity check failed"); + + + } + + StatusCode TrackSystematicsMaker::retrieveTrackCPTool() { + ATH_MSG_INFO(" Retrieving track CPTools"); + + + top::check(m_smearingTool.retrieve(), "Failed to retrieve track smearing tool"); + + std::string biasToolPrefix {"top::TrackCPTools::InDetTrackBiasingTool"}; + top::check(not m_runPeriods.empty(), "Assertion failed"); + // Two cases are possible: + // - Either a single run number was specified to the runPeriods + // parameter in which case we'll use exactly that run number, or + // - at least two numbers have been specified, which then define + // (potentially multiple) run number ranges. + unsigned int end = 0; + if (m_runPeriods.size() == 1) { + end = 1; + m_biasTool.resize(1); + } else { + end = m_runPeriods.size() - 1; + m_biasTool.resize(m_runPeriods.size() - 1); + } + + for (unsigned int i = 0; i < end; i++) { + + + std::string biasToolName { + "" + }; + if (m_runPeriods.size() == 1) { + biasToolName = biasToolPrefix + "_" + std::to_string(m_runPeriods[0]); + } + else { + biasToolName = biasToolPrefix + "_" + std::to_string(m_runPeriods[i]) + "_" + + std::to_string(m_runPeriods[i + 1]); + } + + + if (asg::ToolStore::contains<InDet::InDetTrackBiasingTool>(biasToolName)) { + m_biasTool[i] = asg::ToolStore::get<InDet::InDetTrackBiasingTool>(biasToolName); + } else { + ATH_MSG_ERROR(" Impossible to retrieve " + biasToolName); + return StatusCode::FAILURE; + } + + + + } + + top::check(m_truthOriginTool.retrieve(), "Failed to retrieve track truth origin tool"); + top::check(m_truthFilterTool.retrieve(), "Failed to retrieve track truth filter tool"); + + + return StatusCode::SUCCESS; + } + + + inline const std::list<CP::SystematicSet>& TrackSystematicsMaker::specifiedSystematics() const { + return m_specifiedSystematics; + } + + inline const std::list<CP::SystematicSet>& TrackSystematicsMaker::recommendedSystematics() const { + return m_recommendedSystematics; + } + +} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/EgammaObjectCollectionMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/EgammaObjectCollectionMaker.h index ee3e1b2a6a05..a5eb11e2b91b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/EgammaObjectCollectionMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/EgammaObjectCollectionMaker.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ -// $Id: EgammaObjectCollectionMaker.h 802735 2017-04-11 16:38:01Z tpelzer $ +// $Id: EgammaObjectCollectionMaker.h 811374 2017-10-24 13:04:52Z iconnell $ #ifndef ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_EGAMMAOBJECTCOLLECTIONMAKER_H #define ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_EGAMMAOBJECTCOLLECTIONMAKER_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief EgammaObjectCollectionMaker - * Makes all systematic variations of photons and electrons - * - * $Revision: 802735 $ - * $Date: 2017-04-11 18:38:01 +0200 (Tue, 11 Apr 2017) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief EgammaObjectCollectionMaker + * Makes all systematic variations of photons and electrons + * + * $Revision: 811374 $ + * $Date: 2017-10-24 14:04:52 +0100 (Tue, 24 Oct 2017) $ + * + **/ // system include(s): #include <memory> @@ -30,73 +30,108 @@ #include "PATInterfaces/SystematicSet.h" // CP Tool include(s): -#include "ElectronPhotonFourMomentumCorrection/IEgammaCalibrationAndSmearingTool.h" -#include "ElectronPhotonShowerShapeFudgeTool/IElectronPhotonShowerShapeFudgeTool.h" +#include "EgammaAnalysisInterfaces/IEgammaCalibrationAndSmearingTool.h" +#include "EgammaAnalysisInterfaces/IElectronPhotonShowerShapeFudgeTool.h" #include "IsolationSelection/IIsolationSelectionTool.h" +//#include "IsolationSelection/IIsolationLowPtPLVTool.h" #include "IsolationCorrections/IIsolationCorrectionTool.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class EgammaObjectCollectionMaker final : public asg::AsgTool { - public: - explicit EgammaObjectCollectionMaker( const std::string& name ); - virtual ~EgammaObjectCollectionMaker(){} - - // Delete Standard constructors - EgammaObjectCollectionMaker(const EgammaObjectCollectionMaker& rhs) = delete; - EgammaObjectCollectionMaker(EgammaObjectCollectionMaker&& rhs) = delete; - EgammaObjectCollectionMaker& operator=(const EgammaObjectCollectionMaker& rhs) = delete; - - StatusCode initialize(); - - StatusCode executePhotons(); - StatusCode executeElectrons(); - - StatusCode printoutPhotons(); - StatusCode printoutElectrons(); - - // return specific Systematic - inline virtual const std::list<CP::SystematicSet>& specifiedSystematicsPhotons() const {return m_specifiedSystematicsPhotons;} - inline virtual const std::list<CP::SystematicSet>& specifiedSystematicsElectrons() const {return m_specifiedSystematicsElectrons;} - - // return all recommendedSystematics - inline const std::list<CP::SystematicSet>& recommendedSystematicsPhotons() const {return m_recommendedSystematicsPhotons;} - inline const std::list<CP::SystematicSet>& recommendedSystematicsElectrons() const {return m_recommendedSystematicsElectrons;} - - protected: - // specify Systematic - virtual void specifiedSystematicsPhotons ( const std::set<std::string>& specifiedSystematics ); - virtual void specifiedSystematicsElectrons( const std::set<std::string>& specifiedSystematics ); - - private: - std::shared_ptr<top::TopConfig> m_config; - - std::list<CP::SystematicSet> m_specifiedSystematicsPhotons; - std::list<CP::SystematicSet> m_specifiedSystematicsElectrons; - - std::list<CP::SystematicSet> m_recommendedSystematicsPhotons; - std::list<CP::SystematicSet> m_recommendedSystematicsElectrons; - - ToolHandle<CP::IEgammaCalibrationAndSmearingTool> m_calibrationTool; - ToolHandle<IElectronPhotonShowerShapeFudgeTool> m_photonFudgeTool; - - ///-- Isolation --/// - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_LooseTrackOnly; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Loose; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Gradient; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_GradientLoose; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutTight; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutTightTrackOnly; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutTightCaloOnly; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutLoose; - - ToolHandle<CP::IIsolationCorrectionTool> m_isolationCorr; - +namespace top { + class EgammaObjectCollectionMaker final: public asg::AsgTool { + public: + explicit EgammaObjectCollectionMaker(const std::string& name); + virtual ~EgammaObjectCollectionMaker() {} + + // Delete Standard constructors + EgammaObjectCollectionMaker(const EgammaObjectCollectionMaker& rhs) = delete; + EgammaObjectCollectionMaker(EgammaObjectCollectionMaker&& rhs) = delete; + EgammaObjectCollectionMaker& operator = (const EgammaObjectCollectionMaker& rhs) = delete; + + StatusCode initialize(); + + StatusCode executePhotons(bool); + StatusCode executeElectrons(bool); + StatusCode executeFwdElectrons(bool); + + StatusCode printoutPhotons(); + StatusCode printoutElectrons(); + StatusCode printoutFwdElectrons(); + + // return specific Systematic + inline virtual const std::list<CP::SystematicSet>& specifiedSystematicsPhotons() const { + return m_specifiedSystematicsPhotons; + } + inline virtual const std::list<CP::SystematicSet>& specifiedSystematicsElectrons() const { + return m_specifiedSystematicsElectrons; + } + inline virtual const std::list<CP::SystematicSet>& specifiedSystematicsFwdElectrons() const { + return m_specifiedSystematicsFwdElectrons; + } + + // return all recommendedSystematics + inline const std::list<CP::SystematicSet>& recommendedSystematicsPhotons() const { + return m_recommendedSystematicsPhotons; + } + inline const std::list<CP::SystematicSet>& recommendedSystematicsElectrons() const {return m_recommendedSystematicsElectrons;} + inline const std::list<CP::SystematicSet>& recommendedSystematicsFwdElectrons() const {return m_recommendedSystematicsFwdElectrons;} + protected: + // specify Systematic + virtual void specifiedSystematicsPhotons(const std::set<std::string>& specifiedSystematics); + virtual void specifiedSystematicsElectrons(const std::set<std::string>& specifiedSystematics); + virtual void specifiedSystematicsFwdElectrons(const std::set<std::string>& specifiedSystematics); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::list<CP::SystematicSet> m_specifiedSystematicsPhotons; + std::list<CP::SystematicSet> m_specifiedSystematicsElectrons; + std::list<CP::SystematicSet> m_specifiedSystematicsFwdElectrons; + + std::list<CP::SystematicSet> m_recommendedSystematicsPhotons; + std::list<CP::SystematicSet> m_recommendedSystematicsElectrons; + std::list<CP::SystematicSet> m_recommendedSystematicsFwdElectrons; + + ToolHandle<CP::IEgammaCalibrationAndSmearingTool> m_calibrationTool; + ToolHandle<IElectronPhotonShowerShapeFudgeTool> m_photonFudgeTool; + + ///-- Isolation --/// + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_LooseTrackOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Loose; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PflowLoose; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Tight; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PflowTight; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Gradient; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_GradientLoose; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutTight; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutTightTrackOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_TightTrackOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_TightTrackOnly_FixedRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutTightCaloOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_TightCaloOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutLoose; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutHighPtCaloOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCHighPtCaloOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_HighPtCaloOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCTight; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCLoose; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PLVTight; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PLVLoose; + +// ToolHandle<CP::IIsolationLowPtPLVTool> m_isolationTool_LowPtPLV; + + ToolHandle<CP::IIsolationCorrectionTool> m_isolationCorr; + + // Flag for applying calibration to objects + bool calibrateElectrons; + bool calibrateFwdElectrons; + bool calibratePhotons; + + // Flag for recomputing CP vars + bool m_recomputePhotonFudge; }; } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/ElectronInJetSubtractionCollectionMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/ElectronInJetSubtractionCollectionMaker.h index 0c7437f51e27..e52620624c86 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/ElectronInJetSubtractionCollectionMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/ElectronInJetSubtractionCollectionMaker.h @@ -1,30 +1,30 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: ElectronInJetSubtractionCollectionMaker.h 653798 2015-03-12 19:24:22Z morrisj $ #ifndef ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_ELECTRONINJETSUBTRACTIONCOLLECTIONMAKER_H #define ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_ELECTRONINJETSUBTRACTIONCOLLECTIONMAKER_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief ElectronInJetSubtractionCollectionMaker - * Makes all needed collections for the Electron in jet subtraction - * Used by boosted analysis - * - * Will require a set of electron and jet collections for: - * Nominal - * All Electron systematics - * All Jet systematics - * - * This class does not do the actual subtraction algorithm - * This class prepares the collections and calls the algorithm - * - * $Revision: 653798 $ - * $Date: 2015-03-12 20:24:22 +0100 (Thu, 12 Mar 2015) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief ElectronInJetSubtractionCollectionMaker + * Makes all needed collections for the Electron in jet subtraction + * Used by boosted analysis + * + * Will require a set of electron and jet collections for: + * Nominal + * All Electron systematics + * All Jet systematics + * + * This class does not do the actual subtraction algorithm + * This class prepares the collections and calls the algorithm + * + * $Revision: 653798 $ + * $Date: 2015-03-12 19:24:22 +0000 (Thu, 12 Mar 2015) $ + * + **/ // system include(s): #include <memory> @@ -38,30 +38,28 @@ #include "TopJetSubstructure/ElectronInJetSubtractionAlgorithm.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class ElectronInJetSubtractionCollectionMaker final : public asg::AsgTool { - public: - explicit ElectronInJetSubtractionCollectionMaker( const std::string& name ); - virtual ~ElectronInJetSubtractionCollectionMaker(){} - - // Delete Standard constructors - ElectronInJetSubtractionCollectionMaker(const ElectronInJetSubtractionCollectionMaker& rhs) = delete; - ElectronInJetSubtractionCollectionMaker(ElectronInJetSubtractionCollectionMaker&& rhs) = delete; - ElectronInJetSubtractionCollectionMaker& operator=(const ElectronInJetSubtractionCollectionMaker& rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - - private: - std::shared_ptr<top::TopConfig> m_config; - bool m_doLooseCuts; - // The algorithm - top::ElectronInJetSubtractionAlgorithm m_subtractionAlgorithm; +namespace top { + class ElectronInJetSubtractionCollectionMaker final: public asg::AsgTool { + public: + explicit ElectronInJetSubtractionCollectionMaker(const std::string& name); + virtual ~ElectronInJetSubtractionCollectionMaker() {} + + // Delete Standard constructors + ElectronInJetSubtractionCollectionMaker(const ElectronInJetSubtractionCollectionMaker& rhs) = delete; + ElectronInJetSubtractionCollectionMaker(ElectronInJetSubtractionCollectionMaker&& rhs) = delete; + ElectronInJetSubtractionCollectionMaker& operator = (const ElectronInJetSubtractionCollectionMaker& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(bool); + private: + std::shared_ptr<top::TopConfig> m_config; + bool m_doLooseCuts; + // The algorithm + top::ElectronInJetSubtractionAlgorithm m_subtractionAlgorithm; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/GhostTrackSystematicsMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/GhostTrackSystematicsMaker.h index e5f19550dc04..6e8052f42ba8 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/GhostTrackSystematicsMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/GhostTrackSystematicsMaker.h @@ -1,14 +1,12 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ // Filename: GhostTrackSystematicsMaker.h // Description: // Author: Fabian Wilk // Created: Mon Oct 24 16:54:17 2016 -// -// by Fabian Wilk <mail@fabianwilk.de> -// The ATLAS Collaboration + #ifndef _TOP_GHOSTTRACKSYSTEMATICSMAKER_H_ #define _TOP_GHOSTTRACKSYSTEMATICSMAKER_H_ @@ -30,182 +28,179 @@ // Forward Declarations. namespace InDet { - class InDetTrackSystematicsTool; - class InDetTrackSmearingTool; - class InDetTrackBiasingTool; - class InDetTrackTruthFilterTool; - class InDetTrackTruthOriginTool; - class JetTrackFilterTool; + class InDetTrackSystematicsTool; + class InDetTrackSmearingTool; + class InDetTrackBiasingTool; + class InDetTrackTruthFilterTool; + class InDetTrackTruthOriginTool; + class JetTrackFilterTool; } namespace top { - class TopConfig; + class TopConfig; } namespace top { + /* + * @brief Tool for making systematics that affect ghost-associated tracks of + * jets available. + * + * Ghost-associated tracks are available on jets through the + * getAssociatedObjects function which retrieves a + * + * std::vector<const xAOD::IParticle*> + * + * container that is decorated onto each jet object. + * + * This tool, produces one copy of this container for each of the affecting + * and requested systematics. Some systematics change only the number of + * tracks (efficiency-style systematics) while other only smear (some) of + * the track particle properties. + * + * The requested systematics are retrieved from top::TopConfig, filtered to + * only contain those affecting the ghost tracks, and propagated back to + * the top::TopConfig instance so that they become available to any tool + * which wishes to query + * + * - the affecting systematics, + * - the decoration name used for the varied ghost track container + * + * Generally, a tool should use the function + * + * top::TopConfig::systMapJetGhostTrack() + * + * to retrieve the mapping from the hash value of a systematic to the + * CP::SystematicSet of that variation for all (configured and requested) + * systematics that affect the ghost tracks (this map includes the nominal + * systematic). The decoration name can then be retrieved using + * + * top::TopConfig::decoKeyJetGhostTrack(std::size_t hash) + */ + class GhostTrackSystematicsMaker final: public asg::AsgTool { + public: + explicit GhostTrackSystematicsMaker(const std::string& name); + virtual ~GhostTrackSystematicsMaker(); + + GhostTrackSystematicsMaker(const GhostTrackSystematicsMaker& rhs) = delete; + GhostTrackSystematicsMaker(GhostTrackSystematicsMaker&& rhs) = delete; + GhostTrackSystematicsMaker& operator = (const GhostTrackSystematicsMaker& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(bool); /* - * @brief Tool for making systematics that affect ghost-associated tracks of - * jets available. - * - * Ghost-associated tracks are available on jets through the - * getAssociatedObjects function which retrieves a - * - * std::vector<const xAOD::IParticle*> - * - * container that is decorated onto each jet object. - * - * This tool, produces one copy of this container for each of the affecting - * and requested systematics. Some systematics change only the number of - * tracks (efficiency-style systematics) while other only smear (some) of - * the track particle properties. - * - * The requested systematics are retrieved from top::TopConfig, filtered to - * only contain those affecting the ghost tracks, and propagated back to - * the top::TopConfig instance so that they become available to any tool - * which wishes to query - * - * - the affecting systematics, - * - the decoration name used for the varied ghost track container + * @brief Retrieve the specified (requested) systematics list.* * - * Generally, a tool should use the function - * - * top::TopConfig::systMapJetGhostTrack() - * - * to retrieve the mapping from the hash value of a systematic to the - * CP::SystematicSet of that variation for all (configured and requested) - * systematics that affect the ghost tracks (this map includes the nominal - * systematic). The decoration name can then be retrieved using - * - * top::TopConfig::decoKeyJetGhostTrack(std::size_t hash) + * Unless systematics have been requested through the + * specifiedSystematics setter function, this will be an empty list. */ - class GhostTrackSystematicsMaker final : public asg::AsgTool { - public: - explicit GhostTrackSystematicsMaker(const std::string & name); - virtual ~GhostTrackSystematicsMaker(); - - GhostTrackSystematicsMaker(const GhostTrackSystematicsMaker & rhs) = delete; - GhostTrackSystematicsMaker(GhostTrackSystematicsMaker && rhs) = delete; - GhostTrackSystematicsMaker & operator=(const GhostTrackSystematicsMaker & rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - - /* - * @brief Retrieve the specified (requested) systematics list.* - * - * Unless systematics have been requested through the - * specifiedSystematics setter function, this will be an empty list. - */ - inline virtual const std::list<CP::SystematicSet> & specifiedSystematics() const; - - /* - * @brief Retrieve the recommended systematics list. - * - * This will return a meaningless (probably empty) list unless the - * setter function specifiedSystematics has been called or the tool has - * been initialized (which call specifiedSystematics using the data - * obtained from top::TopConfig). - */ - inline const std::list<CP::SystematicSet> & recommendedSystematics() const; - - /*! - * @brief Specify the systematics to be used. - * @param specifiedSystematics Set of systematics (by name) to be used; - * an empty set will result in no systematic variation. - */ - virtual void specifiedSystematics(const std::set<std::string> & specifiedSystematics); - - protected: - StatusCode applyNoOpSystematic(xAOD::JetContainer * nominal, - const CP::SystematicSet & syst) const; - - StatusCode applyTruthFilterSystematic(xAOD::JetContainer * nominal, - InDet::InDetTrackTruthFilterTool * tool, - const CP::SystematicSet & syst) const; - - StatusCode applySmearingSystematic(xAOD::JetContainer * nominal, - InDet::InDetTrackSmearingTool * tool, - const CP::SystematicSet & syst) const; - - StatusCode applyBiasingSystematic(xAOD::JetContainer * nominal, - InDet::InDetTrackBiasingTool * tool, - const CP::SystematicSet & syst) const; - - StatusCode applyJetTrackFilterSystematic(xAOD::JetContainer * nominal, - InDet::JetTrackFilterTool * tool, - const CP::SystematicSet & syst) const; - - private: - StatusCode retrieveGhostTrackCPTool(); - - private: - std::shared_ptr<top::TopConfig> m_config; - std::vector<std::uint32_t> m_runPeriods; - - std::list<CP::SystematicSet> m_specifiedSystematics; - std::list<CP::SystematicSet> m_recommendedSystematics; - - CP::SystematicSet m_nominalSystematicSet; - - struct { - void makeUnique(){ - static auto exec = [](std::vector<CP::SystematicSet> & data){ - std::sort(data.begin(), data.end()); - data.erase(std::unique(data.begin(), data.end()), - data.end()); - }; - - exec(smearing); - exec(truthFilter); - exec(bias); - exec(jetTrackFilter); - } - - void removeNonSpecified(const std::list<CP::SystematicSet> & specified){ - auto fnCmp = [&specified](CP::SystematicSet & s){ - return std::find(specified.begin(), - specified.end(), - s) == specified.end(); - }; - - auto exec = [&specified, &fnCmp](std::vector<CP::SystematicSet> & data){ - data.erase(std::remove_if(data.begin(), data.end(), fnCmp), - data.end()); - }; - - exec(smearing); - exec(truthFilter); - exec(bias); - exec(jetTrackFilter); - } - - std::size_t numSystematics() const { - return smearing.size() + truthFilter.size() + bias.size() + jetTrackFilter.size(); - } - - std::vector<CP::SystematicSet> smearing, truthFilter, bias, jetTrackFilter; - } m_systs; - - struct { - ToolHandle<InDet::InDetTrackSmearingTool> smearing; - ToolHandle<InDet::InDetTrackTruthOriginTool> truthOrigin; - ToolHandle<InDet::InDetTrackTruthFilterTool> truthFilter; - ToolHandle<InDet::JetTrackFilterTool> jetTrackFilter; - - std::vector<ToolHandle<InDet::InDetTrackBiasingTool> > bias; - } m_tools; - }; - - /* inline virtual */ const std::list<CP::SystematicSet> & GhostTrackSystematicsMaker::specifiedSystematics() const { - return m_specifiedSystematics; - - } - /* inline */ const std::list<CP::SystematicSet> & GhostTrackSystematicsMaker::recommendedSystematics() const { - return m_recommendedSystematics; - } + inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const; + /* + * @brief Retrieve the recommended systematics list. + * + * This will return a meaningless (probably empty) list unless the + * setter function specifiedSystematics has been called or the tool has + * been initialized (which call specifiedSystematics using the data + * obtained from top::TopConfig). + */ + inline const std::list<CP::SystematicSet>& recommendedSystematics() const; + /*! + * @brief Specify the systematics to be used. + * @param specifiedSystematics Set of systematics (by name) to be used; + * an empty set will result in no systematic variation. + */ + virtual void specifiedSystematics(const std::set<std::string>& specifiedSystematics); + protected: + StatusCode applyNoOpSystematic(xAOD::JetContainer* nominal, + const CP::SystematicSet& syst) const; + + StatusCode applyTruthFilterSystematic(xAOD::JetContainer* nominal, + InDet::InDetTrackTruthFilterTool* tool, + const CP::SystematicSet& syst) const; + + StatusCode applySmearingSystematic(xAOD::JetContainer* nominal, + InDet::InDetTrackSmearingTool* tool, + const CP::SystematicSet& syst) const; + + StatusCode applyBiasingSystematic(xAOD::JetContainer* nominal, + InDet::InDetTrackBiasingTool* tool, + const CP::SystematicSet& syst) const; + + StatusCode applyJetTrackFilterSystematic(xAOD::JetContainer* nominal, + InDet::JetTrackFilterTool* tool, + const CP::SystematicSet& syst) const; + private: + StatusCode retrieveGhostTrackCPTool(); + private: + std::shared_ptr<top::TopConfig> m_config; + double m_jetPtCut, m_jetEtaCut; + std::vector<std::uint32_t> m_runPeriods; + + std::list<CP::SystematicSet> m_specifiedSystematics; + std::list<CP::SystematicSet> m_recommendedSystematics; + + CP::SystematicSet m_nominalSystematicSet; + + + + struct { + void makeUnique() { + static auto exec = [](std::vector<CP::SystematicSet>& data) { + std::sort(data.begin(), data.end()); + data.erase(std::unique(data.begin(), data.end()), + data.end()); + }; + + exec(smearing); + exec(truthFilter); + exec(bias); + exec(jetTrackFilter); + } + + void removeNonSpecified(const std::list<CP::SystematicSet>& specified) { + auto fnCmp = [&specified](CP::SystematicSet& s) { + return std::find(specified.begin(), + specified.end(), + s) == specified.end(); + }; + + auto exec = [&specified, &fnCmp](std::vector<CP::SystematicSet>& data) { + data.erase(std::remove_if(data.begin(), data.end(), fnCmp), + data.end()); + }; + + exec(smearing); + exec(truthFilter); + exec(bias); + exec(jetTrackFilter); + } + + std::size_t numSystematics() const { + return smearing.size() + truthFilter.size() + bias.size() + jetTrackFilter.size(); + } + + std::vector<CP::SystematicSet> smearing, truthFilter, bias, jetTrackFilter; + } m_systs; + + struct { + ToolHandle<InDet::InDetTrackSmearingTool> smearing; + ToolHandle<InDet::InDetTrackTruthOriginTool> truthOrigin; + ToolHandle<InDet::InDetTrackTruthFilterTool> truthFilter; + ToolHandle<InDet::JetTrackFilterTool> jetTrackFilter; + + std::vector<ToolHandle<InDet::InDetTrackBiasingTool> > bias; + } m_tools; + }; + + /* inline virtual */ const std::list<CP::SystematicSet>& GhostTrackSystematicsMaker::specifiedSystematics() const { + return m_specifiedSystematics; + } + + /* inline */ const std::list<CP::SystematicSet>& GhostTrackSystematicsMaker::recommendedSystematics() const { + return m_recommendedSystematics; + } } #endif /* _TOP_GHOSTTRACKSYSTEMATICSMAKER_H_ */ diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/JetObjectCollectionMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/JetObjectCollectionMaker.h index 8bc19a79a689..55ce24c27f7a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/JetObjectCollectionMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/JetObjectCollectionMaker.h @@ -1,28 +1,28 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ -// $Id: JetObjectCollectionMaker.h 794215 2017-01-27 15:12:13Z tpelzer $ +// $Id: JetObjectCollectionMaker.h 809674 2017-08-23 14:10:24Z iconnell $ #ifndef ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_JETOBJECTCOLLECTIONMAKER_H #define ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_JETOBJECTCOLLECTIONMAKER_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief JetObjectCollectionMaker - * Makes all systematic variations of jets - * - * This is actually quite a complex tool - * The steps are as follows - * (1) Calibrate data/MC jets and save this collection to TStore - * (2) Loop over the various NP JES scenarios, using the output of (1) as an input - * (3) Loop over the various NP JER scenarios, using the output of (1) as an input - * (2.a , 3.a) Re-calculate the JVT for each jet - * - * $Revision: 794215 $ - * $Date: 2017-01-27 16:12:13 +0100 (Fri, 27 Jan 2017) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief JetObjectCollectionMaker + * Makes all systematic variations of jets + * + * This is actually quite a complex tool + * The steps are as follows + * (1) Calibrate data/MC jets and save this collection to TStore + * (2) Loop over the various NP JES scenarios, using the output of (1) as an input + * (3) Loop over the various NP JER scenarios, using the output of (1) as an input + * (2.a , 3.a) Re-calculate the JVT for each jet + * + * $Revision: 809674 $ + * $Date: 2017-08-23 15:10:24 +0100 (Wed, 23 Aug 2017) $ + * + **/ // system include(s): #include <memory> @@ -42,119 +42,133 @@ // CP Tool include(s): #include "JetCalibTools/IJetCalibrationTool.h" #include "JetCPInterfaces/ICPJetUncertaintiesTool.h" -#include "JetResolution/IJERSmearingTool.h" #include "JetInterface/IJetUpdateJvt.h" #include "TopJetSubstructure/TopJetSubstructure.h" +#include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h" +#include "JetAnalysisInterfaces/IJetSelectorTool.h" +//#include "ParticleJetTools/JetTruthLabelingTool.h" + // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class JetObjectCollectionMaker final : public asg::AsgTool { - - using systMap = std::unordered_map<CP::SystematicSet,CP::SystematicSet>; - - public: - explicit JetObjectCollectionMaker( const std::string& name ); - virtual ~JetObjectCollectionMaker(){} - - // Delete Standard constructors - JetObjectCollectionMaker(const JetObjectCollectionMaker& rhs) = delete; - JetObjectCollectionMaker(JetObjectCollectionMaker&& rhs) = delete; - JetObjectCollectionMaker& operator=(const JetObjectCollectionMaker& rhs) = delete; - - StatusCode initialize(); - - StatusCode executeJets(); - StatusCode executeLargeRJets(); - StatusCode executeTrackJets(); - - StatusCode printoutJets(); - StatusCode printoutLargeRJets(); - - // return specific Systematic - inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} - inline virtual const std::list<CP::SystematicSet>& specifiedSystematicsLargeR() const {return m_specifiedSystematicsLargeR;} +namespace top { + class JetObjectCollectionMaker final: public asg::AsgTool { + using systMap = std::unordered_map<CP::SystematicSet, CP::SystematicSet>; + public: + explicit JetObjectCollectionMaker(const std::string& name); + virtual ~JetObjectCollectionMaker() {} + + // Delete Standard constructors + JetObjectCollectionMaker(const JetObjectCollectionMaker& rhs) = delete; + JetObjectCollectionMaker(JetObjectCollectionMaker&& rhs) = delete; + JetObjectCollectionMaker& operator = (const JetObjectCollectionMaker& rhs) = delete; + + StatusCode initialize(); + + StatusCode executeJets(bool); + StatusCode executeLargeRJets(bool); + StatusCode executeTrackJets(bool); + + StatusCode printoutJets(); + StatusCode printoutLargeRJets(); + + // return specific Systematic + inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} + inline virtual const std::list<CP::SystematicSet>& specifiedSystematicsLargeR() const { + return m_specifiedSystematicsLargeR; + } + + // return all recommendedSystematics + inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} + protected: - // return all recommendedSystematics - inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} - - protected: - // specify Systematic - virtual void specifiedSystematics( const std::set<std::string>& specifiedSystematics , const ToolHandle<ICPJetUncertaintiesTool>& tool , std::unordered_map<CP::SystematicSet,CP::SystematicSet>& map , const std::string& modName , bool isLargeR = false); - virtual void specifiedSystematics( const std::set<std::string>& specifiedSystematics , const ToolHandle<IJERSmearingTool>& tool , std::unordered_map<CP::SystematicSet,CP::SystematicSet>& map ); - - StatusCode execute( const bool isLargeR ); - - StatusCode calibrate( const bool isLargeR ); - virtual StatusCode applySystematic( ToolHandle<ICPJetUncertaintiesTool>& tool, const std::unordered_map<CP::SystematicSet,CP::SystematicSet>& map , bool isLargeR = false); - virtual StatusCode applySystematic( ToolHandle<IJERSmearingTool>& tool, const std::unordered_map<CP::SystematicSet,CP::SystematicSet>& map ); - - StatusCode printout( const bool isLargeR ); - - void addCorrelation(const std::string& name, - systMap& map_one, - const std::string& syst_one_name, - systMap& map_two, - const std::string& syst_two_name); - - void addCorrelation(const std::string& name, - systMap& map_one, - const std::string& syst_one_name, - std::list<CP::SystematicSet>& jet_specified); - - - private: - std::shared_ptr<top::TopConfig> m_config; - bool m_doJER; - bool m_doFull_JER; - - bool m_do_fjvt = false; - - std::list<CP::SystematicSet> m_specifiedSystematics; - std::list<CP::SystematicSet> m_specifiedSystematicsLargeR; - std::list<CP::SystematicSet> m_specifiedSystematicsTrackJets; - std::list<CP::SystematicSet> m_recommendedSystematics; - CP::SystematicSet m_nominalSystematicSet; - - ToolHandle<IJetCalibrationTool> m_jetCalibrationTool; - ToolHandle<IJetCalibrationTool> m_jetCalibrationToolLargeR; - - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesTool; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario1; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario2; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario3; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario4; - - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolLargeR_strong; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolLargeR_medium; - ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolLargeR_weak; - - ToolHandle<IJERSmearingTool> m_jetJERSmearingTool; - ToolHandle<IJetUpdateJvt> m_jetUpdateJvtTool; - ToolHandle<IJetModifier> m_fjvtTool; - - std::string m_truthJetCollForHS; - - std::unique_ptr<top::TopJetSubstructure> m_jetSubstructure; - - systMap m_systMap_AllNP; - systMap m_systMap_ReducedNPScenario1; - systMap m_systMap_ReducedNPScenario2; - systMap m_systMap_ReducedNPScenario3; - systMap m_systMap_ReducedNPScenario4; - systMap m_systMap_LargeR_strong; - systMap m_systMap_LargeR_medium; - systMap m_systMap_LargeR_weak; - systMap m_systMap_JER; - typedef std::unordered_map<CP::SystematicSet,CP::SystematicSet>::const_iterator Itr; - - StatusCode decorateBJets(xAOD::Jet& jet); - StatusCode decorateHSJets(); + // Function will return prefix which will be added to systematic names obtained from tools + virtual std::string getLargeRModName(const std::string& NPModel) const; + // specify Systematic + virtual void addSystematics(const std::set<std::string>& specifiedSystematics, + const CP::SystematicSet& recommendedSysts, std::unordered_map<CP::SystematicSet, + CP::SystematicSet>& map, + const std::string& modName, bool isLargeR = false, + bool onlyJER = false); + + StatusCode execute(const bool isLargeR, bool executeNominal); + + StatusCode calibrate(const bool isLargeR); + virtual StatusCode applySystematic(ToolHandle<ICPJetUncertaintiesTool>& tool, + const std::unordered_map<CP::SystematicSet, CP::SystematicSet>& map, + bool isLargeR = false); + + StatusCode printout(const bool isLargeR); + + private: + std::shared_ptr<top::TopConfig> m_config; + bool m_doJER; + bool m_doFull_JER; + bool m_doFull_JER_Pseudodata; + bool m_isMC; + bool m_doMultipleJES; + bool m_do_fjvt = false; + + std::list<CP::SystematicSet> m_specifiedSystematics; + std::list<CP::SystematicSet> m_specifiedSystematicsLargeR; + std::list<CP::SystematicSet> m_specifiedSystematicsTrackJets; + std::list<CP::SystematicSet> m_recommendedSystematics; + CP::SystematicSet m_nominalSystematicSet; + + ToolHandle<IJetCalibrationTool> m_jetCalibrationTool; + ToolHandle<IJetCalibrationTool> m_jetCalibrationToolLargeR; + + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesTool; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolFrozenJMS; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario1; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario2; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario3; + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolReducedNPScenario4; + + ToolHandle<ICPJetUncertaintiesTool> m_jetUncertaintiesToolLargeR; + std::unordered_map<std::string, ToolHandle<ICPJetUncertaintiesTool> > m_tagSFuncertTool; + + // do decorate the large-R jets with the boosted-tagging flags + // and decorate jets with TAccept object containing detailed tag result informaiton + // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/BoostedJetTaggingRecommendation2017#TAcceptUsageSection + std::unordered_map<std::string, ToolHandle<IJetSelectorTool> > m_boostedJetTaggers; + + ToolHandle<IJetUpdateJvt> m_jetUpdateJvtTool; + ToolHandle<IJetModifier> m_jetSelectfJvtTool; + + std::string m_truthJetCollForHS; + + std::unique_ptr<top::TopJetSubstructure> m_jetSubstructure; + + systMap m_systMap_AllNP; + systMap m_systMap_AllNP_FrozenJMS; + systMap m_systMap_ReducedNPScenario1; + systMap m_systMap_ReducedNPScenario2; + systMap m_systMap_ReducedNPScenario3; + systMap m_systMap_ReducedNPScenario4; + systMap m_systMap_LargeR; + + typedef std::unordered_map<CP::SystematicSet, CP::SystematicSet>::const_iterator Itr; + + StatusCode decorateBJets(xAOD::Jet& jet); + StatusCode decorateHSJets(); + StatusCode decorateMatchedTruth(); + StatusCode tagLargeRJet(const xAOD::Jet& jet); + StatusCode tagNominalLargeRJets(); + + ///-- Large R jet truth labeling --/// +// std::unique_ptr<JetTruthLabelingTool> m_jetTruthLabelingTool; + + // DL1 decoration + std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool> > m_btagSelToolsDL1Decor; + std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool> > m_btagSelToolsDL1Decor_trkJet; + StatusCode decorateDL1(bool trackJets = false); + + std::unordered_map<std::string, SG::AuxElement::Decorator<float>> DLx; }; } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/MissingETObjectCollectionMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/MissingETObjectCollectionMaker.h index d23a7cc679d8..a13fedc6878a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/MissingETObjectCollectionMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/MissingETObjectCollectionMaker.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: MissingETObjectCollectionMaker.h 683191 2015-07-15 16:05:25Z morrisj $ #ifndef ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_MISSINGETOBJECTCOLLECTIONMAKER_H #define ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_MISSINGETOBJECTCOLLECTIONMAKER_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief MissingETObjectCollectionMaker - * Makes all systematic variations of Missing ET - * - * $Revision: 683191 $ - * $Date: 2015-07-15 18:05:25 +0200 (Wed, 15 Jul 2015) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief MissingETObjectCollectionMaker + * Makes all systematic variations of Missing ET + * + * $Revision: 683191 $ + * $Date: 2015-07-15 17:05:25 +0100 (Wed, 15 Jul 2015) $ + * + **/ // system include(s): #include <memory> @@ -30,57 +30,53 @@ #include "METInterface/IMETMaker.h" #include "METInterface/IMETSystematicsTool.h" -namespace xAOD{ +namespace xAOD { class SystematicEvent; } -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class MissingETObjectCollectionMaker final : public asg::AsgTool { - public: - explicit MissingETObjectCollectionMaker( const std::string& name ); - virtual ~MissingETObjectCollectionMaker(){} - - // Delete Standard constructors - MissingETObjectCollectionMaker(const MissingETObjectCollectionMaker& rhs ) = delete; - MissingETObjectCollectionMaker(MissingETObjectCollectionMaker&& rhs ) = delete; - MissingETObjectCollectionMaker& operator=(const MissingETObjectCollectionMaker& rhs ) = delete; - - StatusCode initialize(); - StatusCode recalculateMET(); - - // return specific Systematic - inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} - - // return all recommendedSystematics - inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} - - protected: - // specify Systematic - virtual void specifiedSystematics( const std::set<std::string>& specifiedSystematics ); - - - private: - - StatusCode recalculateEventMET( xAOD::SystematicEvent* event, - const xAOD::MissingETContainer* met_core, - const xAOD::MissingETAssociationMap* met_map); - - std::shared_ptr<top::TopConfig> m_config; - - std::list<CP::SystematicSet> m_specifiedSystematics; - std::list<CP::SystematicSet> m_recommendedSystematics; - - std::string m_MET_core; - std::string m_MET_map; - - ToolHandle<IMETMaker> m_met_maker; - ToolHandle<IMETSystematicsTool> m_met_systematics; - +namespace top { + class MissingETObjectCollectionMaker final: public asg::AsgTool { + public: + explicit MissingETObjectCollectionMaker(const std::string& name); + virtual ~MissingETObjectCollectionMaker() {} + + // Delete Standard constructors + MissingETObjectCollectionMaker(const MissingETObjectCollectionMaker& rhs) = delete; + MissingETObjectCollectionMaker(MissingETObjectCollectionMaker&& rhs) = delete; + MissingETObjectCollectionMaker& operator = (const MissingETObjectCollectionMaker& rhs) = delete; + + StatusCode initialize(); + StatusCode recalculateMET(bool); + + // return specific Systematic + inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} + + // return all recommendedSystematics + inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} + protected: + // specify Systematic + virtual void specifiedSystematics(const std::set<std::string>& specifiedSystematics); + private: + StatusCode recalculateEventMET(const xAOD::SystematicEvent* event, + const xAOD::MissingETContainer* met_core, + const xAOD::MissingETAssociationMap* met_map, + bool forceUseLooseObjects=false, + std::string outputContainerSuffix=""); + + std::shared_ptr<top::TopConfig> m_config; + + std::list<CP::SystematicSet> m_specifiedSystematics; + std::list<CP::SystematicSet> m_recommendedSystematics; + + std::string m_MET_core; + std::string m_MET_map; + + ToolHandle<IMETMaker> m_met_maker; + ToolHandle<IMETSystematicsTool> m_met_systematics; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/MuonObjectCollectionMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/MuonObjectCollectionMaker.h index 090e939feddc..a70c2ae72053 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/MuonObjectCollectionMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/MuonObjectCollectionMaker.h @@ -1,22 +1,23 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + */ +// $Id: MuonObjectCollectionMaker.h 799839 2017-03-08 11:07:28Z grancagn $ #ifndef ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_MUONOBJECTCOLLECTIONMAKER_H #define ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_MUONOBJECTCOLLECTIONMAKER_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief MuonObjectCollectionMaker - * Makes all systematic variations of muons. - * Momentum Corrections are applied using the calibration tool. - * Efficiency Corrections are applied using the efficiency tool. - * - * $Revision: 799839 $ - * $Date: 2017-03-08 12:07:28 +0100 (Wed, 08 Mar 2017) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief MuonObjectCollectionMaker + * Makes all systematic variations of muons. + * Momentum Corrections are applied using the calibration tool. + * Efficiency Corrections are applied using the efficiency tool. + * + * $Revision: 799839 $ + * $Date: 2017-03-08 11:07:28 +0000 (Wed, 08 Mar 2017) $ + * + **/ // system include(s): #include <memory> @@ -33,60 +34,78 @@ // CP Tool include(s): #include "MuonAnalysisInterfaces/IMuonCalibrationAndSmearingTool.h" #include "IsolationSelection/IIsolationSelectionTool.h" +//#include "IsolationSelection/IIsolationLowPtPLVTool.h" // the following is needed to make sure all muons for which d0sig is calculated are at least Loose #include "MuonAnalysisInterfaces/IMuonSelectionTool.h" - +#include "MuonMomentumCorrections/MuonCalibrationPeriodTool.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ - - class MuonObjectCollectionMaker final : public asg::AsgTool { - public: - explicit MuonObjectCollectionMaker( const std::string& name ); - virtual ~MuonObjectCollectionMaker(){} - - // Delete Standard constructors - MuonObjectCollectionMaker(const MuonObjectCollectionMaker& rhs) = delete; - MuonObjectCollectionMaker(MuonObjectCollectionMaker&& rhs) = delete; - MuonObjectCollectionMaker& operator=(const MuonObjectCollectionMaker& rhs) = delete; - - StatusCode initialize(); - StatusCode execute(); - - StatusCode printout(); - - // return specific Systematic - inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} - - // return all recommendedSystematics - inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} - - protected: - // specify Systematic - virtual void specifiedSystematics( const std::set<std::string>& specifiedSystematics ); - - private: - std::shared_ptr<top::TopConfig> m_config; - - std::list<CP::SystematicSet> m_specifiedSystematics; - std::list<CP::SystematicSet> m_recommendedSystematics; - - ToolHandle<CP::IMuonCalibrationAndSmearingTool> m_calibrationTool; - - ///-- Isolation --/// - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_LooseTrackOnly; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Loose; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Gradient; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_GradientLoose; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutTight; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutTightTrackOnly; - ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutLoose; - // the following is needed to make sure all muons for which d0sig is calculated are at least Loose - ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolVeryLooseVeto; - +namespace top { + class MuonObjectCollectionMaker final: public asg::AsgTool { + public: + explicit MuonObjectCollectionMaker(const std::string& name); + virtual ~MuonObjectCollectionMaker() {} + + // Delete Standard constructors + MuonObjectCollectionMaker(const MuonObjectCollectionMaker& rhs) = delete; + MuonObjectCollectionMaker(MuonObjectCollectionMaker&& rhs) = delete; + MuonObjectCollectionMaker& operator = (const MuonObjectCollectionMaker& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(bool); + + StatusCode printout(); + + // return specific Systematic + inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} + + // return all recommendedSystematics + inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} + protected: + // specify Systematic + virtual void specifiedSystematics(const std::set<std::string>& specifiedSystematics); + private: + std::shared_ptr<top::TopConfig> m_config; + + std::list<CP::SystematicSet> m_specifiedSystematics; + std::list<CP::SystematicSet> m_recommendedSystematics; + + ToolHandle<CP::IMuonCalibrationAndSmearingTool> m_calibrationPeriodTool; + ToolHandle<CP::IMuonCalibrationAndSmearingTool> m_calibrationTool2017; + + ///-- Isolation --/// + //until release 21.2.110 these are the used WPs + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCTight; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCLoose; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCTightTrackOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCTightTrackOnly_FixedRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCLoose_FixedRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FCTight_FixedRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutPflowTight; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_FixedCutPflowLoose; + //since release 21.2.111 these are the used WPs + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PflowTight_FixedRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PflowLoose_FixedRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PflowTight_VarRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PflowLoose_VarRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_HighPtTrackOnly; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_TightTrackOnly_VarRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_TightTrackOnly_FixedRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PLVTight; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_PLVLoose; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Tight_VarRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Tight_FixedRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Loose_VarRad; + ToolHandle<CP::IIsolationSelectionTool> m_isolationTool_Loose_FixedRad; + +// ToolHandle<CP::IIsolationLowPtPLVTool> m_isolationTool_LowPtPLV; + // the following is needed to make sure all muons for which d0sig is calculated are at least Loose + ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolVeryLooseVeto; + + bool m_isFirstEvent; }; } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/ObjectCollectionMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/ObjectCollectionMaker.h index 01d2625df73d..7edb717ef26a 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/ObjectCollectionMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/ObjectCollectionMaker.h @@ -1,21 +1,21 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + */ // $Id: ObjectCollectionMaker.h 790414 2016-12-19 00:49:08Z tpelzer $ #ifndef ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_OBJECTCOLLECTIONMAKER_H #define ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_OBJECTCOLLECTIONMAKER_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief ObjectCollectionMaker - * Makes all systematic variations of all objects - * - * $Revision: 790414 $ - * $Date: 2016-12-19 01:49:08 +0100 (Mon, 19 Dec 2016) $ - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief ObjectCollectionMaker + * Makes all systematic variations of all objects + * + * $Revision: 790414 $ + * $Date: 2016-12-19 00:49:08 +0000 (Mon, 19 Dec 2016) $ + * + **/ // system include(s): #include <vector> @@ -29,45 +29,48 @@ #include "TopSystematicObjectMaker/EgammaObjectCollectionMaker.h" #include "TopSystematicObjectMaker/MuonObjectCollectionMaker.h" +#include "TopSystematicObjectMaker/SoftMuonObjectCollectionMaker.h" #include "TopSystematicObjectMaker/TauObjectCollectionMaker.h" #include "TopSystematicObjectMaker/JetObjectCollectionMaker.h" #include "TopSystematicObjectMaker/MissingETObjectCollectionMaker.h" #include "TopSystematicObjectMaker/GhostTrackSystematicsMaker.h" +#include "TopSystematicObjectMaker/TrackSystematicsMaker.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ +namespace top { + class ObjectCollectionMaker final: public asg::AsgTool { + public: + explicit ObjectCollectionMaker(const std::string& name); + virtual ~ObjectCollectionMaker() {} - class ObjectCollectionMaker final : public asg::AsgTool { - public: - explicit ObjectCollectionMaker( const std::string& name ); - virtual ~ObjectCollectionMaker() {} + ObjectCollectionMaker(const ObjectCollectionMaker& rhs) = delete; + ObjectCollectionMaker(ObjectCollectionMaker&& rhs) = delete; + ObjectCollectionMaker& operator = (const ObjectCollectionMaker& rhs) = delete; - ObjectCollectionMaker(const ObjectCollectionMaker& rhs) = delete; - ObjectCollectionMaker(ObjectCollectionMaker&& rhs) = delete; - ObjectCollectionMaker& operator=(const ObjectCollectionMaker& rhs) = delete; + StatusCode initialize(); + StatusCode execute(bool); + StatusCode executeNominal(); + StatusCode executeSystematics(); + StatusCode recalculateMET(bool); + StatusCode printout(); - StatusCode initialize(); - StatusCode execute(); - StatusCode recalculateMET(); - StatusCode printout(); - - bool isTruthDxAOD() const; + bool isTruthDxAOD() const; + private: + std::shared_ptr<top::TopConfig> m_config; + std::unique_ptr<top::EgammaObjectCollectionMaker> m_egammaMaker; + std::unique_ptr<top::MuonObjectCollectionMaker> m_muonMaker; + std::unique_ptr<top::SoftMuonObjectCollectionMaker> m_softmuonMaker; + std::unique_ptr<top::TauObjectCollectionMaker> m_tauMaker; + std::unique_ptr<top::JetObjectCollectionMaker> m_jetMaker; + std::unique_ptr<top::MissingETObjectCollectionMaker> m_metMaker; + std::unique_ptr<top::GhostTrackSystematicsMaker> m_ghostTrackSystMaker; + std::unique_ptr<top::TrackSystematicsMaker> m_trackSystMaker; - private: - - std::shared_ptr<top::TopConfig> m_config; - std::unique_ptr<top::EgammaObjectCollectionMaker> m_egammaMaker; - std::unique_ptr<top::MuonObjectCollectionMaker> m_muonMaker; - std::unique_ptr<top::TauObjectCollectionMaker> m_tauMaker; - std::unique_ptr<top::JetObjectCollectionMaker> m_jetMaker; - std::unique_ptr<top::MissingETObjectCollectionMaker> m_metMaker; - std::unique_ptr<top::GhostTrackSystematicsMaker> m_ghostTrackSystMaker; }; - } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/SoftMuonObjectCollectionMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/SoftMuonObjectCollectionMaker.h new file mode 100644 index 000000000000..d1347b17b051 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/SoftMuonObjectCollectionMaker.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_SOFTMUONOBJECTCOLLECTIONMAKER_H +#define ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_SOFTMUONOBJECTCOLLECTIONMAKER_H + +/** + * @author Marco Vanadia <marco.vanadia@cern.ch> + * + * @brief SoftMuonObjectCollectionMaker + * Makes all systematic variations of soft muons. + * Momentum Corrections are applied using the calibration tool. + * Efficiency Corrections are applied using the efficiency tool. + * + **/ + +// system include(s): +#include <memory> +#include <set> +#include <list> + +// Framework include(s): +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +// Systematic include(s): +#include "PATInterfaces/SystematicSet.h" + +// CP Tool include(s): +#include "MuonAnalysisInterfaces/IMuonCalibrationAndSmearingTool.h" +//#include "IsolationSelection/IIsolationSelectionTool.h" +#include "MuonAnalysisInterfaces/IMuonSelectionTool.h" +#include "MuonMomentumCorrections/MuonCalibrationPeriodTool.h" +// Forward declaration(s): +namespace top { + class TopConfig; +} + +namespace top { + class SoftMuonObjectCollectionMaker final: public asg::AsgTool { + public: + explicit SoftMuonObjectCollectionMaker(const std::string& name); + virtual ~SoftMuonObjectCollectionMaker() {} + + // Delete Standard constructors + SoftMuonObjectCollectionMaker(const SoftMuonObjectCollectionMaker& rhs) = delete; + SoftMuonObjectCollectionMaker(SoftMuonObjectCollectionMaker&& rhs) = delete; + SoftMuonObjectCollectionMaker& operator = (const SoftMuonObjectCollectionMaker& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(bool); + + StatusCode printout(); + + // return specific Systematic + inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} + + // return all recommendedSystematics + inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} + protected: + // specify Systematic + virtual void specifiedSystematics(const std::set<std::string>& specifiedSystematics); + private: + + std::shared_ptr<top::TopConfig> m_config; + std::list<CP::SystematicSet> m_specifiedSystematics; + std::list<CP::SystematicSet> m_recommendedSystematics; + + ToolHandle<CP::IMuonCalibrationAndSmearingTool> m_calibrationPeriodTool; + ToolHandle<CP::IMuonCalibrationAndSmearingTool> m_calibrationTool2017; + + // the following is needed to make sure all muons for which d0sig is calculated are at least Loose + ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolVeryLooseVeto; + }; +} // namespace +#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/TauObjectCollectionMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/TauObjectCollectionMaker.h index 7202821469a0..40f3b039d83c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/TauObjectCollectionMaker.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/TauObjectCollectionMaker.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ // $Id: TauObjectCollectionMaker.h $ #ifndef ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_TAUOBJECTCOLLECTIONMAKER_H #define ANALYSISTOP_TOPSYSTEMATICOBJECTMAKER_TAUOBJECTCOLLECTIONMAKER_H /** - * @author John Morris <john.morris@cern.ch> - * - * @brief TauObjectCollectionMaker - * Makes all systematic variations of taus - * - * - **/ + * @author John Morris <john.morris@cern.ch> + * + * @brief TauObjectCollectionMaker + * Makes all systematic variations of taus + * + * + **/ // system include(s): #include <memory> @@ -32,45 +32,42 @@ #include "TauAnalysisTools/ITauTruthMatchingTool.h" // Forward declaration(s): -namespace top{ +namespace top { class TopConfig; } -namespace top{ +namespace top { + class TauObjectCollectionMaker final: public asg::AsgTool { + public: + explicit TauObjectCollectionMaker(const std::string& name); + virtual ~TauObjectCollectionMaker() {} - class TauObjectCollectionMaker final : public asg::AsgTool { - public: - explicit TauObjectCollectionMaker( const std::string& name ); - virtual ~TauObjectCollectionMaker(){} + // Delete Standard constructors + TauObjectCollectionMaker(const TauObjectCollectionMaker& rhs) = delete; + TauObjectCollectionMaker(TauObjectCollectionMaker&& rhs) = delete; + TauObjectCollectionMaker& operator = (const TauObjectCollectionMaker& rhs) = delete; - // Delete Standard constructors - TauObjectCollectionMaker(const TauObjectCollectionMaker& rhs) = delete; - TauObjectCollectionMaker(TauObjectCollectionMaker&& rhs) = delete; - TauObjectCollectionMaker& operator=(const TauObjectCollectionMaker& rhs) = delete; + StatusCode initialize(); + StatusCode execute(bool); - StatusCode initialize(); - StatusCode execute(); + StatusCode printout(); - StatusCode printout(); + // return specific Systematic + inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} - // return specific Systematic - inline virtual const std::list<CP::SystematicSet>& specifiedSystematics() const {return m_specifiedSystematics;} - - // return all recommendedSystematics - inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} + // return all recommendedSystematics + inline const std::list<CP::SystematicSet>& recommendedSystematics() const {return m_recommendedSystematics;} + protected: + // specify Systematic + virtual void specifiedSystematics(const std::set<std::string>& specifiedSystematics); + private: + std::shared_ptr<top::TopConfig> m_config; - protected: - // specify Systematic - virtual void specifiedSystematics( const std::set<std::string>& specifiedSystematics ); + std::list<CP::SystematicSet> m_specifiedSystematics; + std::list<CP::SystematicSet> m_recommendedSystematics; - private: - std::shared_ptr<top::TopConfig> m_config; - - std::list<CP::SystematicSet> m_specifiedSystematics; - std::list<CP::SystematicSet> m_recommendedSystematics; - - ToolHandle<TauAnalysisTools::ITauSmearingTool> m_calibrationTool; - + ToolHandle<TauAnalysisTools::ITauSmearingTool> m_calibrationTool; + ToolHandle<TauAnalysisTools::ITauTruthMatchingTool> m_truthMatchingTool; }; } // namespace #endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/TrackSystematicsMaker.h b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/TrackSystematicsMaker.h new file mode 100644 index 000000000000..910aa4c86fb5 --- /dev/null +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/TopSystematicObjectMaker/TrackSystematicsMaker.h @@ -0,0 +1,152 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +// modified base on GhostTrackSystematicsMaker.h from Fabian Wilk +// Description: +// Author: Andrea Knue +// Created: June 2020 + + +#ifndef _TOP_TRACKSYSTEMATICSMAKER_H_ +#define _TOP_TRACKSYSTEMATICSMAKER_H_ + +#include <list> +#include <set> +#include <string> +#include <vector> +#include <utility> + +// Framework include(s): +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +#include "PATInterfaces/SystematicSet.h" + +#include "xAODTracking/TrackParticleContainer.h" + + +// Forward Declarations. +namespace InDet { + class InDetTrackSystematicsTool; + class InDetTrackSmearingTool; + class InDetTrackBiasingTool; + class InDetTrackTruthFilterTool; + class InDetTrackTruthOriginTool; +} + +namespace top { + class TopConfig; +} + +namespace top { + + class TrackSystematicsMaker final: public asg::AsgTool { + public: + explicit TrackSystematicsMaker(const std::string& name); + virtual ~TrackSystematicsMaker(); + + TrackSystematicsMaker(const TrackSystematicsMaker& rhs) = delete; + TrackSystematicsMaker(TrackSystematicsMaker&& rhs) = delete; + TrackSystematicsMaker& operator = (const TrackSystematicsMaker& rhs) = delete; + + StatusCode initialize(); + StatusCode execute(bool); + + /* + * @brief Retrieve the specified (requested) systematics list.* + * + * Unless systematics have been requested through the + * specifiedSystematics setter function, this will be an empty list. + */ + inline const std::list<CP::SystematicSet>& specifiedSystematics() const; + + /* + * @brief Retrieve the recommended systematics list. + * + * This will return a meaningless (probably empty) list unless the + * setter function specifiedSystematics has been called or the tool has + * been initialized (which call specifiedSystematics using the data + * obtained from top::TopConfig). + */ + inline const std::list<CP::SystematicSet>& recommendedSystematics() const; + + /*! + * @brief Specify the systematics to be used. + * @param specifiedSystematics Set of systematics (by name) to be used; + * an empty set will result in no systematic variation. + */ + virtual void specifiedSystematics(const std::set<std::string>& specifiedSystematics); + + protected: + + + StatusCode applyTruthFilterSystematic(InDet::InDetTrackTruthFilterTool* tool, + const CP::SystematicSet& syst) const; + + StatusCode applySmearingSystematic(InDet::InDetTrackSmearingTool* tool, + const CP::SystematicSet& syst) const; + + StatusCode applyBiasingSystematic(InDet::InDetTrackBiasingTool* tool, + const CP::SystematicSet& syst) const; + + private: + StatusCode retrieveTrackCPTool(); + private: + std::shared_ptr<top::TopConfig> m_config; + std::vector<std::uint32_t> m_runPeriods; + + std::list<CP::SystematicSet> m_specifiedSystematics; + std::list<CP::SystematicSet> m_recommendedSystematics; + + CP::SystematicSet m_nominalSystematicSet; + + + + struct { + void makeUnique() { + static auto exec = [](std::vector<CP::SystematicSet>& data) { + std::sort(data.begin(), data.end()); + data.erase(std::unique(data.begin(), data.end()), + data.end()); + }; + + exec(smearing); + exec(truthFilter); + exec(bias); + } + + void removeNonSpecified(const std::list<CP::SystematicSet>& specified) { + auto fnCmp = [&specified](CP::SystematicSet& s) { + return std::find(specified.begin(), + specified.end(), + s) == specified.end(); + }; + + auto exec = [&specified, &fnCmp](std::vector<CP::SystematicSet>& data) { + data.erase(std::remove_if(data.begin(), data.end(), fnCmp), + data.end()); + }; + + exec(smearing); + exec(truthFilter); + exec(bias); + } + + std::size_t numSystematics() const { + return smearing.size() + truthFilter.size() + bias.size(); + } + + std::vector<CP::SystematicSet> smearing, truthFilter, bias; + } m_systs; + + ToolHandle<InDet::InDetTrackSmearingTool> m_smearingTool; + std::vector<ToolHandle<InDet::InDetTrackBiasingTool> > m_biasTool; + ToolHandle<InDet::InDetTrackTruthOriginTool> m_truthOriginTool; + ToolHandle<InDet::InDetTrackTruthFilterTool> m_truthFilterTool; + + }; + +} + +#endif /* _TOP_TRACKSYSTEMATICSMAKER_H_ */ -- GitLab From 9ad13105c6804054d88e2bd93ec3fc95b7e553ed Mon Sep 17 00:00:00 2001 From: Tomas Dado <tomas.dado@cern.ch> Date: Mon, 26 Oct 2020 14:31:08 +0100 Subject: [PATCH 03/12] Adding AT packages to package_filters --- Projects/AnalysisBase/package_filters.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Projects/AnalysisBase/package_filters.txt b/Projects/AnalysisBase/package_filters.txt index 274072529144..23b1f409e490 100644 --- a/Projects/AnalysisBase/package_filters.txt +++ b/Projects/AnalysisBase/package_filters.txt @@ -125,4 +125,23 @@ + Trigger/TrigSteer/TrigCompositeUtils #+ Trigger/TrigValidation/TrigAnalysisTest +# +### AnalysisTop packages +# + ++ PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation ++ PhysicsAnalysis/TopPhys/xAOD/TopAnalysis ++ PhysicsAnalysis/TopPhys/xAOD/TopCPTools ++ PhysicsAnalysis/TopPhys/xAOD/TopConfiguration ++ PhysicsAnalysis/TopPhys/xAOD/TopCorrections ++ PhysicsAnalysis/TopPhys/xAOD/TopEvent ++ PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools ++ PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools ++ PhysicsAnalysis/TopPhys/xAOD/TopExamples ++ PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure ++ PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools ++ PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel ++ PhysicsAnalysis/TopPhys/xAOD/TopPartons ++ PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker + - .* -- GitLab From 50b06310839e8a68ccb786047e1d6b61658c171a Mon Sep 17 00:00:00 2001 From: Tomas Dado <tomas.dado@cern.ch> Date: Mon, 26 Oct 2020 15:28:11 +0100 Subject: [PATCH 04/12] Fixing compilation warnings + changes needed for recent master --- .../TopAnalysis/Root/EventSaverFlatNtuple.cxx | 146 +++++++++--------- .../TopAnalysis/Root/EventSaverxAODNext.cxx | 24 +-- .../xAOD/TopAnalysis/util/top-xaod.cxx | 4 +- .../Root/ExamplePlots.cxx | 6 - .../Root/GlobalTrigDecisionSelector.cxx | 2 +- .../Root/GlobalTrigMatchSelector.cxx | 2 +- .../Root/IP3DSV1Selector.cxx | 22 --- .../Root/MV1Selector.cxx | 23 --- .../Root/MV2c10Selector.cxx | 8 +- .../Root/MV2c20Selector.cxx | 31 ---- .../TopEventSelectionTools/IP3DSV1Selector.h | 27 ---- .../TopEventSelectionTools/MV1Selector.h | 25 --- .../TopEventSelectionTools/MV2c20Selector.h | 38 ----- .../xAOD/TopExamples/Root/DefaultPlots.cxx | 2 +- .../TopExamples/Root/LJetsTtresAnalysis.cxx | 4 +- .../Root/EventCleaningSelection.cxx | 4 +- .../Root/JetObjectCollectionMaker.cxx | 23 +-- .../Root/MissingETObjectCollectionMaker.cxx | 10 +- 18 files changed, 116 insertions(+), 285 deletions(-) delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/IP3DSV1Selector.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV1Selector.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c20Selector.cxx delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/IP3DSV1Selector.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV1Selector.h delete mode 100644 PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV2c20Selector.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverFlatNtuple.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverFlatNtuple.cxx index a038ef355770..980df371278e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverFlatNtuple.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverFlatNtuple.cxx @@ -1112,20 +1112,20 @@ namespace top { } if (m_config->useTracks()) { - systematicTree->makeOutputVariable(m_track_pt, "track_pt"); - systematicTree->makeOutputVariable(m_track_eta, "track_eta"); - systematicTree->makeOutputVariable(m_track_phi, "track_phi"); - systematicTree->makeOutputVariable(m_track_e, "track_e"); - systematicTree->makeOutputVariable(m_track_charge, "track_charge"); - systematicTree->makeOutputVariable(m_track_d0, "track_d0"); - systematicTree->makeOutputVariable(m_track_d0_significance, "track_d0_significance"); - systematicTree->makeOutputVariable(m_track_z0, "track_z0"); - systematicTree->makeOutputVariable(m_track_z0_significance, "track_z0_significance"); - systematicTree->makeOutputVariable(m_track_phi0, "track_phi0"); - systematicTree->makeOutputVariable(m_track_theta, "track_theta"); - systematicTree->makeOutputVariable(m_track_qOverP, "track_qOverP"); - systematicTree->makeOutputVariable(m_track_chiSquared, "track_chiSquared"); - systematicTree->makeOutputVariable(m_track_numberDoF, "track_numberDoF"); + systematicTree->makeOutputVariable(m_track_pt, "track_pt"); + systematicTree->makeOutputVariable(m_track_eta, "track_eta"); + systematicTree->makeOutputVariable(m_track_phi, "track_phi"); + systematicTree->makeOutputVariable(m_track_e, "track_e"); + systematicTree->makeOutputVariable(m_track_charge, "track_charge"); + systematicTree->makeOutputVariable(m_track_d0, "track_d0"); + systematicTree->makeOutputVariable(m_track_d0_significance, "track_d0_significance"); + systematicTree->makeOutputVariable(m_track_z0, "track_z0"); + systematicTree->makeOutputVariable(m_track_z0_significance, "track_z0_significance"); + systematicTree->makeOutputVariable(m_track_phi0, "track_phi0"); + systematicTree->makeOutputVariable(m_track_theta, "track_theta"); + systematicTree->makeOutputVariable(m_track_qOverP, "track_qOverP"); + systematicTree->makeOutputVariable(m_track_chiSquared, "track_chiSquared"); + systematicTree->makeOutputVariable(m_track_numberDoF, "track_numberDoF"); } @@ -2782,8 +2782,8 @@ namespace top { m_jet_phi[i] = jetPtr->phi(); m_jet_e[i] = jetPtr->e(); // In R21, list of b-tagging variables is changing and this is outdated - const xAOD::BTagging* btag(nullptr); - btag = jetPtr->btagging(); + //const xAOD::BTagging* btag(nullptr); + //btag = jetPtr->btagging(); if (m_config->isMC()) { m_jet_truthflav[i] = -99; if (jetPtr->isAvailable<int>("HadronConeExclTruthLabelID")) { @@ -2888,7 +2888,7 @@ namespace top { if (m_config->bTagAlgo_MV2c10_used()) { double mvx = -999; - if (btag) btag->MVx_discriminant("MV2c10", mvx); + //if (btag) btag->MVx_discriminant("MV2c10", mvx); m_jet_mv2c10[i] = mvx; } @@ -2913,27 +2913,27 @@ namespace top { // calculated by BtaggingSelectionTool for (const std::string& algo : m_config->bTagAlgo_available()) { std::vector<float>& m_jet_DLx_pick = m_jet_DLx.at(algo); - std::vector<float>& m_jet_DLx_pb_pick = m_jet_DLx_pb.at(algo); - std::vector<float>& m_jet_DLx_pc_pick = m_jet_DLx_pc.at(algo); - std::vector<float>& m_jet_DLx_pu_pick = m_jet_DLx_pu.at(algo); + //std::vector<float>& m_jet_DLx_pb_pick = m_jet_DLx_pb.at(algo); + //std::vector<float>& m_jet_DLx_pc_pick = m_jet_DLx_pc.at(algo); + //std::vector<float>& m_jet_DLx_pu_pick = m_jet_DLx_pu.at(algo); const SG::AuxElement::ConstAccessor<float>& DLx_acc = DLx.at(algo); i = 0; for (const auto* const jetPtr : event.m_jets) { m_jet_DLx_pick[i] = DLx_acc(*jetPtr); - const xAOD::BTagging* btag(nullptr); - btag = jetPtr->btagging(); - if (btag) { - double pu = -999; - double pc = -999; - double pb = -999; - btag->pu(algo, pu); - btag->pc(algo, pc); - btag->pb(algo, pb); - m_jet_DLx_pb_pick[i] = pb; - m_jet_DLx_pc_pick[i] = pc; - m_jet_DLx_pu_pick[i] = pu; - } + //const xAOD::BTagging* btag(nullptr); + //btag = jetPtr->btagging(); + //if (btag) { + // double pu = -999; + // double pc = -999; + // double pb = -999; + // btag->pu(algo, pu); + // btag->pc(algo, pc); + // btag->pb(algo, pb); + // m_jet_DLx_pb_pick[i] = pb; + // m_jet_DLx_pc_pick[i] = pc; + // m_jet_DLx_pu_pick[i] = pu; + //} ++i; } } @@ -3208,9 +3208,9 @@ namespace top { m_ljet_e[i] = jetPtr->e(); m_ljet_m[i] = jetPtr->m(); - for (const std::pair<std::string,std::string>& it : m_config->largeRJetSubstructureVariables()) { - m_ljet_substructure[it.first][i] = jetPtr->isAvailable<float>(it.second) ? jetPtr->auxdata<float>(it.second) : -999; - } + for (const std::pair<std::string,std::string>& it : m_config->largeRJetSubstructureVariables()) { + m_ljet_substructure[it.first][i] = jetPtr->isAvailable<float>(it.second) ? jetPtr->auxdata<float>(it.second) : -999; + } for (const std::string& taggerName : m_boostedJetTaggersNames) { m_ljet_isTagged[taggerName][i] = jetPtr->getAttribute<char>("isTagged_" + taggerName); @@ -3270,10 +3270,10 @@ namespace top { m_tjet_e[i] = jetPtr->e(); if (m_config->bTagAlgo_MV2c10_used_trkJet()) { - const xAOD::BTagging* btag(nullptr); - btag = jetPtr->btagging(); + //const xAOD::BTagging* btag(nullptr); + //btag = jetPtr->btagging(); double mvx = -999; - if (btag) btag->MVx_discriminant("MV2c10", mvx); + //if (btag) btag->MVx_discriminant("MV2c10", mvx); m_tjet_mv2c10[i] = mvx; } @@ -3315,27 +3315,27 @@ namespace top { // calculated by BtaggingSelectionTool for (const std::string& algo : m_config->bTagAlgo_available_trkJet()) { std::vector<float>& m_tjet_DLx_pick = m_tjet_DLx.at(algo); - std::vector<float>& m_tjet_DLx_pb_pick = m_tjet_DLx_pb.at(algo); - std::vector<float>& m_tjet_DLx_pc_pick = m_tjet_DLx_pc.at(algo); - std::vector<float>& m_tjet_DLx_pu_pick = m_tjet_DLx_pu.at(algo); + //std::vector<float>& m_tjet_DLx_pb_pick = m_tjet_DLx_pb.at(algo); + //std::vector<float>& m_tjet_DLx_pc_pick = m_tjet_DLx_pc.at(algo); + //std::vector<float>& m_tjet_DLx_pu_pick = m_tjet_DLx_pu.at(algo); const SG::AuxElement::ConstAccessor<float>& DLx_acc = DLx.at(algo); i = 0; for (const auto* const jetPtr : event.m_trackJets) { m_tjet_DLx_pick[i] = DLx_acc(*jetPtr); - const xAOD::BTagging* btag(nullptr); - btag = jetPtr->btagging(); - if (btag) { - double pu = -999; - double pc = -999; - double pb = -999; - btag->pu(algo, pu); - btag->pc(algo, pc); - btag->pb(algo, pb); - m_tjet_DLx_pb_pick[i] = pb; - m_tjet_DLx_pc_pick[i] = pc; - m_tjet_DLx_pu_pick[i] = pu; - } + //const xAOD::BTagging* btag(nullptr); + //btag = jetPtr->btagging(); + //if (btag) { + // double pu = -999; + // double pc = -999; + // double pb = -999; + // btag->pu(algo, pu); + // btag->pc(algo, pc); + // btag->pb(algo, pb); + // m_tjet_DLx_pb_pick[i] = pb; + // m_tjet_DLx_pc_pick[i] = pc; + // m_tjet_DLx_pu_pick[i] = pu; + //} ++i; } } @@ -3556,21 +3556,21 @@ namespace top { } const xAOD::Jet* subjet(nullptr); - const xAOD::BTagging* btag(nullptr); + //const xAOD::BTagging* btag(nullptr); for (auto rc_jet_subjet : rc_jet->getConstituents()) { subjet = static_cast<const xAOD::Jet*>(rc_jet_subjet->rawConstituent()); if (m_config->bTagAlgo_MV2c10_used()) { - btag = subjet->btagging(); + //btag = subjet->btagging(); - double mvx10(-999.); // b-tagging mv2c10 + //double mvx10(-999.); // b-tagging mv2c10 - if (btag) { - btag->MVx_discriminant("MV2c10", mvx10); - } else { - mvx10 = -999.; - } - m_rcjetsub_mv2c10[i].push_back(mvx10); + //if (btag) { + // btag->MVx_discriminant("MV2c10", mvx10); + //} else { + // mvx10 = -999.; + //} + //m_rcjetsub_mv2c10[i].push_back(mvx10); } m_rcjetsub_pt[i].push_back(subjet->pt()); @@ -3745,7 +3745,7 @@ namespace top { // loop over subjets const xAOD::Jet* subjet(nullptr); - const xAOD::BTagging* btag(nullptr); + //const xAOD::BTagging* btag(nullptr); m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_pt"][i].clear(); // clear the vector size (otherwise it // grows out of control!) m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_eta"][i].clear(); @@ -3758,16 +3758,16 @@ namespace top { subjet = static_cast<const xAOD::Jet*>(rc_jet_subjet->rawConstituent()); if (m_config->bTagAlgo_MV2c10_used()) { - btag = subjet->btagging(); + //btag = subjet->btagging(); - double mvx10(-999.); // b-tagging mv2c10 + //double mvx10(-999.); // b-tagging mv2c10 - if (btag) { - btag->MVx_discriminant("MV2c10", mvx10); - } else { - mvx10 = -999.; - } - m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_mv2c10"][i].push_back(mvx10); + //if (btag) { + // btag->MVx_discriminant("MV2c10", mvx10); + //} else { + // mvx10 = -999.; + //} + //m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_mv2c10"][i].push_back(mvx10); } m_VarRCjetsubBranches[VarRC + "_" + name + "_sub_pt"][i].push_back(subjet->pt()); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAODNext.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAODNext.cxx index 47716a65b955..dd6cd0e2a145 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAODNext.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/EventSaverxAODNext.cxx @@ -528,10 +528,10 @@ namespace top { } // Loop over container // Reset b-tagging links - for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); - i != currentSystematicThinningMap.end(); ++i) { - output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); - } + //for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); + // i != currentSystematicThinningMap.end(); ++i) { + // output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); + //} } // saveEventObjects top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::JetContainer"); thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); @@ -581,10 +581,10 @@ namespace top { } // Loop over container // Reset b-tagging links - for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); - i != currentSystematicThinningMap.end(); ++i) { - output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); - } + //for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); + // i != currentSystematicThinningMap.end(); ++i) { + // output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); + //} } // saveEventObjects top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::JetContainer"); thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); @@ -634,10 +634,10 @@ namespace top { } // Loop over container // Reset b-tagging links - for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); - i != currentSystematicThinningMap.end(); ++i) { - output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); - } + //for (std::map<unsigned int, unsigned int>::const_iterator i = currentSystematicThinningMap.begin(); + // i != currentSystematicThinningMap.end(); ++i) { + // output->at((*i).second)->setBTaggingLink(xaod->at((*i).first)->btaggingLink()); + //} } // saveEventObjects top::check(evtStore()->event()->record(output, sgKey), "Failed to record xAOD::JetContainer"); thinningMap->insert(std::make_pair(currentSystematic.first, currentSystematicThinningMap)); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx index 35cb6370e303..95aad4ecb79c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx @@ -529,8 +529,8 @@ int main(int argc, char** argv) { unsigned int totalYieldSoFar = 0; unsigned int skippedEventsSoFar = 0; - unsigned int eventSavedReco(0), eventSavedRecoLoose(0), eventSavedTruth(0), eventSavedParticle(0), - eventSavedUpgrade(0); + unsigned int eventSavedReco(0), eventSavedRecoLoose(0), eventSavedTruth(0), eventSavedParticle(0); +// unsigned int eventSavedUpgrade(0); // Close the file that we opened only for metadata metadataInitFile->Close(); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ExamplePlots.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ExamplePlots.cxx index 6a9b8b45f146..4644e3108051 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ExamplePlots.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/ExamplePlots.cxx @@ -86,7 +86,6 @@ namespace top { m_hists.addHist("jet_truthflav", ";Jet truth flavor;Jets", 20, 0., 20.); m_hists.addHist("jet_btagSF_MV2c10_77", ";Jet btag SF;Jets", 100, 0.5, 1.5); } - m_hists.addHist("jet_isbtagged_MV2c10_77", ";Jet is b-tagged;Jets", 2, 0., 2.); m_hists.addHist("jet0_pt", ";Jet0 p_{T} / GeV; Events / 10 GeV", 25, 5, 505); m_hists.addHist("jet0_eta", ";Jet0 #eta; Jets", 25, -2.5, 2.5); @@ -302,11 +301,6 @@ namespace top { m_hists.hist("jet_e")->Fill(jetPtr->e() * toGeV, eventWeight); double mv2c10_discriminant = 0.; - const bool hasmv2c10 = jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); - if (hasmv2c10) { - m_hists.hist("jet_mv2c10")->Fill(mv2c10_discriminant, eventWeight); - } - int jet_truthflav = -1; if (m_config->isMC()) { if (jetPtr->isAvailable<int>("HadronConeExclTruthLabelID")) { diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigDecisionSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigDecisionSelector.cxx index 252027d95c2c..c91dea599d4d 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigDecisionSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigDecisionSelector.cxx @@ -17,7 +17,7 @@ namespace top { } bool GlobalTrigDecisionSelector::apply(top::Event const& event) const { - auto&& tool = (event.m_isLoose ? m_globalTriggerSFLoose : m_globalTriggerSF); + //auto&& tool = (event.m_isLoose ? m_globalTriggerSFLoose : m_globalTriggerSF); std::vector<std::string> triggers; // top::check(tool->getRelevantTriggers(triggers), "TrigGlobalEfficiencyCorrectionTool::getRelevantTriggers failed"); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigMatchSelector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigMatchSelector.cxx index 1dbed2e6c693..750fa58cf2da 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigMatchSelector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/GlobalTrigMatchSelector.cxx @@ -21,7 +21,7 @@ namespace top { } bool GlobalTrigMatchSelector::apply(top::Event const& event) const { - auto&& tool = (event.m_isLoose ? m_globalTriggerSFLoose : m_globalTriggerSF); +// auto&& tool = (event.m_isLoose ? m_globalTriggerSFLoose : m_globalTriggerSF); bool result = false; std::vector<xAOD::IParticle const*> particles; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/IP3DSV1Selector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/IP3DSV1Selector.cxx deleted file mode 100644 index 997a6f6a7197..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/IP3DSV1Selector.cxx +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TopEventSelectionTools/IP3DSV1Selector.h" - -#include <algorithm> - -namespace top { - -IP3DSV1Selector::IP3DSV1Selector(const std::string& params) : - SignValueSelector("IP3DSV1_N", params, true) { - checkMultiplicityIsInteger(); -} - -bool IP3DSV1Selector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Jet* const jetPtr) { return jetPtr->btagging()->SV1plusIP3D_discriminant() > value(); }; - auto count = std::count_if(event.m_jets.begin(), event.m_jets.end(), func); - return checkInt(count, multiplicity()); -} - -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV1Selector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV1Selector.cxx deleted file mode 100644 index ae0c52beecbf..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV1Selector.cxx +++ /dev/null @@ -1,23 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TopEventSelectionTools/MV1Selector.h" -#include "TopEvent/EventTools.h" - -#include <algorithm> - -namespace top { - -MV1Selector::MV1Selector(const std::string& params) : - SignValueSelector("MV1_N", params, true) { - checkMultiplicityIsInteger(); -} - -bool MV1Selector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Jet* const jetPtr) { return jetPtr->btagging()->MV1_discriminant() > value(); }; - auto count = std::count_if(event.m_jets.begin(), event.m_jets.end(), func); - return checkInt(count, multiplicity()); -} - -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c10Selector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c10Selector.cxx index 0b5e94069e25..47223c9143f6 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c10Selector.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c10Selector.cxx @@ -14,11 +14,11 @@ namespace top { } bool MV2c10Selector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Jet* const jetPtr) { - double mv2c10_discriminant = 0.; - const bool hasMv2c10 = jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); + auto func = [&](const xAOD::Jet* const /*jetPtr*/) { + //double mv2c10_discriminant = 0.; + //const bool hasMv2c10 = jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); - if (hasMv2c10) return mv2c10_discriminant > value(); + //if (hasMv2c10) return mv2c10_discriminant > value(); return false; }; diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c20Selector.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c20Selector.cxx deleted file mode 100644 index da4ae7a65586..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/Root/MV2c20Selector.cxx +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TopEventSelectionTools/MV2c20Selector.h" -#include "TopEvent/EventTools.h" - -#include <algorithm> - -namespace top { - -MV2c20Selector::MV2c20Selector(const std::string& params) : - SignValueSelector("MV2C20_N", params, true) { - checkMultiplicityIsInteger(); -} - -bool MV2c20Selector::apply(const top::Event& event) const { - auto func = [&](const xAOD::Jet* const jetPtr) { - double mv2c20_discriminant = 0.; - const bool hasMv2c20 = jetPtr->btagging()->MVx_discriminant("MV2c20", mv2c20_discriminant); - if (hasMv2c20) - return mv2c20_discriminant > value(); - - return false; - }; - - auto count = std::count_if(event.m_jets.begin(), event.m_jets.end(), func); - return checkInt(count, multiplicity()); -} - -} diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/IP3DSV1Selector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/IP3DSV1Selector.h deleted file mode 100644 index b61ac0fc9228..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/IP3DSV1Selector.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef IP3DSV1SELECTOR_H_ -#define IP3DSV1SELECTOR_H_ - -#include "TopEventSelectionTools/SignValueSelector.h" - -namespace top { - -/** - * @brief Should count how many jets have an IP3DSV1 weight above some value. - * The user is expected to input something a bit like IP3DSV1 1.8 >= 2, to get - * two jets tagged with 1.8. Maybe in the future we can make this easier to use - * by the person just saying 70% or something for the 0.7 WP? - */ -class IP3DSV1Selector : public SignValueSelector { -public: - explicit IP3DSV1Selector(const std::string& params); - - virtual bool apply(const top::Event& event) const override; -}; - -} - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV1Selector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV1Selector.h deleted file mode 100644 index 764096adfab5..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV1Selector.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef MV1SELECTOR_H_ -#define MV1SELECTOR_H_ - -#include "TopEventSelectionTools/SignValueSelector.h" - -namespace top { - -/** - * @brief Should count how many jets have an mv1 weight above some value. - * mv1 Seem to not be filled yet though. - */ -class MV1Selector : public SignValueSelector { -public: - explicit MV1Selector(const std::string& params); - - bool apply(const top::Event& event) const override; -}; - -} - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV2c20Selector.h b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV2c20Selector.h deleted file mode 100644 index 8dcbfcc28fe1..000000000000 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/TopEventSelectionTools/MV2c20Selector.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef MV2C20SELECTOR_H_ -#define MV2C20SELECTOR_H_ - -#include "TopEventSelectionTools/SignValueSelector.h" - -namespace top { - -/** - * @brief Should count how many jets have an mv2c20 weight above some value. - * - * Information is taken from these slides presented in PC: - * https://indico.cern.ch/event/394627/contribution/1/5/material/slides/0.pdf - */ -class MV2c20Selector : public SignValueSelector { -public: - explicit MV2c20Selector(const std::string& params); - - /** - * @brief Look at the event and check if the required number of tagged jets - * are there. - * - * If MV2C20 is not in the input file (it is for MC15) then you need to - * return false, since no events pass the cut. If it is there we retrieve - * it and check the value against the user specified cut. - * - * @param event The event to analyse - * @return True if the event passes the cut, false otherwise. - */ - bool apply(const top::Event& event) const override; -}; - -} - -#endif diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DefaultPlots.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DefaultPlots.cxx index b830abf81f5d..6d70bd0385cf 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DefaultPlots.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/DefaultPlots.cxx @@ -132,7 +132,7 @@ namespace top { manager.hist("jet_e")->Fill(jetPtr->e() * toGeV, eventWeight); double mv2c10_discriminant = 0.; - jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); + //jetPtr->btagging()->MVx_discriminant("MV2c10", mv2c10_discriminant); manager.hist("jet_mv2c10")->Fill(mv2c10_discriminant, eventWeight); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsTtresAnalysis.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsTtresAnalysis.cxx index c185024f259a..a599fd3419c3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsTtresAnalysis.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/Root/LJetsTtresAnalysis.cxx @@ -227,10 +227,10 @@ namespace top { vjets.push_back(new TLorentzVector(0, 0, 0, 0)); vjets[z]->SetPtEtaPhiE(topEvent.m_jets[z]->pt(), topEvent.m_jets[z]->eta(), topEvent.m_jets[z]->phi(), topEvent.m_jets[z]->e()); - const xAOD::BTagging* myBTag = topEvent.m_jets[z]->btagging(); + //const xAOD::BTagging* myBTag = topEvent.m_jets[z]->btagging(); // https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/BTagingxAODEDM // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/BTaggingBenchmarks - vjets_btagged.push_back(myBTag->SV1plusIP3D_discriminant() > 1.85); // best discriminant available for 8 TeV + //vjets_btagged.push_back(myBTag->SV1plusIP3D_discriminant() > 1.85); // best discriminant available for 8 TeV // (cut at 70%) } TLorentzVector met(0, 0, 0, 0); diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/EventCleaningSelection.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/EventCleaningSelection.cxx index ab04baaeb8ca..0e9dbd615759 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/EventCleaningSelection.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/EventCleaningSelection.cxx @@ -755,14 +755,14 @@ namespace top { bool EventCleaningSelection::isElectronTrigger(std::string const& trigger) const { top::check(trigger.find("HLT_") == 0, "Expected trigger name to start with `HLT_'"); - bool success; + //bool success; return true; // return(TrigGlobEffCorr::ImportData::associatedLeptonFlavour(trigger.substr(4), success) == xAOD::Type::Electron); } bool EventCleaningSelection::isMuonTrigger(std::string const& trigger) const { top::check(trigger.find("HLT_") == 0, "Expected trigger name to start with `HLT_'"); - bool success; + //bool success; return true; //return(TrigGlobEffCorr::ImportData::associatedLeptonFlavour(trigger.substr(4), success) == xAOD::Type::Muon); } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/JetObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/JetObjectCollectionMaker.cxx index 7edf05738daa..21f5fe7c7c04 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/JetObjectCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/JetObjectCollectionMaker.cxx @@ -879,16 +879,19 @@ namespace top { const std::unordered_map<std::string, ToolHandle<IBTaggingSelectionTool>>& m_btagDecorTools \ = (trackJets ? m_btagSelToolsDL1Decor_trkJet : m_btagSelToolsDL1Decor); for (std::pair<std::string, ToolHandle<IBTaggingSelectionTool>> algo : m_btagDecorTools) { - double DL1_weight = -999., dl1_pb = -10., dl1_pc = -10., dl1_pu = -10.; - if (jet->btagging()->pb(algo.first, dl1_pb) - && jet->btagging()->pc(algo.first, dl1_pc) - && jet->btagging()->pu(algo.first, dl1_pu)) { - if (!algo.second->getTaggerWeight(dl1_pb, dl1_pc, dl1_pu, DL1_weight)) { - DL1_weight = -999.; // value for errors from retrieving DL1x weight - } - } else { - DL1_weight = -100.; // value for errors from nonexistence of probabilities - } + double DL1_weight = -999.; + //double dl1_pb = -10.; + //double dl1_pc = -10.; + //double dl1_pu = -10.; + //if (jet->btagging()->pb(algo.first, dl1_pb) + // && jet->btagging()->pc(algo.first, dl1_pc) + // && jet->btagging()->pu(algo.first, dl1_pu)) { + // if (!algo.second->getTaggerWeight(dl1_pb, dl1_pc, dl1_pu, DL1_weight)) { + // DL1_weight = -999.; // value for errors from retrieving DL1x weight + // } + //} else { + // DL1_weight = -100.; // value for errors from nonexistence of probabilities + //} DLx.at(algo.first)(*jet) = DL1_weight; } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MissingETObjectCollectionMaker.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MissingETObjectCollectionMaker.cxx index 33aebfc7886f..7cb4f2beb9e1 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MissingETObjectCollectionMaker.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/Root/MissingETObjectCollectionMaker.cxx @@ -128,11 +128,11 @@ namespace top { return StatusCode::SUCCESS; } - StatusCode MissingETObjectCollectionMaker::recalculateEventMET(const xAOD::SystematicEvent* event, - const xAOD::MissingETContainer* xaod_met_core, - const xAOD::MissingETAssociationMap* xaod_met_map, - bool forceUseLooseObjects, - std::string outputContainerSuffix) { + StatusCode MissingETObjectCollectionMaker::recalculateEventMET(const xAOD::SystematicEvent* /*event*/, + const xAOD::MissingETContainer* /*xaod_met_core*/, + const xAOD::MissingETAssociationMap* /*xaod_met_map*/, + bool /*forceUseLooseObjects*/, + std::string /*outputContainerSuffix*/){ // // decoration for objects that pass pre OR selection // std::string passPreORSelection = "passPreORSelection"; // -- GitLab From ecd18860f5a02ae9181d70827d9ad71caebebd82 Mon Sep 17 00:00:00 2001 From: Walter Lampl <Walter.Lampl@cern.ch> Date: Wed, 28 Oct 2020 13:05:09 +0100 Subject: [PATCH 05/12] Minor cleanup of ClusterMomentsMaker: - omit manual symmetrization of matrix fed into SelfAdjointEigenSolver (not necessary according to eigen-doc) - omit second check for eigenvalue !=0 --- .../CaloRec/src/CaloClusterMomentsMaker.cxx | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx b/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx index 2f3dbf5ff1ea..807b8462fc0f 100644 --- a/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx +++ b/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx @@ -563,17 +563,8 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, C(2,2) += e2*(ci.z-zc)*(ci.z-zc); w += e2; } - - //Symmetrize matrix (Eigen has not symmetric matrix class) - C(0,1)=C(1,0); - C(0,2)=C(2,0); - C(1,2)=C(2,1); C/=w; - - //HepSymMatrix S(C); - //HepMatrix U = diagonalize(&S); - Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(C); if (eigensolver.info() != Eigen::Success) { msg(MSG::WARNING) << "Failed to compute Eigenvalues -> Can't determine shower axis" << endmsg; @@ -593,22 +584,20 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, int iEigen = -1; for (i=0;i<3;i++) { - if ( S[i] != 0 ) { - Vector3D<double> tmpAxis = Vector3D<double>(U(0,i),U(1,i),U(2,i)); + Vector3D<double> tmpAxis = Vector3D<double>(U(0,i),U(1,i),U(2,i)); - // calculate the angle + // calculate the angle - double tmpAngle = tmpAxis.angle(showerAxis); - if ( tmpAngle > 90*deg ) { - tmpAngle = 180*deg - tmpAngle; - tmpAxis = -tmpAxis; - } + double tmpAngle = tmpAxis.angle(showerAxis); + if ( tmpAngle > 90*deg ) { + tmpAngle = 180*deg - tmpAngle; + tmpAxis = -tmpAxis; + } - if ( iEigen == -1 || tmpAngle < angle ) { - iEigen = i; - angle = tmpAngle; - prAxis = tmpAxis; - } + if ( iEigen == -1 || tmpAngle < angle ) { + iEigen = i; + angle = tmpAngle; + prAxis = tmpAxis; } }//end for loop @@ -628,8 +617,11 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, << m_maxAxisAngle*(1./deg) << " deg from IP-to-ClusterCenter-axis (" << showerAxis.x() << ", " << showerAxis.y() << ", " << showerAxis.z() << ")"); - }//end if !S[i]==0 - }// end else got Eigenvalues + }//end if fabs(S)<epsilon + else { + ATH_MSG_DEBUG("Eigenvalues close to 0, do not use principal axis"); + } + }//end got eigenvalues } //end if ncell>2 ATH_MSG_DEBUG("Shower Axis = (" << showerAxis.x() << ", " -- GitLab From bd88edaeb6b78cfa2c23f7f66ca85c01b097b333 Mon Sep 17 00:00:00 2001 From: Walter Lampl <Walter.Lampl@cern.ch> Date: Wed, 28 Oct 2020 14:47:57 +0100 Subject: [PATCH 06/12] range-based for loop --- Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx b/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx index 807b8462fc0f..ef2a1fccddb4 100644 --- a/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx +++ b/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx @@ -631,9 +631,10 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, // along the shower axis for each cell. The cluster center is // at r=0 and lambda=0 - for(i=0;i<ncell;i++) { - CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i]; - Point3D<double> currentCell(ci.x,ci.y,ci.z); + //for(i=0;i<ncell;i++) { + //CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i]; + for (auto& ci : cellinfo) { + const Point3D<double> currentCell(ci.x,ci.y,ci.z); // calculate distance from shower axis r ci.r = ((currentCell-showerCenter).cross(showerAxis)).mag(); // calculate distance from shower center along shower axis @@ -646,11 +647,11 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, double commonNorm = 0; double phi0 = ncell > 0 ? cellinfo[0].phi : 0; - for(i=0;i<ncell;i++) { - const CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i]; + for(unsigned i=0;i<ncell;i++) { + const CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i]; // loop over all valid moments commonNorm += ci.energy; - for(size_t iMoment = 0, size = m_validMoments.size(); + for(size_t iMoment = 0, size = m_validMoments.size(); iMoment != size; ++ iMoment) { -- GitLab From 9570689e4f3136e09f406b80374c65c75375c10c Mon Sep 17 00:00:00 2001 From: Fabrizio Trovato <fabrizio.trovato@cern.ch> Date: Wed, 28 Oct 2020 15:16:09 +0100 Subject: [PATCH 07/12] Adding chain to FS ID monitoring --- .../TrigIDtrkMonitoring/python/TrigIDtrkMonitoringConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Trigger/TrigMonitoring/TrigIDtrkMonitoring/python/TrigIDtrkMonitoringConfig.py b/Trigger/TrigMonitoring/TrigIDtrkMonitoring/python/TrigIDtrkMonitoringConfig.py index d72033db74a9..ae0bf8a1c6c7 100644 --- a/Trigger/TrigMonitoring/TrigIDtrkMonitoring/python/TrigIDtrkMonitoringConfig.py +++ b/Trigger/TrigMonitoring/TrigIDtrkMonitoring/python/TrigIDtrkMonitoringConfig.py @@ -334,7 +334,7 @@ def TrigIDtrkMonitoringTool( legacy_monitoring=False ): if mt_chains: tidabjet.ntupleChainNames += [ "Offline", - ":HLT_IDTrack_FS_FTF:vtx=HLT_IDVertex_FS", + "HLT_j45_ftf_L1J15:key=HLT_IDTrack_FS_FTF:vtx=HLT_IDVertex_FS", "HLT_j.*.*boffperf.*:key=HLT_IDTrack_Bjet_FTF", "HLT_j.*.*boffperf.*:key=HLT_IDTrack_Bjet_IDTrig" ] -- GitLab From 8b74be30a8a6dacd82e390850cbd7a04bb98bfd6 Mon Sep 17 00:00:00 2001 From: Fabrizio Trovato <fabrizio.trovato@cern.ch> Date: Wed, 28 Oct 2020 15:41:44 +0100 Subject: [PATCH 08/12] Adding chain to PhysVal for bjets FS tests --- .../TrigIDtrkMonitoring/python/TrigIDPhysValMonitoringConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Trigger/TrigMonitoring/TrigIDtrkMonitoring/python/TrigIDPhysValMonitoringConfig.py b/Trigger/TrigMonitoring/TrigIDtrkMonitoring/python/TrigIDPhysValMonitoringConfig.py index 04390e1abae5..bd4359a1adc7 100644 --- a/Trigger/TrigMonitoring/TrigIDtrkMonitoring/python/TrigIDPhysValMonitoringConfig.py +++ b/Trigger/TrigMonitoring/TrigIDtrkMonitoring/python/TrigIDPhysValMonitoringConfig.py @@ -200,7 +200,7 @@ def TrigIDPhysValMonitoringTool( legacy_monitoring=False ): useOffline=True if mt_chains: chainnames = [ - ":key=HLT_IDTrack_FS_FTF", + "HLT_j45_ftf_L1J15:key=HLT_IDTrack_FS_FTF:vtx=HLT_IDVertex_FS", "HLT_j.*b.*perf_split:key=HLT_IDTrack_Bjet_FTF", "HLT_j.*b.*perf_split:key=HLT_IDTrack_Bjet_IDTrig" ] -- GitLab From 808ab2b78627f499e9a946de63be33146096581f Mon Sep 17 00:00:00 2001 From: Walter Lampl <Walter.Lampl@cern.ch> Date: Wed, 28 Oct 2020 16:29:01 +0100 Subject: [PATCH 09/12] CaloClusterMomentsMaker: Consistently use Eigen (instead of CLHEP/HepGeom) --- .../CaloRec/src/CaloClusterMomentsMaker.cxx | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx b/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx index ef2a1fccddb4..5c679d82e58c 100644 --- a/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx +++ b/Calorimeter/CaloRec/src/CaloClusterMomentsMaker.cxx @@ -26,9 +26,10 @@ #include "CaloGeoHelpers/CaloPhiRange.h" #include "CaloIdentifier/CaloCell_ID.h" #include "AthAllocators/ArenaPoolSTLAllocator.h" -//#include "CxxUtils/unordered_set.h" -#include "CLHEP/Geometry/Point3D.h" -#include "CLHEP/Geometry/Vector3D.h" + +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoPrimitives/GeoPrimitivesHelpers.h" + #include "CLHEP/Units/SystemOfUnits.h" #include "CxxUtils/prefetch.h" #include <Eigen/Dense> @@ -38,9 +39,6 @@ #include <limits> #include <sstream> - -using HepGeom::Vector3D; -using HepGeom::Point3D; using CLHEP::deg; using CLHEP::cm; @@ -529,7 +527,7 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, xc/=w; yc/=w; zc/=w; - Point3D<double> showerCenter(xc,yc,zc); + Amg::Vector3D showerCenter(xc,yc,zc); w=0; @@ -538,8 +536,8 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, // shower axis is just the vector pointing from the IP to the shower center // in case there are less than 3 cells in the cluster - Vector3D<double> showerAxis(xc,yc,zc); - showerAxis.setMag(1); + Amg::Vector3D showerAxis(xc,yc,zc); + Amg::setMag(showerAxis,1.0); // otherwise the principal direction with the largest absolute // eigenvalue will be used unless it's angle w.r.t. the vector pointing @@ -580,15 +578,15 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, if ( !( std::abs(S[0]) < epsilon || std::abs(S[1]) < epsilon || std::abs(S[2]) < epsilon ) ) { - Vector3D<double> prAxis(showerAxis); + Amg::Vector3D prAxis(showerAxis); int iEigen = -1; for (i=0;i<3;i++) { - Vector3D<double> tmpAxis = Vector3D<double>(U(0,i),U(1,i),U(2,i)); + Amg::Vector3D tmpAxis=U.col(i); + + // calculate the angle + double tmpAngle=Amg::angle(tmpAxis,showerAxis); - // calculate the angle - - double tmpAngle = tmpAxis.angle(showerAxis); if ( tmpAngle > 90*deg ) { tmpAngle = 180*deg - tmpAngle; tmpAxis = -tmpAxis; @@ -609,14 +607,15 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, // check the angle - if ( angle < m_maxAxisAngle ) + if ( angle < m_maxAxisAngle ) { showerAxis = prAxis; + } else - ATH_MSG_DEBUG("principal Direction (" << prAxis.x() << ", " - << prAxis.y() << ", " << prAxis.z() << ") deviates more than " + ATH_MSG_DEBUG("principal Direction (" << prAxis[Amg::x] << ", " + << prAxis[Amg::y] << ", " << prAxis[Amg::z] << ") deviates more than " << m_maxAxisAngle*(1./deg) - << " deg from IP-to-ClusterCenter-axis (" << showerAxis.x() << ", " - << showerAxis.y() << ", " << showerAxis.z() << ")"); + << " deg from IP-to-ClusterCenter-axis (" << showerAxis[Amg::x] << ", " + << showerAxis[Amg::y] << ", " << showerAxis[Amg::z] << ")"); }//end if fabs(S)<epsilon else { ATH_MSG_DEBUG("Eigenvalues close to 0, do not use principal axis"); @@ -624,17 +623,16 @@ CaloClusterMomentsMaker::execute(const EventContext& ctx, }//end got eigenvalues } //end if ncell>2 - ATH_MSG_DEBUG("Shower Axis = (" << showerAxis.x() << ", " - << showerAxis.y() << ", " << showerAxis.z() << ")"); + ATH_MSG_DEBUG("Shower Axis = (" << showerAxis[Amg::x] << ", " + << showerAxis[Amg::y] << ", " << showerAxis[Amg::z] << ")"); + // calculate radial distance from and the longitudinal distance // along the shower axis for each cell. The cluster center is // at r=0 and lambda=0 - //for(i=0;i<ncell;i++) { - //CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i]; for (auto& ci : cellinfo) { - const Point3D<double> currentCell(ci.x,ci.y,ci.z); + const Amg::Vector3D currentCell(ci.x,ci.y,ci.z); // calculate distance from shower axis r ci.r = ((currentCell-showerCenter).cross(showerAxis)).mag(); // calculate distance from shower center along shower axis -- GitLab From 558c5f6146cadd427a3fbd47e3d80cdca28ea9f8 Mon Sep 17 00:00:00 2001 From: Tomas Dado <tomas.dado@cern.ch> Date: Wed, 28 Oct 2020 17:44:35 +0100 Subject: [PATCH 10/12] CMakeLists cleanup --- .../TopPhysUtils/TopDataPreparation/CMakeLists.txt | 4 +--- PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt | 7 +------ PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt | 7 +------ .../TopPhys/xAOD/TopConfiguration/CMakeLists.txt | 4 +--- .../TopPhys/xAOD/TopCorrections/CMakeLists.txt | 7 +------ PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt | 4 +--- .../xAOD/TopEventReconstructionTools/CMakeLists.txt | 4 +--- .../TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt | 7 +------ PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt | 8 +------- .../TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt | 7 +------ .../TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt | 7 +------ .../TopPhys/xAOD/TopParticleLevel/CMakeLists.txt | 7 +------ PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt | 7 +------ .../TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt | 7 +------ 14 files changed, 14 insertions(+), 73 deletions(-) diff --git a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/CMakeLists.txt b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/CMakeLists.txt index 006d0fda5b55..1a8fd7212e75 100644 --- a/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/TopPhysUtils/TopDataPreparation/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-09 17:44:33.125987 - # Declare the name of this package: -atlas_subdir( TopDataPreparation None ) +atlas_subdir( TopDataPreparation ) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt index 14b4788f5a0a..04ec018efe49 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:33.629640 - # Declare the name of this package: -atlas_subdir( TopAnalysis None ) +atlas_subdir( TopAnalysis ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -34,9 +32,6 @@ atlas_depends_on_subdirs( PUBLIC # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) -# Custom definitions needed for this package: -add_definitions( -g ) - # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopAnalysis _cintDictSource ROOT_HEADERS Root/LinkDef.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt index fc1f64a55f9c..83394cfc539c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCPTools/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:34.346308 - # Declare the name of this package: -atlas_subdir( TopCPTools None ) +atlas_subdir( TopCPTools ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -59,9 +57,6 @@ atlas_depends_on_subdirs( PUBLIC # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) -# Custom definitions needed for this package: -add_definitions( -g -std=c++14 ) - # Build a library that other components can link against: atlas_add_library( TopCPTools Root/*.cxx Root/*.h Root/*.icc TopCPTools/*.h TopCPTools/*.icc TopCPTools/*/*.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/CMakeLists.txt index 788d9749ce76..cf7eef726ca3 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:35.608258 - # Declare the name of this package: -atlas_subdir( TopConfiguration None ) +atlas_subdir( TopConfiguration ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/CMakeLists.txt index 84d0e64bfc50..9b933124d83e 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopCorrections/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:35.652165 - # Declare the name of this package: -atlas_subdir( TopCorrections None ) +atlas_subdir( TopCorrections ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -26,9 +24,6 @@ find_package( Lhapdf ) # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) -# Custom definitions needed for this package: -add_definitions( -g -std=c++14 ) - # Add a ROOT dictionary atlas_add_root_dictionary( TopCorrections _cintDictSource ROOT_HEADERS Root/LinkDef.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt index d2754af30015..80a5a47fc21b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEvent/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:36.020351 - # Declare the name of this package: -atlas_subdir( TopEvent None ) +atlas_subdir( TopEvent ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/CMakeLists.txt index aba16f9cc601..8eb186314d2c 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventReconstructionTools/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:36.489231 - # Declare the name of this package: -atlas_subdir( TopEventReconstructionTools None ) +atlas_subdir( TopEventReconstructionTools ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt index d6b986f9c287..9c4ed1d2e360 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopEventSelectionTools/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:36.708684 - # Declare the name of this package: -atlas_subdir( TopEventSelectionTools None ) +atlas_subdir( TopEventSelectionTools ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -17,9 +15,6 @@ atlas_depends_on_subdirs( PUBLIC # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) -# Custom definitions needed for this package: -add_definitions( -g ) - # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopEventSelectionTools _cintDictSource ROOT_HEADERS Root/LinkDef.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt index 726bf4fb359a..f4694ce281f4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopExamples/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:36.923782 - # Declare the name of this package: -atlas_subdir( TopExamples None ) +atlas_subdir( TopExamples ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -20,10 +18,6 @@ atlas_depends_on_subdirs( PUBLIC # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO Math MathMore MathCore Graf Physics ) - -# Custom definitions needed for this package: -add_definitions( -g ) - # Build a library that other components can link against: atlas_add_library( TopExamples Root/*.cxx Root/*.h Root/*.icc TopExamples/*.h TopExamples/*.icc TopExamples/*/*.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt index 721474570f2b..cf1ffff012ee 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopJetSubstructure/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:37.639679 - # Declare the name of this package: -atlas_subdir( TopJetSubstructure None ) +atlas_subdir( TopJetSubstructure ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -24,9 +22,6 @@ find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) find_package( FastJet ) find_package( FastJetContrib ) -# Custom definitions needed for this package: -add_definitions( -g ) - # Build a library that other components can link against: atlas_add_library( TopJetSubstructure Root/*.cxx Root/*.h Root/*.icc TopJetSubstructure/*.h TopJetSubstructure/*.icc TopJetSubstructure/*/*.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt index fd5bbb17159d..139045ae4993 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:37.990954 - # Declare the name of this package: -atlas_subdir( TopObjectSelectionTools None ) +atlas_subdir( TopObjectSelectionTools ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -40,9 +38,6 @@ atlas_depends_on_subdirs( PUBLIC # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) -# Custom definitions needed for this package: -add_definitions( -g ) - # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopObjectSelectionTools _cintDictSource ROOT_HEADERS Root/LinkDef.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/CMakeLists.txt index 1462dd37605a..4ca1c02bfcaa 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopParticleLevel/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:38.688787 - # Declare the name of this package: -atlas_subdir( TopParticleLevel None ) +atlas_subdir( TopParticleLevel ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -30,9 +28,6 @@ find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) find_package( FastJet COMPONENTS fastjetplugins fastjettools ) find_package( FastJetContrib COMPONENTS EnergyCorrelator Nsubjettiness ) -# Custom definitions needed for this package: -add_definitions( -g ) - # Build a library that other components can link against: atlas_add_library( TopParticleLevel Root/*.cxx Root/*.h Root/*.icc TopParticleLevel/*.h TopParticleLevel/*.icc TopParticleLevel/*/*.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt index 6ca87a659784..d434650d2ff0 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopPartons/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:38.930377 - # Declare the name of this package: -atlas_subdir( TopPartons None ) +atlas_subdir( TopPartons ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -15,9 +13,6 @@ atlas_depends_on_subdirs( PUBLIC # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore TMVA Graf ) -# Custom definitions needed for this package: -add_definitions( -g ) - # Generate a CINT dictionary source file: atlas_add_root_dictionary( TopPartons _cintDictSource ROOT_HEADERS Root/LinkDef.h diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt index e89acc744f35..7b3550af079b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt +++ b/PhysicsAnalysis/TopPhys/xAOD/TopSystematicObjectMaker/CMakeLists.txt @@ -1,7 +1,5 @@ -# Auto-generated on: 2017-03-08 14:47:39.125284 - # Declare the name of this package: -atlas_subdir( TopSystematicObjectMaker None ) +atlas_subdir( TopSystematicObjectMaker ) # This package depends on other packages: atlas_depends_on_subdirs( PUBLIC @@ -38,9 +36,6 @@ atlas_depends_on_subdirs( PUBLIC # This package uses ROOT: find_package( ROOT REQUIRED COMPONENTS Core Gpad Tree Hist RIO MathCore Graf ) -# Custom definitions needed for this package: -add_definitions( -g ) - # Build a library that other components can link against: atlas_add_library( TopSystematicObjectMaker Root/*.cxx Root/*.h Root/*.icc TopSystematicObjectMaker/*.h TopSystematicObjectMaker/*.icc TopSystematicObjectMaker/*/*.h -- GitLab From 1c9a5d3897cb28166329b36cc03e8640be32774e Mon Sep 17 00:00:00 2001 From: Tadej Novak <tadej.novak@cern.ch> Date: Wed, 28 Oct 2020 18:20:26 +0100 Subject: [PATCH 11/12] Remove unused StreamSelectorTool --- .../AthenaPoolMultiTest/CMakeLists.txt | 6 - .../AthenaPoolMultiTestPropagateSelect.ref | 281 ----------- .../share/AthenaPoolMultiTestStreamSelect.ref | 458 ------------------ .../share/CheckStreamPropagate_jo.py | 71 --- .../share/CheckStreamSelector_jo.py | 91 ---- .../src/StreamSelectorTool.cxx | 124 ----- .../src/StreamSelectorTool.h | 53 -- .../EventBookkeeperTools_entries.cxx | 2 - 8 files changed, 1086 deletions(-) delete mode 100644 AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/AthenaPoolMultiTestPropagateSelect.ref delete mode 100644 AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/AthenaPoolMultiTestStreamSelect.ref delete mode 100755 AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/CheckStreamPropagate_jo.py delete mode 100755 AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/CheckStreamSelector_jo.py delete mode 100644 Event/EventBookkeeperTools/src/StreamSelectorTool.cxx delete mode 100644 Event/EventBookkeeperTools/src/StreamSelectorTool.h diff --git a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/CMakeLists.txt b/AtlasTest/DatabaseTest/AthenaPoolMultiTest/CMakeLists.txt index a7fb457b3358..7654abe0716e 100644 --- a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/CMakeLists.txt +++ b/AtlasTest/DatabaseTest/AthenaPoolMultiTest/CMakeLists.txt @@ -47,12 +47,6 @@ athenapoolmultitest_run_test( AthenaPoolMultiTestEventNoSplit EventNoSplit_jo athenapoolmultitest_run_test( AthenaPoolMultiTestPropagate DecisionPropagation_jo post_check_p DEPENDS AthenaPoolMultiTestEventSplitDecision ) -athenapoolmultitest_run_test( AthenaPoolMultiTestStreamSelect CheckStreamSelector_jo - post_check_ss - DEPENDS AthenaPoolMultiTestEventSplitDecision ) -athenapoolmultitest_run_test( AthenaPoolMultiTestPropagateSelect CheckStreamPropagate_jo - post_check_ss - DEPENDS AthenaPoolMultiTestPropagate ) #athenapoolmultitest_run_test( AthenaPoolMultiTestCheckNull CheckNull_jo # post_check_cn # DEPENDS AthenaPoolMultiTestEventSplit ) diff --git a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/AthenaPoolMultiTestPropagateSelect.ref b/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/AthenaPoolMultiTestPropagateSelect.ref deleted file mode 100644 index f3b45fbf61d1..000000000000 --- a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/AthenaPoolMultiTestPropagateSelect.ref +++ /dev/null @@ -1,281 +0,0 @@ -ReadData INFO in initialize() -EventSelector.S... DEBUG Property update for OutputLevel : new value = 2 -EventSelector.S... DEBUG ... postInitialize -EventSelector INFO EventSelection with query -AthenaEventLoopMgr INFO Setup EventSelector service EventSelector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAllP -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 0 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1.2 y = -2.3 z = 226.6 detector = DummyHitDetector -ReadData INFO Hit x = 4.4 y = -8.0 z = 94.7 detector = DummyHitDetector -ReadData INFO Hit x = 7.6 y = -13.7 z = 70.2 detector = DummyHitDetector -ReadData INFO Hit x = 10.8 y = -19.3 z = 59.9 detector = DummyHitDetector -ReadData INFO Hit x = 14.0 y = -25.0 z = 54.2 detector = DummyHitDetector -ReadData INFO Hit x = 17.2 y = -30.7 z = 50.6 detector = DummyHitDetector -ReadData INFO Hit x = 20.4 y = -36.4 z = 48.1 detector = DummyHitDetector -ReadData INFO Hit x = 23.7 y = -42.0 z = 46.3 detector = DummyHitDetector -ReadData INFO Hit x = 26.9 y = -47.7 z = 44.9 detector = DummyHitDetector -ReadData INFO Hit x = 30.1 y = -53.4 z = 43.8 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 3 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 4 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 5 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 6 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 2 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAllP -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 6 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 601.2 y = -2.3 z = -373.3 detector = DummyHitDetector -ReadData INFO Hit x = 604.4 y = -8.0 z = -505.2 detector = DummyHitDetector -ReadData INFO Hit x = 607.6 y = -13.7 z = -529.7 detector = DummyHitDetector -ReadData INFO Hit x = 610.8 y = -19.3 z = -540.0 detector = DummyHitDetector -ReadData INFO Hit x = 614.0 y = -25.0 z = -545.7 detector = DummyHitDetector -ReadData INFO Hit x = 617.2 y = -30.7 z = -549.3 detector = DummyHitDetector -ReadData INFO Hit x = 620.4 y = -36.4 z = -551.8 detector = DummyHitDetector -ReadData INFO Hit x = 623.7 y = -42.0 z = -553.6 detector = DummyHitDetector -ReadData INFO Hit x = 626.9 y = -47.7 z = -555.0 detector = DummyHitDetector -ReadData INFO Hit x = 630.1 y = -53.4 z = -556.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 2 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 8 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 2 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 9 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 3 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAllP -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 9 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 901.2 y = -2.3 z = -673.3 detector = DummyHitDetector -ReadData INFO Hit x = 904.4 y = -8.0 z = -805.2 detector = DummyHitDetector -ReadData INFO Hit x = 907.6 y = -13.7 z = -829.7 detector = DummyHitDetector -ReadData INFO Hit x = 910.8 y = -19.3 z = -840.0 detector = DummyHitDetector -ReadData INFO Hit x = 914.0 y = -25.0 z = -845.7 detector = DummyHitDetector -ReadData INFO Hit x = 917.2 y = -30.7 z = -849.3 detector = DummyHitDetector -ReadData INFO Hit x = 920.4 y = -36.4 z = -851.8 detector = DummyHitDetector -ReadData INFO Hit x = 923.7 y = -42.0 z = -853.6 detector = DummyHitDetector -ReadData INFO Hit x = 926.9 y = -47.7 z = -855.0 detector = DummyHitDetector -ReadData INFO Hit x = 930.1 y = -53.4 z = -856.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 3 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 11 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 3 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 12 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 4 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAllP -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 12 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1201.2 y = -2.3 z = -973.3 detector = DummyHitDetector -ReadData INFO Hit x = 1204.4 y = -8.0 z = -1105.2 detector = DummyHitDetector -ReadData INFO Hit x = 1207.6 y = -13.7 z = -1129.7 detector = DummyHitDetector -ReadData INFO Hit x = 1210.8 y = -19.3 z = -1140.0 detector = DummyHitDetector -ReadData INFO Hit x = 1214.0 y = -25.0 z = -1145.7 detector = DummyHitDetector -ReadData INFO Hit x = 1217.2 y = -30.7 z = -1149.3 detector = DummyHitDetector -ReadData INFO Hit x = 1220.4 y = -36.4 z = -1151.8 detector = DummyHitDetector -ReadData INFO Hit x = 1223.7 y = -42.0 z = -1153.6 detector = DummyHitDetector -ReadData INFO Hit x = 1226.9 y = -47.7 z = -1155.0 detector = DummyHitDetector -ReadData INFO Hit x = 1230.1 y = -53.4 z = -1156.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 4 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 14 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 4 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 15 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 5 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAllP -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 15 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1501.2 y = -2.3 z = -1273.3 detector = DummyHitDetector -ReadData INFO Hit x = 1504.4 y = -8.0 z = -1405.2 detector = DummyHitDetector -ReadData INFO Hit x = 1507.6 y = -13.7 z = -1429.7 detector = DummyHitDetector -ReadData INFO Hit x = 1510.8 y = -19.3 z = -1440.0 detector = DummyHitDetector -ReadData INFO Hit x = 1514.0 y = -25.0 z = -1445.7 detector = DummyHitDetector -ReadData INFO Hit x = 1517.2 y = -30.7 z = -1449.3 detector = DummyHitDetector -ReadData INFO Hit x = 1520.4 y = -36.4 z = -1451.8 detector = DummyHitDetector -ReadData INFO Hit x = 1523.7 y = -42.0 z = -1453.6 detector = DummyHitDetector -ReadData INFO Hit x = 1526.9 y = -47.7 z = -1455.0 detector = DummyHitDetector -ReadData INFO Hit x = 1530.1 y = -53.4 z = -1456.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 6 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAllP -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 16 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1601.2 y = -2.3 z = -1373.3 detector = DummyHitDetector -ReadData INFO Hit x = 1604.4 y = -8.0 z = -1505.2 detector = DummyHitDetector -ReadData INFO Hit x = 1607.6 y = -13.7 z = -1529.7 detector = DummyHitDetector -ReadData INFO Hit x = 1610.8 y = -19.3 z = -1540.0 detector = DummyHitDetector -ReadData INFO Hit x = 1614.0 y = -25.0 z = -1545.7 detector = DummyHitDetector -ReadData INFO Hit x = 1617.2 y = -30.7 z = -1549.3 detector = DummyHitDetector -ReadData INFO Hit x = 1620.4 y = -36.4 z = -1551.8 detector = DummyHitDetector -ReadData INFO Hit x = 1623.7 y = -42.0 z = -1553.6 detector = DummyHitDetector -ReadData INFO Hit x = 1626.9 y = -47.7 z = -1555.0 detector = DummyHitDetector -ReadData INFO Hit x = 1630.1 y = -53.4 z = -1556.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 6 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 18 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 7 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAllP -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 18 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1801.2 y = -2.3 z = -1573.3 detector = DummyHitDetector -ReadData INFO Hit x = 1804.4 y = -8.0 z = -1705.2 detector = DummyHitDetector -ReadData INFO Hit x = 1807.6 y = -13.7 z = -1729.7 detector = DummyHitDetector -ReadData INFO Hit x = 1810.8 y = -19.3 z = -1740.0 detector = DummyHitDetector -ReadData INFO Hit x = 1814.0 y = -25.0 z = -1745.7 detector = DummyHitDetector -ReadData INFO Hit x = 1817.2 y = -30.7 z = -1749.3 detector = DummyHitDetector -ReadData INFO Hit x = 1820.4 y = -36.4 z = -1751.8 detector = DummyHitDetector -ReadData INFO Hit x = 1823.7 y = -42.0 z = -1753.6 detector = DummyHitDetector -ReadData INFO Hit x = 1826.9 y = -47.7 z = -1755.0 detector = DummyHitDetector -ReadData INFO Hit x = 1830.1 y = -53.4 z = -1756.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 7 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector INFO skipping event 20 -EventSelector INFO Disconnecting input sourceID: B3D760F4-F874-B44B-AED4-78DE0A73D140 -ReadData INFO in finalize() diff --git a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/AthenaPoolMultiTestStreamSelect.ref b/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/AthenaPoolMultiTestStreamSelect.ref deleted file mode 100644 index 467cfa0fbdd7..000000000000 --- a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/AthenaPoolMultiTestStreamSelect.ref +++ /dev/null @@ -1,458 +0,0 @@ -ReadData INFO in initialize() -EventSelector.S... DEBUG Property update for OutputLevel : new value = 2 -EventSelector.S... DEBUG Property update for OutputLevel : new value = 2 -EventSelector.S... DEBUG Property update for OutputLevel : new value = 2 -EventSelector.S... DEBUG ... postInitialize -EventSelector.S... DEBUG ... postInitialize -EventSelector.S... DEBUG ... postInitialize -EventSelector INFO EventSelection with query -AthenaEventLoopMgr INFO Setup EventSelector service EventSelector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAll2 -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 0 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1.2 y = -2.3 z = 226.6 detector = DummyHitDetector -ReadData INFO Hit x = 4.4 y = -8.0 z = 94.7 detector = DummyHitDetector -ReadData INFO Hit x = 7.6 y = -13.7 z = 70.2 detector = DummyHitDetector -ReadData INFO Hit x = 10.8 y = -19.3 z = 59.9 detector = DummyHitDetector -ReadData INFO Hit x = 14.0 y = -25.0 z = 54.2 detector = DummyHitDetector -ReadData INFO Hit x = 17.2 y = -30.7 z = 50.6 detector = DummyHitDetector -ReadData INFO Hit x = 20.4 y = -36.4 z = 48.1 detector = DummyHitDetector -ReadData INFO Hit x = 23.7 y = -42.0 z = 46.3 detector = DummyHitDetector -ReadData INFO Hit x = 26.9 y = -47.7 z = 44.9 detector = DummyHitDetector -ReadData INFO Hit x = 30.1 y = -53.4 z = 43.8 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 3 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 4 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 5 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 1 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 6 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAll2 -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 6 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 601.2 y = -2.3 z = -373.3 detector = DummyHitDetector -ReadData INFO Hit x = 604.4 y = -8.0 z = -505.2 detector = DummyHitDetector -ReadData INFO Hit x = 607.6 y = -13.7 z = -529.7 detector = DummyHitDetector -ReadData INFO Hit x = 610.8 y = -19.3 z = -540.0 detector = DummyHitDetector -ReadData INFO Hit x = 614.0 y = -25.0 z = -545.7 detector = DummyHitDetector -ReadData INFO Hit x = 617.2 y = -30.7 z = -549.3 detector = DummyHitDetector -ReadData INFO Hit x = 620.4 y = -36.4 z = -551.8 detector = DummyHitDetector -ReadData INFO Hit x = 623.7 y = -42.0 z = -553.6 detector = DummyHitDetector -ReadData INFO Hit x = 626.9 y = -47.7 z = -555.0 detector = DummyHitDetector -ReadData INFO Hit x = 630.1 y = -53.4 z = -556.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 2 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 2 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 8 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 2 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 2 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 9 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 3 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 3 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAll2 -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 9 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 901.2 y = -2.3 z = -673.3 detector = DummyHitDetector -ReadData INFO Hit x = 904.4 y = -8.0 z = -805.2 detector = DummyHitDetector -ReadData INFO Hit x = 907.6 y = -13.7 z = -829.7 detector = DummyHitDetector -ReadData INFO Hit x = 910.8 y = -19.3 z = -840.0 detector = DummyHitDetector -ReadData INFO Hit x = 914.0 y = -25.0 z = -845.7 detector = DummyHitDetector -ReadData INFO Hit x = 917.2 y = -30.7 z = -849.3 detector = DummyHitDetector -ReadData INFO Hit x = 920.4 y = -36.4 z = -851.8 detector = DummyHitDetector -ReadData INFO Hit x = 923.7 y = -42.0 z = -853.6 detector = DummyHitDetector -ReadData INFO Hit x = 926.9 y = -47.7 z = -855.0 detector = DummyHitDetector -ReadData INFO Hit x = 930.1 y = -53.4 z = -856.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 3 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 3 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 11 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 3 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 3 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 12 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 4 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 4 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAll2 -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 12 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1201.2 y = -2.3 z = -973.3 detector = DummyHitDetector -ReadData INFO Hit x = 1204.4 y = -8.0 z = -1105.2 detector = DummyHitDetector -ReadData INFO Hit x = 1207.6 y = -13.7 z = -1129.7 detector = DummyHitDetector -ReadData INFO Hit x = 1210.8 y = -19.3 z = -1140.0 detector = DummyHitDetector -ReadData INFO Hit x = 1214.0 y = -25.0 z = -1145.7 detector = DummyHitDetector -ReadData INFO Hit x = 1217.2 y = -30.7 z = -1149.3 detector = DummyHitDetector -ReadData INFO Hit x = 1220.4 y = -36.4 z = -1151.8 detector = DummyHitDetector -ReadData INFO Hit x = 1223.7 y = -42.0 z = -1153.6 detector = DummyHitDetector -ReadData INFO Hit x = 1226.9 y = -47.7 z = -1155.0 detector = DummyHitDetector -ReadData INFO Hit x = 1230.1 y = -53.4 z = -1156.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 4 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 4 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 14 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 4 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 4 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 15 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 5 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 5 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAll2 -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 15 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1501.2 y = -2.3 z = -1273.3 detector = DummyHitDetector -ReadData INFO Hit x = 1504.4 y = -8.0 z = -1405.2 detector = DummyHitDetector -ReadData INFO Hit x = 1507.6 y = -13.7 z = -1429.7 detector = DummyHitDetector -ReadData INFO Hit x = 1510.8 y = -19.3 z = -1440.0 detector = DummyHitDetector -ReadData INFO Hit x = 1514.0 y = -25.0 z = -1445.7 detector = DummyHitDetector -ReadData INFO Hit x = 1517.2 y = -30.7 z = -1449.3 detector = DummyHitDetector -ReadData INFO Hit x = 1520.4 y = -36.4 z = -1451.8 detector = DummyHitDetector -ReadData INFO Hit x = 1523.7 y = -42.0 z = -1453.6 detector = DummyHitDetector -ReadData INFO Hit x = 1526.9 y = -47.7 z = -1455.0 detector = DummyHitDetector -ReadData INFO Hit x = 1530.1 y = -53.4 z = -1456.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 6 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 6 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAll2 -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 16 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1601.2 y = -2.3 z = -1373.3 detector = DummyHitDetector -ReadData INFO Hit x = 1604.4 y = -8.0 z = -1505.2 detector = DummyHitDetector -ReadData INFO Hit x = 1607.6 y = -13.7 z = -1529.7 detector = DummyHitDetector -ReadData INFO Hit x = 1610.8 y = -19.3 z = -1540.0 detector = DummyHitDetector -ReadData INFO Hit x = 1614.0 y = -25.0 z = -1545.7 detector = DummyHitDetector -ReadData INFO Hit x = 1617.2 y = -30.7 z = -1549.3 detector = DummyHitDetector -ReadData INFO Hit x = 1620.4 y = -36.4 z = -1551.8 detector = DummyHitDetector -ReadData INFO Hit x = 1623.7 y = -42.0 z = -1553.6 detector = DummyHitDetector -ReadData INFO Hit x = 1626.9 y = -47.7 z = -1555.0 detector = DummyHitDetector -ReadData INFO Hit x = 1630.1 y = -53.4 z = -1556.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 6 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 6 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 18 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 7 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Accepting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 7 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -ReadData INFO EventStreamInfo: Number of events = 20 -ReadData INFO EventStreamInfo: ItemList: -ReadData INFO CLID = 2101, key = McEventInfo -ReadData INFO CLID = 9102, key = MyHits -ReadData INFO CLID = 1287802, key = ExcludeTestTrigMap -ReadData INFO CLID = 1287802, key = MultiTestTrigMap -ReadData INFO CLID = 38853911, key = EventInfoAux. -ReadData INFO CLID = 45903698, key = EventInfo -ReadData INFO CLID = 222376821, key = StreamAll2 -ReadData INFO EventType: Event type: sim/data - is sim , testbeam/atlas - is atlas , calib/physics - is physics -ReadData INFO TagInfo: -ReadData INFO EventInfo event: 18 run: 0 -ReadData INFO Get Smart data ptr 1 -ReadData INFO Could not find ExampleTrackContainer/MyTracks -ReadData INFO Hit x = 1801.2 y = -2.3 z = -1573.3 detector = DummyHitDetector -ReadData INFO Hit x = 1804.4 y = -8.0 z = -1705.2 detector = DummyHitDetector -ReadData INFO Hit x = 1807.6 y = -13.7 z = -1729.7 detector = DummyHitDetector -ReadData INFO Hit x = 1810.8 y = -19.3 z = -1740.0 detector = DummyHitDetector -ReadData INFO Hit x = 1814.0 y = -25.0 z = -1745.7 detector = DummyHitDetector -ReadData INFO Hit x = 1817.2 y = -30.7 z = -1749.3 detector = DummyHitDetector -ReadData INFO Hit x = 1820.4 y = -36.4 z = -1751.8 detector = DummyHitDetector -ReadData INFO Hit x = 1823.7 y = -42.0 z = -1753.6 detector = DummyHitDetector -ReadData INFO Hit x = 1826.9 y = -47.7 z = -1755.0 detector = DummyHitDetector -ReadData INFO Hit x = 1830.1 y = -53.4 z = -1756.1 detector = DummyHitDetector -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector1: For [Stream1] cutflow events = 7 -EventSelector INFO Request skipping event from: EventSelector.Selector1 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... DEBUG Rejecting event -EventSelector.S... DEBUG EventSelector.Selector2: For [Stream1] cutflow events = 7 -EventSelector INFO Request skipping event from: EventSelector.Selector2 -EventSelector.S... INFO StreamSelectorTool::postNext -EventSelector.S... DEBUG Found attribute list -EventSelector.S... ERROR Stream decision for [StreamX] does not exist in input -EventSelector.S... DEBUG EventSelector.SelectorX: For [StreamX] cutflow events = 0 -EventSelector INFO skipping event 20 -EventSelector INFO Disconnecting input sourceID: 0E8E08EE-13D0-BF40-BB78-56E53AEBF449 -ReadData INFO in finalize() diff --git a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/CheckStreamPropagate_jo.py b/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/CheckStreamPropagate_jo.py deleted file mode 100755 index af0ad699fb91..000000000000 --- a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/CheckStreamPropagate_jo.py +++ /dev/null @@ -1,71 +0,0 @@ -## @file CheckExplicit_jo.py -## @brief TopOptions (but dependent SplittableData_jo.py, EventSplit_jo.py): -## Checks that the root collection is readable with the EventSelector -## @author Jack Cranshaw (Jack.Cranshaw@cern.ch) -## $Id: CheckExplicit_jo.py,v 1.9 2009-05-20 13:34:21 cranshaw Exp $ -############################################################### -# -# Job options file -# -#============================================================== - -#-------------------------------------------------------------- -# Event related parameters -#-------------------------------------------------------------- -from AthenaCommon.AlgSequence import AthSequencer -topSequence = AthSequencer("AthAlgSeq") -athRegSeq = AthSequencer("AthRegSeq") - -from AthenaCommon.AppMgr import theApp - -from AthenaCommon.AppMgr import ServiceMgr as svcMgr - -theApp.EvtMax = 200000 - -#-------------------------------------------------------------- -# Load POOL support -#-------------------------------------------------------------- -include( "AthenaPoolExampleConverter/AthenaPoolExampleConverter_jobOption.py" ) -include( "AthenaPoolTestAthenaPool/AthenaPoolTestAthenaPool_joboptions.py" ) -#-------------------------------------------------------------- -#--- Read portion ----- -#-------------------------------------------------------------- -import AthenaPoolCnvSvc.ReadAthenaPool - -from PoolSvc.PoolSvcConf import PoolSvc -svcMgr += PoolSvc() -PoolSvc = svcMgr.PoolSvc -PoolSvc.ReadCatalog = ["xmlcatalog_file:EventSplit.xml"] - -EventSelector = svcMgr.EventSelector -EventSelector.InputCollections = [ "AthenaPoolMultiTest_Propagate.root" ]; - -# Include the StreamSelectorTool -from EventBookkeeperTools.EventBookkeeperToolsConf import StreamSelectorTool -# Select existing Stream1 -selector1 = StreamSelectorTool("Selector1") -selector1.AcceptStreams = ["Stream1"] -selector1.OutputLevel = DEBUG -svcMgr.EventSelector.HelperTools += [selector1] - -#-------------------------------------------------------------- -# Configure the filters -#-------------------------------------------------------------- -from AthenaPoolExampleAlgorithms.AthenaPoolExampleAlgorithmsConf import AthPoolEx__ReadData - -topSequence += AthPoolEx__ReadData("ReadData") -#from AthenaPoolMultiTest.AthenaPoolMultiTestConf import EventTagReader - -from AthenaPoolMultiTest.AthenaPoolMultiTestConf import * - -#-------------------------------------------------------------- -# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL) -#-------------------------------------------------------------- -svcMgr.MessageSvc.infoLimit = 5000 -svcMgr.MessageSvc.debugLimit = 5000 -svcMgr.MessageSvc.OutputLevel = INFO -#============================================================== -# -# End of job options file -# -############################################################### diff --git a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/CheckStreamSelector_jo.py b/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/CheckStreamSelector_jo.py deleted file mode 100755 index 170cd50a12ba..000000000000 --- a/AtlasTest/DatabaseTest/AthenaPoolMultiTest/share/CheckStreamSelector_jo.py +++ /dev/null @@ -1,91 +0,0 @@ -## @file CheckExplicit_jo.py -## @brief TopOptions (but dependent SplittableData_jo.py, EventSplit_jo.py): -## Checks that the root collection is readable with the EventSelector -## @author Jack Cranshaw (Jack.Cranshaw@cern.ch) -## $Id: CheckExplicit_jo.py,v 1.9 2009-05-20 13:34:21 cranshaw Exp $ -############################################################### -# -# Job options file -# -#============================================================== - -#-------------------------------------------------------------- -# Event related parameters -#-------------------------------------------------------------- -from AthenaCommon.AlgSequence import AthSequencer -topSequence = AthSequencer("AthAlgSeq") -athRegSeq = AthSequencer("AthRegSeq") - -from AthenaCommon.AppMgr import theApp - -from AthenaCommon.AppMgr import ServiceMgr as svcMgr - -theApp.EvtMax = 200000 - -#-------------------------------------------------------------- -# Load POOL support -#-------------------------------------------------------------- -include( "AthenaPoolExampleConverter/AthenaPoolExampleConverter_jobOption.py" ) -include( "AthenaPoolTestAthenaPool/AthenaPoolTestAthenaPool_joboptions.py" ) -#-------------------------------------------------------------- -#--- Read portion ----- -#-------------------------------------------------------------- -import AthenaPoolCnvSvc.ReadAthenaPool - -from PoolSvc.PoolSvcConf import PoolSvc -svcMgr += PoolSvc() -PoolSvc = svcMgr.PoolSvc -PoolSvc.ReadCatalog = ["xmlcatalog_file:EventSplit.xml"] - -EventSelector = svcMgr.EventSelector -EventSelector.InputCollections = [ "AthenaPoolMultiTest_StreamAll2.root" ]; - -# Include the StreamSelectorTool -from EventBookkeeperTools.EventBookkeeperToolsConf import StreamSelectorTool -# Select existing Stream1 -selector1 = StreamSelectorTool("Selector1") -selector1.AcceptStreams = ["Stream1"] -selector1.OutputLevel = DEBUG -svcMgr.EventSelector.HelperTools += [selector1] - -# Select existing Stream1, but use a separate CutFlowSvc -# Create the CutFlowSvc instance(s) -from EventBookkeeperTools.EventBookkeeperToolsConf import CutFlowSvc -cfs = CfgMgr.CutFlowSvc("SS_CutFlowSvc") -svcMgr += cfs -cfs.InputStream = "StreamAll" -cfs.OutputCollName = "StreamSelect" -# -selector2 = StreamSelectorTool("Selector2") -selector2.AcceptStreams = ["Stream1"] -selector2.CutFlowSvc = cfs -selector2.OutputLevel = DEBUG -svcMgr.EventSelector.HelperTools += [selector2] - -# Select non-existing StreamX -selectorx = StreamSelectorTool("SelectorX") -selectorx.AcceptStreams = ["StreamX"] -selectorx.OutputLevel = DEBUG -svcMgr.EventSelector.HelperTools += [selectorx] - -#-------------------------------------------------------------- -# Configure the filters -#-------------------------------------------------------------- -from AthenaPoolExampleAlgorithms.AthenaPoolExampleAlgorithmsConf import AthPoolEx__ReadData - -topSequence += AthPoolEx__ReadData("ReadData") -#from AthenaPoolMultiTest.AthenaPoolMultiTestConf import EventTagReader - -from AthenaPoolMultiTest.AthenaPoolMultiTestConf import * - -#-------------------------------------------------------------- -# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL) -#-------------------------------------------------------------- -svcMgr.MessageSvc.infoLimit = 5000 -svcMgr.MessageSvc.debugLimit = 5000 -svcMgr.MessageSvc.OutputLevel = INFO -#============================================================== -# -# End of job options file -# -############################################################### diff --git a/Event/EventBookkeeperTools/src/StreamSelectorTool.cxx b/Event/EventBookkeeperTools/src/StreamSelectorTool.cxx deleted file mode 100644 index 04cf7c636959..000000000000 --- a/Event/EventBookkeeperTools/src/StreamSelectorTool.cxx +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration -*/ - -/** @file StreamSelectorTool.cxx - * @brief This file contains the implementation for the StreamSelectorTool class. - * $Id: StreamSelectorTool.cxx,v 1.5 2009-03-17 09:44:46 cranshaw Exp $ - **/ -#include <algorithm> - -#include "GaudiKernel/ServiceHandle.h" -#include "StoreGate/StoreGateSvc.h" - -#include "StreamSelectorTool.h" -#include "PersistentDataModel/AthenaAttributeList.h" -#include "xAODCutFlow/CutBookkeeperContainer.h" - -//___________________________________________________________________________ -StreamSelectorTool::StreamSelectorTool(const std::string& type, const std::string& name, const IInterface* parent) : - AthAlgTool(type, name, parent), - m_cutflow("CutFlowSvc/CutFlowSvc",name) -{ - declareInterface<IAthenaSelectorTool>(this); - declareProperty("CutFlowSvc", m_cutflow, - "handle to the ICutFlowSvc instance this filtering algorithm" - " will use for building the flow of cuts."); - declareProperty("AcceptStreams",m_streamName,"Name of stream to be used as a ACCEPT, defaluts to ALL"); - declareProperty("VetoStreams",m_unstreamName,"Name of stream to be used as a VETO, defaluts to ALL"); -} -//___________________________________________________________________________ -StreamSelectorTool::~StreamSelectorTool() { -} - -//__________________________________________________________________________ -StatusCode StreamSelectorTool::postInitialize() { - ATH_MSG_DEBUG("... postInitialize"); - - ATH_CHECK(m_cutflow.retrieve()); - m_cutid = m_cutflow->registerFilter(this->name(),"Stream selection"); - if (0 == m_cutid) { - ATH_MSG_WARNING("Unable to register filter tool"); - } - - return StatusCode::SUCCESS; -} -//__________________________________________________________________________ -StatusCode StreamSelectorTool::postNext() const { - ATH_MSG_INFO("StreamSelectorTool::postNext"); - - StatusCode retc = StatusCode::SUCCESS; - - // if default, just return immediately - //if (m_streamName.size()>0 && m_streamName[0]=="ALL") return retc; - - // Use attribute list to filter on selected stream - const DataHandle<AthenaAttributeList> attrList; - StatusCode sc = evtStore()->retrieve(attrList,m_attrListKey); - if (sc.isSuccess()) { - ATH_MSG_DEBUG("Found attribute list"); - // fill the input bookkeeper - float weight = (*attrList)["EventWeight"].data<float>(); - // Search for stream name in attribute list, and check flag - for (auto sel = m_streamName.begin(); sel != m_streamName.end(); ++sel) { - // check veto - if ( attrList->specification().exists(*sel) ) { - bool dec(false); - bool veto(false); - // First check for vetoes - for (auto ivet = m_unstreamName.begin(); ivet != m_unstreamName.end(); ++ivet) { - try { - if ((*attrList)[*ivet].data<bool>()) { - ATH_MSG_DEBUG("Stream " << *ivet << " vetoed event"); - veto=true; - break; - } - } - catch (...) { - ATH_MSG_WARNING("Unable to access " << m_streamName << " decision"); - } - } - // if not vetoed, then look for accept - if (!veto) { - try { - dec = (*attrList)[*sel].data<bool>(); - } - catch (...) { - ATH_MSG_WARNING("Unable to access " << m_streamName << " decision"); - } - } else { - // exit loop as reject if already vetoed - retc = StatusCode::RECOVERABLE; - break; - } - // if not vetoed and decision found in attribute list - if (dec!=true) { - // Rejecting event - retc = StatusCode::RECOVERABLE; - ATH_MSG_DEBUG("Rejecting event"); - } else { - // Accepting event - ATH_MSG_DEBUG("Accepting event"); - m_cutflow->addEvent(m_cutid,weight); - } - } else { - ATH_MSG_ERROR("Stream decision for " << m_streamName << " does not exist in input"); - } - } - - uint64_t nAcceptedEvents = m_cutflow->getNAcceptedEvents(m_cutid); - if (nAcceptedEvents != std::numeric_limits<uint64_t>::max()) { - ATH_MSG_DEBUG(name() << ": For " << m_streamName << " cutflow events = " << nAcceptedEvents); - } - } - else { - ATH_MSG_WARNING("Could not find attribute list for " << m_attrListKey); - ATH_MSG_ERROR("Cannot do attributelist bookkeeping"); - } - return retc; -} -//__________________________________________________________________________ -StatusCode StreamSelectorTool::preNext() const { - return(StatusCode::SUCCESS); -} -//__________________________________________________________________________ diff --git a/Event/EventBookkeeperTools/src/StreamSelectorTool.h b/Event/EventBookkeeperTools/src/StreamSelectorTool.h deleted file mode 100644 index cc254b570fd6..000000000000 --- a/Event/EventBookkeeperTools/src/StreamSelectorTool.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef STREAMSELECTORTOOL_H -#define STREAMSELECTORTOOL_H - -/** @file StreamSelectorTool.h - * @brief This file contains the class definition for the StreamSelectorTool class. - * $Id: StreamSelectorTool.h,v 1.1 2008-12-10 21:28:11 gemmeren Exp $ - **/ - -#include "GaudiKernel/ServiceHandle.h" -#include "AthenaKernel/IAthenaSelectorTool.h" -#include "AthenaKernel/ICutFlowSvc.h" -#include "AthenaBaseComps/AthAlgTool.h" - -#include <string> - -/** @class StreamSelectorTool - * @brief This class provides an example for reading with a ISelectorTool to veto events on AttributeList. - **/ -class StreamSelectorTool : public AthAlgTool, virtual public IAthenaSelectorTool { -public: // Constructor and Destructor - /// Standard Service Constructor - StreamSelectorTool(const std::string& type, const std::string& name, const IInterface* parent); - /// Destructor - virtual ~StreamSelectorTool(); - -public: - /// IAthenaSelectorTool Interface method implementations: - virtual StatusCode initialize(); - virtual StatusCode postInitialize(); - virtual StatusCode preNext() const; - virtual StatusCode postNext() const; - virtual StatusCode preFinalize(); - virtual StatusCode finalize(); -private: - StringProperty m_attrListKey{this,"AttributeListKey","Input","Key for attribute list input to be used"}; - //StringArrayProperty m_streamName{this,"SelectedStreams","ALL","Name of stream to be used as a ACCEPT, defaluts to ALL"}; - //StringArrayProperty m_unstreamName{this,"DeselectedStreams","ALL","Name of stream to be used as a VETO, defaluts to ALL"}; - std::vector<std::string> m_streamName; - std::vector<std::string> m_unstreamName; - - ServiceHandle<ICutFlowSvc> m_cutflow; - CutIdentifier m_cutid; -}; - -inline StatusCode StreamSelectorTool::initialize() {return StatusCode::SUCCESS;} -inline StatusCode StreamSelectorTool::preFinalize() {return StatusCode::SUCCESS;} -inline StatusCode StreamSelectorTool::finalize() {return StatusCode::SUCCESS;} - -#endif diff --git a/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx b/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx index b7db38a32ec9..a2bb0fb8664b 100644 --- a/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx +++ b/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx @@ -5,7 +5,6 @@ #include "../CutFlowSvc.h" #include "../EventCounterAlg.h" #include "../SkimDecisionMultiFilter.h" -#include "../StreamSelectorTool.h" #include "../TestFilterReentrantAlg.h" DECLARE_COMPONENT( AllExecutedEventsCounterAlg ) @@ -14,5 +13,4 @@ DECLARE_COMPONENT( BookkeeperTool ) DECLARE_COMPONENT( CutFlowSvc ) DECLARE_COMPONENT( EventCounterAlg ) DECLARE_COMPONENT( SkimDecisionMultiFilter ) -DECLARE_COMPONENT( StreamSelectorTool ) DECLARE_COMPONENT( TestFilterReentrantAlg ) -- GitLab From 5100fa8a7b2968857e9d86bc30c1479247bd21e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Ma=C5=A1=C3=ADk?= <Jiri.Masik@manchester.ac.uk> Date: Thu, 29 Oct 2020 07:20:07 +0100 Subject: [PATCH 12/12] fix the override of the monitoring trigger list for taus --- .../TrigHLTMonitoring/python/HLTMonTriggerList.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonTriggerList.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonTriggerList.py index 80f5e3779c49..eaa544ad286c 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonTriggerList.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonTriggerList.py @@ -97,6 +97,7 @@ class HLTMonTriggerList: # Implementation of https://its.cern.ch/jira/browse/ATR-13200 def get_monitoring_mode(self): # Set monitoring mode + print ('jmasik: DQMonFlags.monManDataType(): ', DQMonFlags.monManDataType()) self.data_type = DQMonFlags.monManDataType() if self.data_type == 'monteCarlo': @@ -200,7 +201,8 @@ class HLTMonTriggerList: self.monitoring_tau = tau.monitoring_tau_pp #override if both pp and MC are true - if DQMonFlags.monManDataType()=='monteCarlo': + from AthenaCommon.GlobalFlags import globalflags + if globalflags.DataSource.get_Value() == 'geant4': self.monitoring_tau = tau.monitoring_tau_validation def set_HLTMonTrigList_HI(self): -- GitLab