9#include <nlohmann/json.hpp>
11using json = nlohmann::json;
20 ANA_MSG_INFO(
"WARNING: The Run3 SSV calibration has not been performed yet -> the scale factors are not usable yet");
47 return StatusCode::FAILURE;
77 std::ifstream jsonFile_SSVWeightsAlg(json_file_SSVWeightsAlg);
78 if (!jsonFile_SSVWeightsAlg.is_open()) {
80 return StatusCode::FAILURE;
84 jsonFile_SSVWeightsAlg.close();
89 return StatusCode::FAILURE;
108 return StatusCode::FAILURE;
116 else if (
m_nFMethod ==
"pileup_based_linearfit") {
120 else if (
m_nFMethod ==
"pileup_based_binned") {
125 ATH_MSG_ERROR(
"Unknown nF method: " <<
m_nFMethod <<
" , accepted nF methods are: 'pileup_bjet_based', 'pileup_based_linearfit', 'pileup_based_binned'");
126 return StatusCode::FAILURE;
150 return StatusCode::SUCCESS;
163 std::vector<const xAOD::Vertex*> SSVs;
165 SSVs.push_back(ssvvtx);
172 std::vector<const xAOD::Jet*> jets_Selected;
174 static const SG::AuxElement::ConstAccessor<char> jet_btag_accessor(
m_BTaggingWP);
179 jets_Selected.push_back(
jet);
182 if (jet_btag_accessor(*
jet)){
183 b_jet_count = b_jet_count+1;
192 std::vector<const xAOD::Electron*> electrons_Selected;
197 electrons_Selected.push_back (
electron);
204 std::vector<const xAOD::Muon*> muons_Selected;
209 muons_Selected.push_back(
muon );
214 std::vector<const xAOD::Vertex*> good_SSVs =
create_good_SSVs(jets_Selected, electrons_Selected, muons_Selected, SSVs);
217 std::vector<const xAOD::TruthParticle*> truthBhs;
224 truthBhs.push_back(part);
244 double P_eff = std::pow(
m_SF_eff, N_matched);
256 return StatusCode::FAILURE;
271 ATH_MSG_ERROR(
"Unknown nF method: " <<
m_nFMethod <<
" , accepted nF methods are: 'pileup_bjet_based', 'pileup_based_linearfit', 'pileup_based_binned'");
272 return StatusCode::FAILURE;
276 double SSV_weight = P_eff * P_ineff * P_fake;
311 return StatusCode::SUCCESS;
316 const std::vector<const xAOD::Jet*> &jets,
317 const std::vector<const xAOD::Electron*> &electrons,
318 const std::vector<const xAOD::Muon*> &muons,
319 const std::vector<const xAOD::Vertex*> &SSVs)
const {
321 static const SG::AuxElement::ConstAccessor<float> ssv_pt_accessor((
"bvrtPt"));
322 static const SG::AuxElement::ConstAccessor<float> ssv_m_accessor(
"bvrtM");
323 static const SG::AuxElement::ConstAccessor<float> ssv_eta_accessor(
"bvrtEta");
325 std::vector<const xAOD::Vertex*> good_SSVs;
328 bool overlaps =
false;
331 if ( (ssv_pt_accessor(*SSV) < 3000) || (ssv_m_accessor(*SSV) < 600) || (std::abs(ssv_eta_accessor(*SSV)) > 2.5) ){
338 if (DeltaR_jet < 0.6){
344 if (overlaps ==
true){
350 if (DeltaR_el < 0.2){
356 if (overlaps ==
true){
363 if (DeltaR_mu < 0.2){
369 if (overlaps ==
true){
372 good_SSVs.push_back(SSV);
379 const std::vector<const xAOD::TruthParticle*> &truthBhs,
380 const std::vector<const xAOD::Jet*> &jets)
const {
382 std::vector<const xAOD::TruthParticle*> accepted_truthBhs;
386 if (truthBh->pt() < 2000 || (std::abs(truthBh->eta()) > 2.8)){
391 bool overlaps =
false;
393 double DeltaR = truthBh->p4().DeltaR(
jet->p4());
400 if (overlaps ==
true){
404 accepted_truthBhs.push_back(truthBh);
406 return accepted_truthBhs;
410 const std::vector<const xAOD::TruthParticle*> &truthBhs,
411 const std::vector<const xAOD::Vertex*> &SSVs)
const {
415 bool foundMatch =
false;
427 N_fake_SSV = N_fake_SSV + 1;
438 const std::vector<const xAOD::TruthParticle*> &truthBhs,
439 const std::vector<const xAOD::Vertex*> &SSVs)
const {
441 std::vector<bool> matched_vector(truthBhs.size(),
false);
442 for (
size_t i = 0; i < truthBhs.size(); ++i){
444 for (
size_t j = 0; j < SSVs.size(); ++j){
448 matched_vector[i] =
true;
453 return matched_vector;
461 static const SG::AuxElement::ConstAccessor<float> ssv_eta_accessor(
"bvrtEta");
462 static const SG::AuxElement::ConstAccessor<float> ssv_phi_accessor(
"bvrtPhi");
464 double eta_diff = ssv_eta_accessor(*vtx) - part->eta() ;
468 double phi_diff = TVector2::Phi_mpi_pi(ssv_phi_accessor(*vtx) - part->phi() );
471 return std::sqrt( eta_diff*eta_diff + phi_diff*phi_diff );
477 const std::vector<bool> &matching_vector)
const {
480 return std::count(matching_vector.begin(), matching_vector.end(),
true);
486 const std::vector<bool> &matching_vector)
const {
492 const std::vector<const xAOD::TruthParticle*> &truthBhs,
493 const std::vector<bool> &matched_vector) {
495 std::vector<const xAOD::TruthParticle*> missed_vector;
496 for (
size_t i = 0; i < truthBhs.size(); ++i){
497 if (matched_vector[i] ==
false){
498 missed_vector.push_back(truthBhs[i]);
501 return missed_vector;
507 const int type)
const {
509 for (
unsigned int i = 0; i < part->nChildren(); ++i){
541 const double lambda){
542 if (lambda == 0.0 )
return k == 0.0 ? 1.0 : 0.0;
543 if (lambda < 0 || k < 0)
return 0.0;
544 return std::exp(-lambda + k * std::log(lambda) - std::lgamma(k + 1));
551 for (
size_t i = 0; i <
m_ptbins.size() - 1; ++i) {
552 std::string pT_bin_key =
"pt_bin_" + std::to_string((
int)
m_ptbins[i]) +
"_" + std::to_string((
int)
m_ptbins[i+1]);
560 const std::vector<const xAOD::TruthParticle*> &accepted_truthBhs,
561 const std::vector<bool> &truthBh_to_SSV_matched,
562 double SF_eff)
const{
567 const std::vector<double> &ptbins =
m_ptbins;
570 for (
size_t i = 0; i < missed_truthBhs.size(); ++i) {
572 double pt = missed_truthBhs[i]->pt();
573 double eta = std::abs(missed_truthBhs[i]->
eta());
574 std::string pt_bin_of_truthBh =
"";
576 for (
size_t j = 0; j < ptbins.size() - 1; ++j) {
577 if (
pt >= ptbins[j] &&
pt < ptbins[j+1]) {
579 pt_bin_of_truthBh =
"pt_bin_" + std::to_string((
int)ptbins[j]) +
"_" + std::to_string((
int)ptbins[j+1]);
582 pt_bin_of_truthBh =
"pt_bin_" + std::to_string(
m_upperboundpT) +
"plus";
585 if (pt_bin_of_truthBh ==
""){
596 for (
size_t k = 0; k < eta_bins.size() - 1; ++k) {
597 double eta_low = eta_bins[k];
598 double eta_up = eta_bins[k+1];
599 if (
eta >= eta_low &&
eta < eta_up) {
615 std::string lastItemKey = lastItem->first;
622 const int b_jet_count,
624 const double SF_eff)
const{
634 std::string bjets_key = std::to_string(b_jet_count) +
"_bjets";
642 P_ineff = std::pow((1-SF_eff*epsilon)/(1-epsilon), N_missed);
651 std::map<std::string, double>::iterator lastItem = std::prev(
m_nFPileupBJetMap.at(
"high_muactual").end());
652 std::string lastItemKey = lastItem->first;
659 const double muactual,
660 const int b_jet_count,
662 const double SF_fake_low,
663 const double SF_fake_high)
const{
670 double n_F_value = 0;
674 std::string bjets_key = std::to_string(b_jet_count) +
"_bjets";
695 m_slopeUnscaled = jsonConfig[
"nF_pileup_based_linearfit"][
"unscaled"][
"slope"];
697 m_slopeScaled = jsonConfig[
"nF_pileup_based_linearfit"][
"scaled"][
"slope"];
698 m_interceptScaled = jsonConfig[
"nF_pileup_based_linearfit"][
"scaled"][
"intercept"];
703 const double muactual,
704 const int N_fake)
const{
726 const double muactual,
728 const double SF_fake_low,
729 const double SF_fake_high)
const{
Scalar eta() const
pseudorapidity method
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
TEfficiency * efficiency(const std::string &effName, const std::string &tDir="", const std::string &stream="")
Simplify the retrieval of registered TEfficiency.
EfficiencyMethodBJetBasedClass(const nlohmann::json &jsonConfig)
double getPIneff(const int b_jet_count, const int N_missed, const double SF_eff) const
std::map< std::string, double > m_bjetEfficiencyMap
EfficiencyMethodBhadronPtEtaBasedClass(const nlohmann::json &jsonConfig)
std::map< std::string, std::map< std::string, std::vector< double > > > m_BhadronPtEtaEfficiencyMap
double getPIneff(const std::vector< const xAOD::TruthParticle * > &accepted_truthBh, const std::vector< bool > &truthBh_to_SSV_matched, double SF_eff) const
std::vector< double > m_ptbins
double getPFake(const double muactual, const int b_jet_count, const int N_fake, const double SF_fake_low, const double SF_fake_high) const
double m_lowMuHighMuThreshold
nFMethodPileupBJetBasedClass(const nlohmann::json &jsonConfig)
std::map< std::string, std::map< std::string, double > > m_nFPileupBJetMap
std::vector< double > m_muactualBins
double getPFake(const double muactual, const int N_fake, const double SF_fake_low, const double SF_fake_high) const
nFMethodPileupBasedBinnedClass(const nlohmann::json &jsonConfig)
std::vector< double > m_nFBins
double m_lowMuHighMuThreshold
double getPFake(const double muactual, const int N_fake) const
nFMethodPileupBasedLinearFitClass(const nlohmann::json &jsonConfig)
double m_interceptUnscaled
CP::SysReadSelectionHandle m_muonSelection
std::vector< bool > truthBh_to_SSV_matching(const std::vector< const xAOD::TruthParticle * > &truthBhs, const std::vector< const xAOD::Vertex * > &SSVs) const
int count_not_matched_objects(const std::vector< bool > &matching_vector) const
CP::SysWriteDecorHandle< float > m_number_of_good_SSVs_decor
CP::SysReadHandle< xAOD::JetContainer > m_jetsHandle
OutputVariableSizeType m_OutputVariableSizeType
CP::SysReadHandle< xAOD::VertexContainer > m_ssvHandle
std::unique_ptr< nFMethodPileupBasedLinearFitClass > m_nFPileupBasedLinearFitPtr
CP::SysWriteDecorHandle< float > m_SSV_weight_decor
std::vector< const xAOD::Vertex * > create_good_SSVs(const std::vector< const xAOD::Jet * > &jets, const std::vector< const xAOD::Electron * > &electrons, const std::vector< const xAOD::Muon * > &muons, const std::vector< const xAOD::Vertex * > &SSVs) const
std::unique_ptr< EfficiencyMethodBJetBasedClass > m_EfficiencyMethodBJetBasedPtr
CP::SysReadHandle< xAOD::MuonContainer > m_muonsHandle
virtual StatusCode initialize() override
double compute_DeltaR_between_SSV_and_particle(const xAOD::Vertex *vtx, const xAOD::IParticle *part) const
CP::SysWriteDecorHandle< float > m_P_fake_pileup_based_linearfit_decor
static const std::vector< const xAOD::TruthParticle * > construct_not_matched_vectors(const std::vector< const xAOD::TruthParticle * > &truthBhs, const std::vector< bool > &matched_vector)
std::unique_ptr< EfficiencyMethodBhadronPtEtaBasedClass > m_EfficiencyMethodBhadronPtEtaBasedPtr
nlohmann::json m_jsonConfig_SSVWeightsAlg
bool isHFHadronFinalState(const xAOD::TruthParticle *part, const int type) const
std::vector< const xAOD::TruthParticle * > create_accepted_truthBhs(const std::vector< const xAOD::TruthParticle * > &truthBhs, const std::vector< const xAOD::Jet * > &jets) const
CP::SysWriteDecorHandle< float > m_N_missed_decor
CP::SysWriteDecorHandle< float > m_number_of_accepted_Bhadrons_decor
CP::SysReadSelectionHandle m_electronSelection
static double poisson_pmf(const int k, const double lambda)
CP::SysWriteDecorHandle< float > m_number_of_bjets_decor
int count_matched_objects(const std::vector< bool > &matching_vector) const
Gaudi::Property< std::string > m_jsonConfigPath_SSVWeightsAlg
nFMethodType m_nFMethodType
CP::SysWriteDecorHandle< float > m_N_matched_decor
CP::SysWriteDecorHandle< float > m_P_fake_pileup_bjet_based_decor
Gaudi::Property< std::string > m_nFMethod
Gaudi::Property< std::string > m_EfficiencyMethod
CP::SysReadHandle< xAOD::TruthParticleContainer > m_truthParticlesHandle
std::unique_ptr< nFMethodPileupBJetBasedClass > m_nFPileupBJetBasedPtr
CP::SysWriteDecorHandle< float > m_P_ineff_bjet_based_decor
CP::SysWriteDecorHandle< float > m_P_ineff_decor
SSVWeightsAlg(const std::string &name, ISvcLocator *pSvcLocator)
CP::SysReadSelectionHandle m_jetSelection
int count_number_of_fake_SSVs(const std::vector< const xAOD::TruthParticle * > &truthBhs, const std::vector< const xAOD::Vertex * > &SSVs) const
CP::SysReadHandle< xAOD::EventInfo > m_eventInfoHandle
CP::SysListHandle m_systematicsList
Gaudi::Property< std::string > m_OutputVariableSize
Gaudi::Property< std::string > m_BTaggingWP
CP::SysWriteDecorHandle< float > m_P_ineff_pt_eta_based_decor
CP::SysWriteDecorHandle< float > m_P_fake_pileup_based_binned_decor
CP::SysWriteDecorHandle< float > m_N_fake_decor
CP::SysWriteDecorHandle< float > m_P_fake_decor
CP::SysReadHandle< xAOD::ElectronContainer > m_electronsHandle
CP::SysWriteDecorHandle< float > m_P_eff_decor
EfficiencyMethodType m_EfficiencyMethodType
std::unique_ptr< nFMethodPileupBasedBinnedClass > m_nFPileupBasedBinnedPtr
AnaAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
constructor with parameters
virtual::StatusCode execute()
execute this algorithm
float actualInteractionsPerCrossing() const
Average interactions per crossing for the current BCID - for in-time pile-up.
Class providing the definition of the 4-vector interface.
bool isBottomHadron() const
Determine if the PID is that of a b-hadron.
bool isGenStable() const
Check if this is generator stable particle.
bool isCharmHadron() const
Determine if the PID is that of a c-hadron.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Select isolated Photons, Electrons and Muons.
This module defines the arguments passed from the BATCH driver to the BATCH worker.
Jet_v1 Jet
Definition of the current "jet version".
setRcore setEtHad setFside pt
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TruthParticle_v1 TruthParticle
Typedef to implementation.
Muon_v1 Muon
Reference the current persistent version:
JetContainer_v1 JetContainer
Definition of the current "jet container version".
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.
Electron_v1 Electron
Definition of the current "egamma version".