9#include <nlohmann/json.hpp>
11#include <boost/math/distributions/poisson.hpp>
12using json = nlohmann::json;
21 ANA_MSG_INFO(
"WARNING: The Run3 SSV calibration has not been performed yet -> the scale factors are not usable yet");
48 return StatusCode::FAILURE;
78 std::ifstream jsonFile_SSVWeightsAlg(json_file_SSVWeightsAlg);
79 if (!jsonFile_SSVWeightsAlg.is_open()) {
81 return StatusCode::FAILURE;
85 jsonFile_SSVWeightsAlg.close();
90 return StatusCode::FAILURE;
109 return StatusCode::FAILURE;
117 else if (
m_nFMethod ==
"pileup_based_linearfit") {
121 else if (
m_nFMethod ==
"pileup_based_binned") {
126 ATH_MSG_ERROR(
"Unknown nF method: " <<
m_nFMethod <<
" , accepted nF methods are: 'pileup_bjet_based', 'pileup_based_linearfit', 'pileup_based_binned'");
127 return StatusCode::FAILURE;
151 return StatusCode::SUCCESS;
164 std::vector<const xAOD::Vertex*> SSVs;
166 SSVs.push_back(ssvvtx);
173 std::vector<const xAOD::Jet*> jets_Selected;
180 jets_Selected.push_back(
jet);
183 if (jet_btag_accessor(*
jet)){
184 b_jet_count = b_jet_count+1;
193 std::vector<const xAOD::Electron*> electrons_Selected;
198 electrons_Selected.push_back (
electron);
205 std::vector<const xAOD::Muon*> muons_Selected;
210 muons_Selected.push_back(
muon );
215 std::vector<const xAOD::Vertex*> good_SSVs =
create_good_SSVs(jets_Selected, electrons_Selected, muons_Selected, SSVs);
218 std::vector<const xAOD::TruthParticle*> truthBhs;
225 truthBhs.push_back(part);
245 double P_eff = std::pow(
m_SF_eff, N_matched);
257 return StatusCode::FAILURE;
272 ATH_MSG_ERROR(
"Unknown nF method: " <<
m_nFMethod <<
" , accepted nF methods are: 'pileup_bjet_based', 'pileup_based_linearfit', 'pileup_based_binned'");
273 return StatusCode::FAILURE;
277 double SSV_weight = P_eff * P_ineff * P_fake;
312 return StatusCode::SUCCESS;
317 const std::vector<const xAOD::Jet*> &jets,
318 const std::vector<const xAOD::Electron*> &electrons,
319 const std::vector<const xAOD::Muon*> &muons,
320 const std::vector<const xAOD::Vertex*> &SSVs)
const {
326 std::vector<const xAOD::Vertex*> good_SSVs;
329 bool overlaps =
false;
332 if ( (ssv_pt_accessor(*SSV) < 3000) || (ssv_m_accessor(*SSV) < 600) || (std::abs(ssv_eta_accessor(*SSV)) > 2.5) ){
339 if (DeltaR_jet < 0.6){
345 if (overlaps ==
true){
351 if (DeltaR_el < 0.2){
357 if (overlaps ==
true){
364 if (DeltaR_mu < 0.2){
370 if (overlaps ==
true){
373 good_SSVs.push_back(SSV);
380 const std::vector<const xAOD::TruthParticle*> &truthBhs,
381 const std::vector<const xAOD::Jet*> &jets)
const {
383 std::vector<const xAOD::TruthParticle*> accepted_truthBhs;
387 if (truthBh->pt() < 2000 || (std::abs(truthBh->eta()) > 2.8)){
392 bool overlaps =
false;
394 double DeltaR = truthBh->p4().DeltaR(
jet->p4());
401 if (overlaps ==
true){
405 accepted_truthBhs.push_back(truthBh);
407 return accepted_truthBhs;
411 const std::vector<const xAOD::TruthParticle*> &truthBhs,
412 const std::vector<const xAOD::Vertex*> &SSVs)
const {
416 bool foundMatch =
false;
428 N_fake_SSV = N_fake_SSV + 1;
439 const std::vector<const xAOD::TruthParticle*> &truthBhs,
440 const std::vector<const xAOD::Vertex*> &SSVs)
const {
442 std::vector<bool> matched_vector(truthBhs.size(),
false);
443 for (
size_t i = 0; i < truthBhs.size(); ++i){
445 for (
size_t j = 0; j < SSVs.size(); ++j){
449 matched_vector[i] =
true;
454 return matched_vector;
465 double eta_diff = ssv_eta_accessor(*vtx) - part->eta() ;
469 double phi_diff = TVector2::Phi_mpi_pi(ssv_phi_accessor(*vtx) - part->phi() );
472 return std::sqrt( eta_diff*eta_diff + phi_diff*phi_diff );
478 const std::vector<bool> &matching_vector)
const {
481 return std::count(matching_vector.begin(), matching_vector.end(),
true);
487 const std::vector<bool> &matching_vector)
const {
493 const std::vector<const xAOD::TruthParticle*> &truthBhs,
494 const std::vector<bool> &matched_vector) {
496 std::vector<const xAOD::TruthParticle*> missed_vector;
497 for (
size_t i = 0; i < truthBhs.size(); ++i){
498 if (matched_vector[i] ==
false){
499 missed_vector.push_back(truthBhs[i]);
502 return missed_vector;
508 const int type)
const {
510 for (
unsigned int i = 0; i < part->nChildren(); ++i){
542 const double lambda){
544 boost::math::poisson distrib(lambda);
545 return boost::math::pdf(distrib, k);
552 for (
size_t i = 0; i <
m_ptbins.size() - 1; ++i) {
553 std::string pT_bin_key =
"pt_bin_" + std::to_string((
int)
m_ptbins[i]) +
"_" + std::to_string((
int)
m_ptbins[i+1]);
561 const std::vector<const xAOD::TruthParticle*> &accepted_truthBhs,
562 const std::vector<bool> &truthBh_to_SSV_matched,
563 double SF_eff)
const{
568 const std::vector<double> &ptbins =
m_ptbins;
571 for (
size_t i = 0; i < missed_truthBhs.size(); ++i) {
573 double pt = missed_truthBhs[i]->pt();
574 double eta = std::abs(missed_truthBhs[i]->
eta());
575 std::string pt_bin_of_truthBh =
"";
577 for (
size_t j = 0; j < ptbins.size() - 1; ++j) {
578 if (
pt >= ptbins[j] &&
pt < ptbins[j+1]) {
580 pt_bin_of_truthBh =
"pt_bin_" + std::to_string((
int)ptbins[j]) +
"_" + std::to_string((
int)ptbins[j+1]);
583 pt_bin_of_truthBh =
"pt_bin_" + std::to_string(
m_upperboundpT) +
"plus";
586 if (pt_bin_of_truthBh ==
""){
597 for (
size_t k = 0; k < eta_bins.size() - 1; ++k) {
598 double eta_low = eta_bins[k];
599 double eta_up = eta_bins[k+1];
600 if (
eta >= eta_low &&
eta < eta_up) {
616 std::string lastItemKey = lastItem->first;
623 const int b_jet_count,
625 const double SF_eff)
const{
635 std::string bjets_key = std::to_string(b_jet_count) +
"_bjets";
643 P_ineff = std::pow((1-SF_eff*epsilon)/(1-epsilon), N_missed);
652 std::map<std::string, double>::iterator lastItem = std::prev(
m_nFPileupBJetMap.at(
"high_muactual").end());
653 std::string lastItemKey = lastItem->first;
660 const double muactual,
661 const int b_jet_count,
663 const double SF_fake_low,
664 const double SF_fake_high)
const{
671 double n_F_value = 0;
675 std::string bjets_key = std::to_string(b_jet_count) +
"_bjets";
696 m_slopeUnscaled = jsonConfig[
"nF_pileup_based_linearfit"][
"unscaled"][
"slope"];
698 m_slopeScaled = jsonConfig[
"nF_pileup_based_linearfit"][
"scaled"][
"slope"];
699 m_interceptScaled = jsonConfig[
"nF_pileup_based_linearfit"][
"scaled"][
"intercept"];
704 const double muactual,
705 const int N_fake)
const{
727 const double muactual,
729 const double SF_fake_low,
730 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
virtual StatusCode execute() override
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
SG::ConstAccessor< T, ALLOC > ConstAccessor
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".