9#include <nlohmann/json.hpp>
11#include <boost/math/distributions/poisson.hpp>
12using json = nlohmann::json;
18 declareProperty(
"BTagging_WP",
m_BTagging_WP,
"b-tagging working point that is used to count the number of b-jets in the event for b-jet based SSV weight calculation");
19 declareProperty(
"OverlapRemoval",
m_OverlapRemoval,
"string that will be used in the overlap removal accessor for jets, electrons and muons; empty string means no overlap removal will be applied");
20 declareProperty(
"Jvt",
m_Jvt,
"string that will be used in the jvt accessor for jets; empty string means no jvt selection will be applied");
21 declareProperty(
"efficiency_Method",
m_efficiency_Method,
"efficiency definition that will be used to calculate the SSV weights, string can be 'Bhadron_pT_eta_based' or 'bjet_based'");
22 declareProperty(
"nF_Method",
m_nF_Method,
"average number of fake SSV definition that will be used to calculate the SSV weights, string can be 'pileup_bjet_based','pileup_based_linearfit' or 'pileup_based_binned'");
23 declareProperty(
"OutputVariable_Size",
m_OutputVariable_Size,
"number of variables that will be saved to the output, string can be 'standard','extended','additional' or 'all'");
29 ANA_MSG_INFO(
"WARNING: The Run3 SSV calibration has not been performed yet -> the scale factors are not usable yet");
61 std::ifstream jsonFile_SSVWeightsAlg(json_file_SSVWeightsAlg);
62 if (!jsonFile_SSVWeightsAlg.is_open()) {
64 return StatusCode::FAILURE;
68 jsonFile_SSVWeightsAlg.close();
70 return StatusCode::SUCCESS;
83 std::vector<const xAOD::Vertex*> SSVs;
85 SSVs.push_back(ssvvtx);
92 std::vector<const xAOD::Jet*> jets_PassedORJvt;
101 bool useJvt = !
m_Jvt.empty();
106 char jet_passesOR_char = useOR ? particle_passesOR_accessor(*
jet) : 1;
107 char jet_jvt_selection_char = useJvt ? jet_jvt_selection_accessor(*
jet) : 1;
109 if (jet_passesOR_char && jet_jvt_selection_char){
110 jets_PassedORJvt.push_back(
jet);
113 if (jet_btag_accessor(*
jet)){
114 b_jet_count = b_jet_count+1;
123 std::vector<const xAOD::Electron*> electrons_PassedOR;
127 char electron_passesOR_char = useOR ? particle_passesOR_accessor(*
electron) : 1;
128 if (electron_passesOR_char){
129 electrons_PassedOR.push_back (
electron);
136 std::vector<const xAOD::Muon*> muons_PassedOR;
140 char muon_passesOR_char = useOR ? particle_passesOR_accessor(*
muon) : 1;
141 if (muon_passesOR_char){
142 muons_PassedOR.push_back(
muon );
147 std::vector<const xAOD::Vertex*> good_SSVs =
create_good_SSVs(jets_PassedORJvt, electrons_PassedOR, muons_PassedOR, SSVs);
150 std::vector<const xAOD::TruthParticle*> truthBhs;
157 truthBhs.push_back(part);
181 double P_eff = std::pow(SF_eff, N_matched);
193 return StatusCode::FAILURE;
210 return StatusCode::FAILURE;
215 double SSV_weight = P_eff * P_ineff * P_fake;
249 return StatusCode::SUCCESS;
254 const std::vector<const xAOD::Jet*> &jets,
255 const std::vector<const xAOD::Electron*> &electrons,
256 const std::vector<const xAOD::Muon*> &muons,
257 const std::vector<const xAOD::Vertex*> &SSVs)
const {
263 std::vector<const xAOD::Vertex*> good_SSVs;
266 bool overlaps =
false;
269 if ( (ssv_pt_accessor(*SSV) < 3000) || (ssv_m_accessor(*SSV) < 600) || (std::abs(ssv_eta_accessor(*SSV)) > 2.5) ){
276 if (DeltaR_jet < 0.6){
282 if (overlaps ==
true){
288 if (DeltaR_el < 0.2){
294 if (overlaps ==
true){
301 if (DeltaR_mu < 0.2){
307 if (overlaps ==
true){
310 good_SSVs.push_back(SSV);
317 const std::vector<const xAOD::TruthParticle*> &truthBhs,
318 const std::vector<const xAOD::Jet*> &jets)
const {
320 std::vector<const xAOD::TruthParticle*> accepted_truthBhs;
324 if (truthBh->pt() < 2000 || (std::abs(truthBh->eta()) > 2.8)){
329 bool overlaps =
false;
331 double DeltaR = truthBh->p4().DeltaR(
jet->p4());
338 if (overlaps ==
true){
342 accepted_truthBhs.push_back(truthBh);
344 return accepted_truthBhs;
348 const std::vector<const xAOD::TruthParticle*> &truthBhs,
349 const std::vector<const xAOD::Vertex*> &SSVs)
const {
353 bool foundMatch =
false;
365 N_fake_SSV = N_fake_SSV + 1;
376 const std::vector<const xAOD::TruthParticle*> &truthBhs,
377 const std::vector<const xAOD::Vertex*> &SSVs)
const {
379 std::vector<bool> matched_vector(truthBhs.size(),
false);
380 for (
size_t i = 0; i < truthBhs.size(); ++i){
382 for (
size_t j = 0; j < SSVs.size(); ++j){
386 matched_vector[i] =
true;
391 return matched_vector;
402 double eta_diff = ssv_eta_accessor(*vtx) - part->eta() ;
406 double phi_diff = TVector2::Phi_mpi_pi(ssv_phi_accessor(*vtx) - part->phi() );
409 return std::sqrt( eta_diff*eta_diff + phi_diff*phi_diff );
415 const std::vector<bool> &matching_vector)
const {
418 return std::count(matching_vector.begin(), matching_vector.end(),
true);
424 const std::vector<bool> &matching_vector)
const {
430 const std::vector<const xAOD::TruthParticle*> &truthBhs,
431 const std::vector<bool> &matched_vector)
const {
433 std::vector<const xAOD::TruthParticle*> missed_vector;
434 for (
size_t i = 0; i < truthBhs.size(); ++i){
435 if (matched_vector[i] ==
false){
436 missed_vector.push_back(truthBhs[i]);
439 return missed_vector;
445 const int type)
const {
447 for (
unsigned int i = 0; i < part->nChildren(); ++i){
479 const double lambda)
const {
481 boost::math::poisson distrib(lambda);
482 return boost::math::pdf(distrib, k);
487 const std::vector<const xAOD::TruthParticle*> &accepted_truthBhs,
488 const std::vector<bool> &truthBh_to_SSV_matched,
489 double SF_eff)
const{
497 for (
size_t i = 0; i < missed_truthBhs.size(); ++i) {
499 double pt = missed_truthBhs[i]->pt();
500 double eta = std::abs(missed_truthBhs[i]->
eta());
501 std::string pt_bin_of_truthBh =
"";
503 for (
size_t j = 0; j < ptbins.size() - 1; ++j) {
504 if (
pt >= ptbins[j] &&
pt < ptbins[j+1]) {
506 pt_bin_of_truthBh =
"pt_bin_" + std::to_string((
int)ptbins[j]) +
"_" + std::to_string((
int)ptbins[j+1]);
509 pt_bin_of_truthBh =
"pt_bin_43500_100000";
512 if (pt_bin_of_truthBh ==
""){
518 const std::vector<double>& efficiencies =
m_jsonConfig_SSVWeightsAlg[
"Efficiency_pt_eta_based"][pt_bin_of_truthBh][
"efficiency"];
523 for (
size_t k = 0; k < eta_bins.size() - 1; ++k) {
524 double eta_low = eta_bins[k];
525 double eta_up = eta_bins[k+1];
526 if (
eta >= eta_low &&
eta < eta_up) {
539 const int b_jet_count,
541 const double SF_eff)
const{
545 std::string bjets_key = std::to_string(b_jet_count) +
"_bjets";
551 if (b_jet_count<5 && b_jet_count>0){
554 if (b_jet_count > 4){
557 if (b_jet_count < 1){
561 P_ineff = std::pow((1-SF_eff*epsilon)/(1-epsilon), N_missed);
568 const double muactual,
569 const int b_jet_count,
571 const double SF_fake_low,
572 const double SF_fake_high)
const{
579 std::string bjets_key = std::to_string(b_jet_count) +
"_bjets";
582 double n_F_value = 0;
584 if (b_jet_count<5 && b_jet_count>0){
606 const double muactual,
607 const int N_fake)
const{
616 double n_F = slope_unscaled * muactual + intercept_unscaled;
617 double n_F_scaled = slope_scaled * muactual + intercept_scaled;
627 const double muactual,
629 const double SF_fake_low,
630 const double SF_fake_high)
const{
632 std::vector<double> muactualbins =
m_jsonConfig_SSVWeightsAlg[
"nF_pileup_based_binned"][
"muactual_bins"].get<std::vector<double>>();
639 for (
size_t j = 0; j < muactualbins.size() - 1; ++j) {
640 if (muactual >= muactualbins[j] && muactual < muactualbins[j + 1]) {
Scalar eta() const
pseudorapidity method
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
TEfficiency * efficiency(const std::string &effName, const std::string &tDir="", const std::string &stream="")
Simplify the retrieval of registered TEfficiency.
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
const double m_lowMuHighMuThreshold
CP::SysReadHandle< xAOD::JetContainer > m_jetsHandle
CP::SysReadHandle< xAOD::VertexContainer > m_ssvHandle
CP::SysWriteDecorHandle< float > m_SSV_weight_decor
std::string m_OutputVariable_Size
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
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
double calculate_P_ineff_bjet_based(const int b_jet_count, const int N_missed, const double SF_eff) const
double calculate_P_fake_pileup_based_binned(const double muactual, const int N_fake, const double SF_fake_low, const double SF_fake_high) const
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
double calculate_P_fake_pileup_bjet_based(const double muactual, const int b_jet_count, const int N_fake, const double SF_fake_low, const double SF_fake_high) const
double calculate_P_ineff_Bhadron_pt_eta_based(const std::vector< const xAOD::TruthParticle * > &accepted_truthBh, const std::vector< bool > &truthBh_to_SSV_matched, double SF_eff) const
CP::SysWriteDecorHandle< float > m_N_missed_decor
CP::SysWriteDecorHandle< float > m_number_of_accepted_Bhadrons_decor
CP::SysWriteDecorHandle< float > m_number_of_bjets_decor
virtual StatusCode execute() override
int count_matched_objects(const std::vector< bool > &matching_vector) const
CP::SysWriteDecorHandle< float > m_N_matched_decor
CP::SysWriteDecorHandle< float > m_P_fake_pileup_bjet_based_decor
CP::SysReadHandle< xAOD::TruthParticleContainer > m_truthParticlesHandle
double poisson_pmf(const int k, const double lambda) const
CP::SysWriteDecorHandle< float > m_P_ineff_bjet_based_decor
CP::SysWriteDecorHandle< float > m_P_ineff_decor
SSVWeightsAlg(const std::string &name, ISvcLocator *pSvcLocator)
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
double calculate_P_fake_pileup_based_linearfit(const double muactual, const int N_fake) const
std::string m_OverlapRemoval
const std::vector< const xAOD::TruthParticle * > construct_not_matched_vectors(const std::vector< const xAOD::TruthParticle * > &truthBhs, const std::vector< bool > &matched_vector) const
CP::SysWriteDecorHandle< float > m_P_ineff_pt_eta_based_decor
CP::SysWriteDecorHandle< float > m_P_fake_pileup_based_binned_decor
std::string m_efficiency_Method
CP::SysWriteDecorHandle< float > m_N_fake_decor
std::string m_BTagging_WP
std::string m_jsonConfigPath_SSVWeightsAlg
CP::SysWriteDecorHandle< float > m_P_fake_decor
CP::SysReadHandle< xAOD::ElectronContainer > m_electronsHandle
CP::SysWriteDecorHandle< float > m_P_eff_decor
AnaAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
constructor with parameters
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
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.
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".