41         m_saltModel = std::make_shared<FlavorTagInference::SaltModel>(fullPathToOnnxFile);
 
   44         m_saltModel_endcap = std::make_shared<FlavorTagInference::SaltModel>(fullPathToOnnxFile_endcap);
 
   50         std::map<std::string, FlavorTagInference::Inputs> gnn_input;
 
   53         std::vector<int64_t> elec_feat_dim = {1, 
static_cast<int64_t
>(elec_feat.size())};
 
   55         gnn_input.insert({
"jet_features", elec_info}); 
 
   60         gnn_input.insert({
"track_features", track_info});
 
   62         auto [out_f, out_vc, out_vf] = 
m_saltModel->runInference(gnn_input); 
 
   64         std::vector<std::string> output_names;
 
   65         for (
auto& singlefloat : out_f){
 
   69           output_names.push_back(
outname);
 
   76         m_saltModel = std::make_shared<FlavorTagInference::SaltModel>(fullPathToOnnxFile);
 
   82         std::map<std::string, FlavorTagInference::Inputs> gnn_input;
 
   85         std::vector<int64_t> muon_feat_dim = {1, 
static_cast<int64_t
>(muon_feat.size())};
 
   87         gnn_input.insert({
"jet_features", muon_info}); 
 
   92         gnn_input.insert({
"track_features", track_info});
 
   94         auto [out_f, out_vc, out_vf] = 
m_saltModel->runInference(gnn_input); 
 
   96         std::vector<std::string> output_names;
 
   97         for (
auto& singlefloat : out_f){
 
   99           std::string 
outname = 
m_muonsKey.
key()+
"." + 
m_TaggerName + 
"_" + (singlefloat.first.find(
"muxpromp") != std::string::npos ? 
"TPLTmu_pmuxpromp" : 
"TPLTmu_pnpxall" );
 
  101           output_names.push_back(
outname);
 
  108       return StatusCode::FAILURE;
 
  113     return StatusCode::SUCCESS;
 
  121     if (!tracks->
empty()) {
 
  131         std::vector<SG::WriteDecorHandle<xAOD::ElectronContainer, float>> dec_el_plit_output;
 
  133           dec_el_plit_output.emplace_back(wdhk, ctx);
 
  137             if (!
predictElec(*elec, *tracks, *caloclusters, dec_el_plit_output, ctx)) {
 
  138                 ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to predict electron");
 
  139                 return StatusCode::FAILURE;
 
  145         std::vector<SG::WriteDecorHandle<xAOD::MuonContainer, float>> dec_mu_plit_output;
 
  147           dec_mu_plit_output.emplace_back(wdhk, ctx);
 
  152                 ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to predict muon");
 
  153                 return StatusCode::FAILURE;
 
  158     return StatusCode::SUCCESS;
 
  178     return StatusCode::SUCCESS;
 
  185     const EventContext& ctx)
 const {
 
  201     std::map<std::string, FlavorTagInference::Inputs> gnn_input;
 
  204     float muon_pt = 
muon.pt();
 
  205     float muon_eta = 
muon.eta();
 
  206     float muon_phi = 
muon.phi();
 
  208     float muon_ptvarcone30TTVARel = acc_ptvarcone30TTVA(
muon) / muon_pt;
 
  209     float muon_topoetcone30Rel = acc_topoetcone30(
muon) / muon_pt;
 
  211     float muon_caloClusterERel = -99;
 
  214       float energyloss = 0;
 
  215       if (!
muon.parameter(energyloss,xAOD::Muon::EnergyLoss)) {
 
  216         ATH_MSG_WARNING(
"DecoratePLIT::execute - failed to retrieve energy loss");
 
  217         return StatusCode::FAILURE;
 
  219       float calE = cluster->
calE();
 
  223       if (std::abs(energyloss) != 0)
 
  224         muon_caloClusterERel = calE / energyloss;
 
  228     std::vector<float> muon_feat = {
 
  232       muon_ptvarcone30TTVARel, 
 
  233       muon_topoetcone30Rel,
 
  234       muon_caloClusterERel};
 
  235     std::vector<int64_t> muon_feat_dim = {1, 
static_cast<int64_t
>(muon_feat.size())};
 
  239     gnn_input.insert({
"jet_features", muon_info});
 
  243     std::vector<const xAOD::IParticle *> 
parts;
 
  246       ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to fill particles");
 
  247       return StatusCode::FAILURE;
 
  251     std::vector<float> track_feat;
 
  252     track_feat.reserve(
parts.size() * 
static_cast<int64_t
>(muon_feat.size())); 
 
  259       float deta_lepton = 
track->p4().Eta() - 
muon.eta();
 
  261       float dphi_lepton = 
track->p4().DeltaPhi(
muon.p4());
 
  263       float qoverp = 
track->qOverP();
 
  273       float d0_significance = -99;  
 
  276       float z0SinTheta_significance = -99;
 
  281         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfPixelHits");
 
  282         return StatusCode::FAILURE;
 
  287         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfInnermostPixelLayerHits");
 
  288         return StatusCode::FAILURE;
 
  291       uint8_t pix_nextinnermosthits = 0;
 
  293         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfNextToInnermostPixelLayerHits");
 
  294         return StatusCode::FAILURE;
 
  297       uint8_t pix_innermostsharedhits = 0;
 
  299         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfInnermostPixelLayerSharedHits");
 
  300         return StatusCode::FAILURE;
 
  303       uint8_t pix_innermostsplithits = 0;
 
  305         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfInnermostPixelLayerSplitHits");
 
  306         return StatusCode::FAILURE;
 
  311         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfPixelSharedHits");
 
  312         return StatusCode::FAILURE;
 
  317         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfPixelSplitHits");
 
  318         return StatusCode::FAILURE;
 
  323         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfSCTHits");
 
  324         return StatusCode::FAILURE;
 
  329         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfSCTSharedHits");
 
  330         return StatusCode::FAILURE;
 
  333       char muon_track = acc_muon_track(*
track);
 
  335       track_feat.push_back(deta_lepton);
 
  336       track_feat.push_back(dphi_lepton);
 
  337       track_feat.push_back(qoverp);
 
  338       track_feat.push_back(
d0);
 
  342       track_feat.push_back(d0_significance);
 
  343       track_feat.push_back(z0SinTheta_significance);
 
  344       track_feat.push_back(pix_hits);
 
  345       track_feat.push_back(pix_innermosthits);
 
  346       track_feat.push_back(pix_nextinnermosthits);
 
  347       track_feat.push_back(pix_innermostsharedhits);
 
  348       track_feat.push_back(pix_innermostsplithits);
 
  349       track_feat.push_back(pix_shared);
 
  350       track_feat.push_back(pix_split);
 
  351       track_feat.push_back(sct_hits);
 
  352       track_feat.push_back(sct_shared);
 
  353       track_feat.push_back(muon_track);
 
  357     int num_cnsts = 
parts.size();
 
  361     gnn_input.insert({
"track_features", track_info});
 
  365       for (
auto& inp : gnn_input){
 
  367         for (
auto & 
dim: inp.second.second) {
 
  371         for (
auto & con: inp.second.first) {
 
  379     auto [out_f, out_vc, out_vf] = 
m_saltModel->runInference(gnn_input);
 
  384       for (
auto& singlefloat : out_f){
 
  388       for (
auto& vecchar : out_vc){
 
  390         for (
auto& 
cc : vecchar.second){
 
  395       for (
auto& vecfloat : out_vf){
 
  397         for (
auto& 
ff : vecfloat.second){
 
  403     auto it_dec_mu_plit_output = dec_mu_plit_output.begin();
 
  404     for (
auto& singlefloat : out_f){
 
  406       (*it_dec_mu_plit_output)(
muon) = singlefloat.second;
 
  407       ++it_dec_mu_plit_output;
 
  410     return StatusCode::SUCCESS;
 
  418     const EventContext& ctx)
 const {
 
  421     std::map<std::string, FlavorTagInference::Inputs> gnn_input;
 
  440     float elec_ptvarcone30Rel = acc_ptvarcone30(
electron) / elec_pt;
 
  441     float elec_topoetcone30Rel = acc_topoetcone30(
electron) / elec_pt;
 
  444     float elec_caloClusterSumEtRel = 0.0;
 
  445     float sumCoreEt_large = 0.0;
 
  447       float elec_calEta = 
electron.caloCluster()->eta(); 
 
  448       float elec_calPhi = 
electron.caloCluster()->phi();
 
  451         float deta = elec_calEta - cluster->eta();
 
  453         float dr   = std::sqrt(deta*deta + dphi*dphi);
 
  456           sumCoreEt_large += cluster->pt();
 
  460     elec_caloClusterSumEtRel = sumCoreEt_large / elec_pt;  
 
  465     if (bestmatchedGSFElTrack) {
 
  478     std::vector<float> electron_feat = {
 
  483       elec_topoetcone30Rel, 
 
  484       elec_caloClusterSumEtRel};
 
  485     std::vector<int64_t> electron_feat_dim = {1, 
static_cast<int64_t
>(electron_feat.size())};
 
  489     gnn_input.insert({
"jet_features", electron_info});
 
  492     std::vector<const xAOD::IParticle *> 
parts;
 
  494       ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to fill particles");
 
  495       return StatusCode::FAILURE;
 
  499     std::vector<float> track_feat;
 
  500     track_feat.reserve(
parts.size() * 
static_cast<int64_t
>(electron_feat.size())); 
 
  516       float qoverp = 
track->qOverP();
 
  523       float d0_significance = -99;
 
  527       float z0SinTheta_significance = -99;
 
  532         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfInnermostPixelLayerHits");
 
  533         return StatusCode::FAILURE;
 
  536       uint8_t pix_nextinnermosthits = 0;
 
  538         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfNextToInnermostPixelLayerHits");
 
  539         return StatusCode::FAILURE;
 
  542       uint8_t pix_innermostsharedhits = 0;
 
  544         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfInnermostPixelLayerSharedHits");
 
  545         return StatusCode::FAILURE;
 
  548       uint8_t pix_innermostsplithits = 0;
 
  550         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfInnermostPixelLayerSplitHits");
 
  551         return StatusCode::FAILURE;
 
  556         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfPixelHits");
 
  557         return StatusCode::FAILURE;
 
  562         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfPixelSharedHits");
 
  563         return StatusCode::FAILURE;
 
  568         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfPixelSplitHits");
 
  569         return StatusCode::FAILURE;
 
  574         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfSCTHits");
 
  575         return StatusCode::FAILURE;
 
  580         ATH_MSG_ERROR(
"DecoratePLIT::execute - failed to retrieve xAOD::numberOfSCTSharedHits");
 
  581         return StatusCode::FAILURE;
 
  584       char electron_track = acc_electron_track(*
track);
 
  588       track_feat.push_back(deta_lepton);
 
  589       track_feat.push_back(dphi_lepton);
 
  590       track_feat.push_back(qoverp);
 
  591       track_feat.push_back(
d0);
 
  593       track_feat.push_back(d0_significance);
 
  594       track_feat.push_back(z0SinTheta_significance);
 
  595       track_feat.push_back(pix_innermosthits);
 
  596       track_feat.push_back(pix_nextinnermosthits);    
 
  597       track_feat.push_back(pix_innermostsharedhits);
 
  598       track_feat.push_back(pix_innermostsplithits);
 
  599       track_feat.push_back(pix_hits);
 
  600       track_feat.push_back(pix_shared);
 
  601       track_feat.push_back(pix_split);
 
  602       track_feat.push_back(sct_hits);
 
  603       track_feat.push_back(sct_shared);
 
  604       track_feat.push_back(electron_track);
 
  608     int num_cnsts = 
parts.size();
 
  612     gnn_input.insert({
"track_features", track_info});
 
  616       for (
auto& inp : gnn_input){
 
  618         for (
auto & 
dim: inp.second.second) {
 
  622         for (
auto & con: inp.second.first) {
 
  631     auto [out_f, out_vc, out_vf] = (std::abs(elec_eta) < 1.37) ? 
m_saltModel->runInference(gnn_input) : 
m_saltModel_endcap->runInference(gnn_input);
 
  636       for (
auto& singlefloat : out_f){
 
  640       for (
auto& vecchar : out_vc){
 
  642         for (
auto& 
cc : vecchar.second){
 
  647       for (
auto& vecfloat : out_vf){
 
  649         for (
auto& 
ff : vecfloat.second){
 
  655     auto it_dec_el_plit_output = dec_el_plit_output.begin();
 
  656     for (
auto& singlefloat : out_f){
 
  658       (*it_dec_el_plit_output)(
electron) = singlefloat.second;
 
  659       ++it_dec_el_plit_output;
 
  662     return StatusCode::SUCCESS;
 
  668     constexpr 
float pt_minimum = 500; 
 
  669     constexpr 
float abs_eta_maximum = 2.5;
 
  670     constexpr 
float d0_maximum = 3.5;
 
  671     constexpr 
float z0_maximum= 5.0;
 
  672     constexpr 
unsigned char si_hits_minimum = 8;
 
  673     constexpr 
unsigned char si_shared_maximum = 1;
 
  674     constexpr 
unsigned char si_holes_maximum = 2;
 
  675     constexpr 
unsigned char pix_holes_maximum = 1;
 
  684       ATH_MSG_ERROR(
"DecoratePLIT::passed_r22tracking_cuts - failed to retrieve xAOD::numberOfPixelSharedHits");
 
  689       ATH_MSG_ERROR(
"DecoratePLIT::passed_r22tracking_cuts - failed to retrieve xAOD::numberOfSCTSharedHits");
 
  694       ATH_MSG_ERROR(
"DecoratePLIT::passed_r22tracking_cuts - failed to retrieve xAOD::numberOfPixelHits");
 
  699       ATH_MSG_ERROR(
"DecoratePLIT::passed_r22tracking_cuts - failed to retrieve xAOD::numberOfSCTHits");
 
  704       ATH_MSG_ERROR(
"DecoratePLIT::passed_r22tracking_cuts - failed to retrieve xAOD::numberOfPixelDeadSensors");
 
  709       ATH_MSG_ERROR(
"DecoratePLIT::passed_r22tracking_cuts - failed to retrieve xAOD::numberOfSCTDeadSensors");
 
  714       ATH_MSG_ERROR(
"DecoratePLIT::passed_r22tracking_cuts - failed to retrieve xAOD::numberOfPixelHoles");
 
  719       ATH_MSG_ERROR(
"DecoratePLIT::passed_r22tracking_cuts - failed to retrieve xAOD::numberOfSCTHoles");
 
  723     if (std::abs(
tp.eta()) > abs_eta_maximum)
 
  725     double n_module_shared = (pix_shared + sct_shared / 2);
 
  726     if (n_module_shared > si_shared_maximum)
 
  728     if (
tp.pt() <= pt_minimum)
 
  730     if (std::isfinite(d0_maximum) &&
 
  731         std::abs(acc_d0(
tp)) >= d0_maximum)
 
  733     if (std::isfinite(z0_maximum) &&
 
  734         std::abs(acc_z0SinTheta(
tp)) >= z0_maximum)
 
  736     if (pix_hits + pix_dead + sct_hits + sct_dead < si_hits_minimum)
 
  738     if ((pix_holes + sct_holes) > si_holes_maximum)
 
  740     if (pix_holes > pix_holes_maximum)
 
  746       std::vector<const xAOD::IParticle *> &
parts,
 
  750       const EventContext& ctx)
 const 
  756     std::set<const xAOD::TrackParticle*> tracksUsedForElectron;
 
  757     std::set<const xAOD::TrackParticle*> tracksUsedForMuon;
 
  758     if (
const auto* elec = 
dynamic_cast<const xAOD::Electron*
>(&lepton)) {
 
  760     } 
else if (
const auto* 
muon = 
dynamic_cast<const xAOD::Muon*
>(&lepton)) {
 
  762             tracksUsedForMuon.insert(*(
muon->inDetTrackParticleLink())); 
 
  769         ATH_MSG_ERROR(
"DecoratePLIT::fillParticles - null track pointer");
 
  776       float dr_lepton = (lepton.
p4().Pt() > 0.) ? 
track->p4().DeltaR(lepton.
p4()) : -99;
 
  781       bool isUsedForElectron = tracksUsedForElectron.count(
track);
 
  782       bool isUsedForMuon = tracksUsedForMuon.count(
track);
 
  785         ATH_MSG_ERROR(
"DecoratePLIT::fillParticles - failed to decorate track");
 
  786         return StatusCode::FAILURE;
 
  794       return a->p4().DeltaR(lepton_p4) < 
b->p4().DeltaR(lepton_p4);
 
  796     std::sort(
parts.begin(), 
parts.end(), SORT_TRACKLEP);
 
  798     return StatusCode::SUCCESS;
 
  804       bool isUsedForElectron,
 
  813       float dr_leptontrack = -99;
 
  815           if (trackLep->
pt() > 0.) {
 
  816               dr_leptontrack = 
track.p4().DeltaR(trackLep->
p4());
 
  821       return StatusCode::SUCCESS;