diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkEGamma/python/EGammaCommon.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkEGamma/python/EGammaCommon.py
index 711fa4faa8a6ba2be1e7d88f0bd24ed1b92676ba..cf21e8eff73426c1496bbd404daabd01d3d95561 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkEGamma/python/EGammaCommon.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkEGamma/python/EGammaCommon.py
@@ -91,13 +91,13 @@ ToolSvc += ElectronLHSelectorLooseBL
 #
 # Disabled as is missing in R22
 #
-'''
+
 from ElectronPhotonSelectorTools.ElectronPhotonSelectorToolsConf import AsgElectronChargeIDSelectorTool
 ElectronChargeIDSelector = AsgElectronChargeIDSelectorTool("ElectronChargeIDSelectorLoose")
 ElectronChargeIDSelector.primaryVertexContainer = "PrimaryVertices"
 ElectronChargeIDSelector.TrainingFile = "ElectronPhotonSelectorTools/ChargeID/ECIDS_20180731rel21Summer2018.root"
 ToolSvc += ElectronChargeIDSelector
-'''
+
 
 #====================================================================
 # FWD ELECTRON LH SELECTORS
@@ -240,7 +240,7 @@ print(ElectronPassLHTight)
 #
 # Disabled as is missing in R22
 #
-'''
+
 # decorate electrons with the output of ECIDS ----------------------------------------------------------------------
 ElectronPassECIDS = DerivationFramework__EGElectronLikelihoodToolWrapper( name = "ElectronPassECIDS",
                                                                           EGammaElectronLikelihoodTool = ElectronChargeIDSelector,
@@ -251,7 +251,7 @@ ElectronPassECIDS = DerivationFramework__EGElectronLikelihoodToolWrapper( name =
                                                                           StoreTResult = True)
 ToolSvc += ElectronPassECIDS
 print (ElectronPassECIDS)
-
+'''
 # decorate forward electrons with the output of LH loose
 ForwardElectronPassLHLoose = DerivationFramework__EGSelectionToolWrapper( name = "ForwardElectronPassLHLoose",
                                                                           EGammaSelectionTool = ForwardElectronLHSelectorLoose,
@@ -366,13 +366,13 @@ ElectronAmbiguity = DF_EGEAT(name               = "ElectronAdditionnalAmbiguity"
 ToolSvc += ElectronAmbiguity
 
 #
-# Commented ForwardElectronPassLHLoose, ForwardElectronPassLHMedium, ForwardElectronPassLHTight, ElectronPassECIDS tools due to they are not available in R22 yet
+# Commented ForwardElectronPassLHLoose, ForwardElectronPassLHMedium, ForwardElectronPassLHTight, tools due to they are not available in R22 yet
 #
 # list of all the decorators so far
 EGAugmentationTools = [DFCommonPhotonsDirection,
                        ElectronPassLHVeryLoose, ElectronPassLHLoose, ElectronPassLHLooseBL, ElectronPassLHMedium, ElectronPassLHTight,
                        #ForwardElectronPassLHLoose, ForwardElectronPassLHMedium, ForwardElectronPassLHTight,
-                       #ElectronPassECIDS,
+                       ElectronPassECIDS,
                        PhotonPassIsEMLoose, PhotonPassIsEMTight, 
                        PhotonPassIsEMTightPtIncl, 
                        PhotonPassCleaning,
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkEGamma/src/EGElectronLikelihoodToolWrapper.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkEGamma/src/EGElectronLikelihoodToolWrapper.cxx
index 32afa26be9d8ef46af346ee2f6be700febe3bdfe..c72ee01732b4e9311775a049f4f6fe9f626d42bf 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkEGamma/src/EGElectronLikelihoodToolWrapper.cxx
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkEGamma/src/EGElectronLikelihoodToolWrapper.cxx
@@ -120,10 +120,9 @@ namespace DerivationFramework {
       unsigned int isEM = (unsigned int) theAccept.getCutResultInvertedBitSet().to_ulong(); // this should work for both the cut-based and the LH selectors
       double result(0.); // initialise explicitly to avoid compilation warning. It will be overridden in the following block (result is used only if m_storeTResult is true)
 
-      // Lukas Heinrich: interface in master not yet available.
-      //      if (m_storeTResult) {
-      //	result = double(m_tool->calculate(pCopy));
-      //      }
+      if (m_storeTResult) {
+      	result = double(m_tool->calculate(Gaudi::Hive::currentContext(),pCopy));
+      }
       
       // decorate the original object
       if(m_cut.empty()){
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/CMakeLists.txt b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/CMakeLists.txt
index 9d050bda770e934f98de5ab3624f2a0b963aed51..b5b19c5195c508c1e2bd95f04b99b8dabea4c1cd 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/CMakeLists.txt
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/CMakeLists.txt
@@ -11,7 +11,7 @@ atlas_add_library( ElectronPhotonSelectorToolsLib
   ElectronPhotonSelectorTools/*.h Root/*.cxx
   PUBLIC_HEADERS ElectronPhotonSelectorTools
   PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-  LINK_LIBRARIES EgammaAnalysisInterfacesLib AsgTools xAODEgamma  xAODTracking
+  LINK_LIBRARIES EgammaAnalysisInterfacesLib AsgTools xAODEgamma  xAODTracking MVAUtils
   xAODHIEvent PATCoreAcceptLib AsgDataHandlesLib
   PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} AsgMessagingLib FourMomUtils xAODCaloEvent
   xAODEventInfo PathResolver )
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..f63f32b9b51488bb43a7bdc89e9ed74f86df59c0
--- /dev/null
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h
@@ -0,0 +1,154 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Dear emacs, this is -*-c++-*-
+#ifndef __ASGELECTRONCHARGEIDSELECTORTOOL__
+#define __ASGELECTRONCHARGEIDSELECTORTOOL__
+
+
+// Atlas includes
+#include "AsgTools/AsgTool.h"
+#include "MVAUtils/BDT.h"
+#include "EgammaAnalysisInterfaces/IAsgElectronLikelihoodTool.h"
+#include "ElectronPhotonSelectorTools/AsgElectronLikelihoodTool.h"
+#include "PATCore/AcceptData.h"
+#include "AsgDataHandles/ReadHandleKey.h"
+#include <unordered_map>
+
+class AsgElectronChargeIDSelectorTool : public asg::AsgTool, 
+					virtual public IAsgElectronLikelihoodTool
+{
+  ASG_TOOL_CLASS2(AsgElectronChargeIDSelectorTool, IAsgElectronLikelihoodTool, IAsgSelectionTool)
+
+public:
+  /** Standard constructor */
+  AsgElectronChargeIDSelectorTool( const std::string& myname);
+
+
+  /** Standard destructor */
+  virtual ~AsgElectronChargeIDSelectorTool();
+public:
+  /** Gaudi Service Interface method implementations */ // /** Gaudi Service Interface method implementations */
+  virtual StatusCode initialize() override;             //   virtual StatusCode finalize();
+
+  // Main methods for IAsgSelectorTool interface
+
+  /** Method to get the plain AcceptInfo.
+      This is needed so that one can already get the AcceptInfo 
+      and query what cuts are defined before the first object 
+      is passed to the tool. */
+  //virtual const asg::AcceptInfo& getAcceptInfo() const override; KM: inlined blow
+
+  /** The main accept method: using the generic interface */
+  asg::AcceptData accept( const xAOD::IParticle* part ) const override;
+  asg::AcceptData accept( const EventContext& ctx, const xAOD::IParticle* part ) const override;
+
+  /** The main accept method: the actual cuts are applied here */
+  asg::AcceptData accept( const xAOD::Electron* eg ) const {
+    return accept (eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
+  }
+  asg::AcceptData accept( const EventContext& ctx, const xAOD::Electron* eg ) const override {
+    return accept (ctx, eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
+  }
+
+  /** The main accept method: the actual cuts are applied here */
+  asg::AcceptData accept( const xAOD::Egamma* eg ) const {
+    return accept (eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
+  }
+  asg::AcceptData accept(const EventContext& ctx, const xAOD::Egamma* eg ) const override{
+    return accept (ctx, eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
+  }
+
+  /** The main accept method: in case mu not in EventInfo online */
+  asg::AcceptData accept( const xAOD::Electron* eg, double mu ) const;
+  asg::AcceptData accept( const EventContext& ctx, const xAOD::Electron* eg, double mu ) const override;
+
+  /** The main accept method: in case mu not in EventInfo online */
+  asg::AcceptData accept( const xAOD::Egamma* eg, double mu ) const;
+  asg::AcceptData accept( const EventContext& ctx, const xAOD::Egamma* eg, double mu ) const override;
+  
+  // Main methods for IAsgCalculatorTool interface
+ public:
+  /** The main result method: the actual likelihood is calculated here */
+  double calculate( const xAOD::IParticle* part ) const;
+  double calculate( const EventContext& ctx, const xAOD::IParticle* part ) const override;
+
+  /** The main result method: the actual likelihood is calculated here */
+  double calculate( const xAOD::Electron* eg ) const {
+    return calculate (eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
+  }
+  double calculate( const EventContext& ctx, const xAOD::Electron* eg ) const override {
+    return calculate (ctx, eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
+  }
+
+  /** The main result method: the actual likelihood is calculated here */
+  double calculate( const xAOD::Egamma* eg ) const {
+    return calculate (eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
+  }
+  double calculate( const EventContext &ctx, const xAOD::Egamma* eg ) const override {
+    return calculate (ctx, eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
+  }
+
+  /** The main result method: the actual likelihood is calculated here */
+  double calculate( const xAOD::Electron* eg, double mu ) const;
+  double calculate( const EventContext &ctx, const xAOD::Electron* eg, double mu ) const override;
+
+  /** The main result method: the actual likelihood is calculated here */
+  double calculate( const xAOD::Egamma* eg, double mu ) const; 
+  double calculate( const EventContext &ctx, const xAOD::Egamma* eg, double mu ) const override; 
+
+  //=========================================================================================== same until here
+  inline virtual std::string getOperatingPointName( ) const override
+  { return m_WorkingPoint; };
+
+  inline virtual const asg::AcceptInfo& getAcceptInfo() const override
+  { return m_acceptInfo; };          
+
+  asg::AcceptData accept() const { return asg::AcceptData(&m_acceptInfo); }
+  
+
+  // Private methods
+private:
+  /// Get the number of primary vertices
+  unsigned int getNPrimVertices(const EventContext& ctx) const;
+
+  //BDT instances for different ID operating points (Tight, Medium, Loose) and the vector corresponds to n-fold
+  std::vector<MVAUtils::BDT*> m_v_bdts;
+
+  TString m_pid_name;
+  float m_cutOnBDT;
+
+  int m_cutPosition_bdt;
+  asg::AcceptInfo m_acceptInfo;
+ 
+  // Private member variables
+private: 
+  /** Working Point */
+  std::string m_WorkingPoint;
+
+  /// Whether to use the PV (not available for trigger)
+  bool m_usePVCont;
+
+  /// defualt nPV (when not using PVCont)
+  unsigned int m_nPVdefault;
+
+  /// The primary vertex container name
+  SG::ReadHandleKey<xAOD::VertexContainer> m_primVtxContKey {
+    this, "primaryVertexContainer", "PrimaryVertices",
+    "The primary vertex container name"};
+
+  /// The input ROOT file name that holds the PDFs
+  std::string m_trainingFile;
+
+  // BDT input variables
+  std::vector<std::string> m_inputVars;
+
+}; // End: class definition
+
+
+
+
+
+#endif
+
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/ElectronPhotonSelectorToolsPythonDict.h b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/ElectronPhotonSelectorToolsPythonDict.h
index 54ac5d791c014c9ebc10760615c1c8a8448dd19a..5ec5d03a65b5526d1e3e6a994e7962b5bee4d3c0 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/ElectronPhotonSelectorToolsPythonDict.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/ElectronPhotonSelectorToolsPythonDict.h
@@ -10,6 +10,7 @@
 #include "ElectronPhotonSelectorTools/AsgPhotonIsEMSelector.h"
 #include "ElectronPhotonSelectorTools/AsgForwardElectronIsEMSelector.h"
 #include "ElectronPhotonSelectorTools/AsgElectronLikelihoodTool.h"
+#include "ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h"
 #include "ElectronPhotonSelectorTools/EGammaAmbiguityTool.h"
 #include "ElectronPhotonSelectorTools/AsgDeadHVCellRemovalTool.h"
 #endif
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/AsgElectronChargeIDSelectorTool.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/AsgElectronChargeIDSelectorTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..20f547235a3ba4d1434098270b9701a46f518d23
--- /dev/null
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/AsgElectronChargeIDSelectorTool.cxx
@@ -0,0 +1,504 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+   @class AsgElectronChargeIDSelectorTool
+   @brief Electron selector tool to select objects in Asgena using an underlying pure ROOT tool.
+ 
+   @author Karsten Koeneke
+   @date   October 2012
+   09-APR-2014, convert to ASGTool (Jovan Mitrevski)
+   22-AUG-2016, copied from AsgElectronLikelihoodTool (Kazuya Mochizuki) 
+*/
+
+// Include this class's header
+#include "ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h"
+
+
+
+
+// STL includes
+#include <string>
+#include <cstdint>
+#include <cmath>
+
+//EDM includes
+#include "xAODEgamma/Electron.h"
+#include "xAODTracking/Vertex.h"
+#include "xAODTracking/VertexContainer.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "xAODEventInfo/EventInfo.h"
+#include "TROOT.h"
+#include "TKey.h"
+#include "TClass.h"
+#include "TEnv.h"
+#include "TFile.h"
+#include "TObjString.h"
+#include "TObjArray.h"
+
+#include "AsgDataHandles/ReadHandle.h"
+#include "AsgTools/CurrentContext.h"
+#include "PathResolver/PathResolver.h"
+
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+AsgElectronChargeIDSelectorTool::AsgElectronChargeIDSelectorTool(const std::string& myname) :
+  AsgTool(myname) //,m_cutOnBDT(0)//,m_configFile("")//,m_rootTool(0)
+{
+  // Declare the needed properties
+  declareProperty("WorkingPoint",m_WorkingPoint="","The Working Point");
+  //declareProperty("ConfigFile",m_configFile="","The config file to use");
+  declareProperty("usePVContainer", m_usePVCont=true, "Whether to use the PV container");
+  declareProperty("nPVdefault", m_nPVdefault = 0, "The default number of PVs if not counted");
+  //declareProperty("primaryVertexContainer", m_primVtxContKey="PrimaryVertices", "The primary vertex container name" );
+    
+  declareProperty("TrainingFile",  m_trainingFile="", "The input ROOT file name holding training" );
+  declareProperty("CutOnBDT",m_cutOnBDT=0,"Cut on BDT discriminant");
+  m_pid_name=myname.data();
+}
+
+
+//=============================================================================
+// Standard destructor
+//=============================================================================
+AsgElectronChargeIDSelectorTool::~AsgElectronChargeIDSelectorTool()
+{
+  for (auto bdt: m_v_bdts) if (bdt) delete bdt;
+}
+
+
+//=============================================================================
+// Asgena initialize method
+//=============================================================================
+StatusCode AsgElectronChargeIDSelectorTool::initialize()
+{
+  m_pid_name.ToLower(); //KM: List of 97% OPs with different PIDs below
+  std::string op_name="loose";
+  bool op_isUserSpecified=false;
+  if (m_cutOnBDT==0) {  //when cutOnBDT is unmodified, adjust it to the 97% OP in each PID menu
+    if      (m_pid_name.Contains("tight") ) op_name="tight" , m_cutOnBDT=-0.109249;//Tight  (with data): -0.109249
+    else if (m_pid_name.Contains("medium")) op_name="medium", m_cutOnBDT=-0.257081;//Medium (with data): -0.257081
+    else                                                      m_cutOnBDT=-0.337671;//Loose  (with data): -0.337671
+  }
+  else op_isUserSpecified=true;
+  m_pid_name="loose";//Now only one training is provided, using loose PID but OP varies for differnt PID
+    
+  std::string display= op_isUserSpecified ? "user specified":"97% signal-eff";
+  ATH_MSG_INFO("OP to use: " << op_name <<", with cut on BDT: "<<m_cutOnBDT<<", which corresponds to "<<display<<" working point.");
+    
+  std::string TrainingFile;
+  if (!m_trainingFile.empty()) {  //If the property was set by the user, take that.
+        
+    TrainingFile= PathResolverFindCalibFile( m_trainingFile );
+    if(TrainingFile==""){//Error if it cant find the conf
+      ATH_MSG_ERROR("Could not locate " << m_trainingFile );
+      return StatusCode::FAILURE;
+    }
+    else ATH_MSG_INFO("trainingfile loaded from: " << TrainingFile );
+
+  }
+  else {
+    ATH_MSG_ERROR("Could not find configuration file: \""<< m_trainingFile<<"\"");
+    return StatusCode::FAILURE;
+  }
+    
+  unsigned nfold=1;
+  TFile* bdtfile = TFile::Open(TrainingFile.data());
+  if (!bdtfile) {
+    ATH_MSG_ERROR("Input file found to be empty!! "<< TrainingFile);
+    return StatusCode::FAILURE;
+  }
+  else {
+    TIter next(bdtfile->GetListOfKeys());
+    TKey *key;
+    while ((key = (TKey*)next())) {
+      TClass *clas = gROOT->GetClass(key->GetClassName());
+      if (!clas->InheritsFrom("TDirectoryFile")) continue;
+      TDirectory *td = (TDirectoryFile*)key->ReadObj();
+      std::string dirName =td->GetName();
+      if (dirName.find(m_pid_name)!=std::string::npos) {
+        std::string foldconf=dirName.substr(dirName.rfind("_")+1,-1);
+        // std::string f_index=foldconf.substr(0,foldconf.find("o"));
+        std::string s_nfold=foldconf.substr(foldconf.find("o")+1,-1);
+        nfold=atoi(s_nfold.data());
+        break;
+      }
+    }
+  }
+    
+  ATH_MSG_INFO("ECIDS nfold configuration: "<<nfold);
+    
+  TObjArray* toa= (TObjArray*) bdtfile->Get("/ECIDS_"+m_pid_name+TString::Format("_0o%d",nfold)+"/variables");
+  std::string commaSepVars="";
+  if (toa) {
+    TObjString *tos= 0;
+    if (toa->GetEntries()>0) tos= (TObjString*) toa->At(0);
+    commaSepVars=tos->GetString().Data();
+    ATH_MSG_INFO("Variables for ECIDS= "<<commaSepVars);
+  }
+  else ATH_MSG_FATAL("Cannot access the list of input variables @"<<bdtfile->GetName()<<":/ECIDS_"+m_pid_name+TString::Format("_0o%d",nfold)+"/variables");
+    
+  //prepare m_inputVars
+  m_inputVars.clear();
+  while (commaSepVars.find(",")!=std::string::npos) {
+    m_inputVars.push_back(commaSepVars.substr(0,commaSepVars.find(",")));
+    commaSepVars.erase(0,commaSepVars.find(",")+1);
+  }
+  m_inputVars.push_back(commaSepVars.substr(0,-1));//push back the last element
+
+  for (unsigned i_fold=0; i_fold<nfold; i_fold++) {
+    TString treename="/ECIDS_"+m_pid_name+TString::Format("_%do%d",i_fold,nfold)+"/BDT";
+    //std::cout<<"Trying to access a ttree with name: "<<treename<<std::endl;
+    TTree* tree = (TTree*)bdtfile->Get(treename);
+    m_v_bdts.push_back(new MVAUtils::BDT(tree));
+  }
+    
+  ///-----------End of text config----------------------------
+
+  // Setup primary vertex key handle
+  ATH_CHECK( m_primVtxContKey.initialize(m_usePVCont) );
+    
+  m_cutPosition_bdt = m_acceptInfo.addCut( "bdt", "pass bdt" );
+    
+  return StatusCode::SUCCESS ;
+}
+
+//=============================================================================
+// The main accept method: the actual cuts are applied here
+//=============================================================================
+asg::AcceptData AsgElectronChargeIDSelectorTool::accept(const xAOD::Electron* el, double mu ) const
+{
+  //Backwards compatibility
+  return accept(Gaudi::Hive::currentContext(), el, mu );
+}
+asg::AcceptData AsgElectronChargeIDSelectorTool::accept(const EventContext& ctx,  const xAOD::Electron* eg, double mu ) const
+{
+    
+  double bdt=calculate(ctx,eg,mu);
+
+  ATH_MSG_VERBOSE("\t accept( ctx, el, mu ), bdt="<<bdt);
+
+  asg::AcceptData acceptBDT(&m_acceptInfo);
+  acceptBDT.clear();
+
+  acceptBDT.setCutResult(m_cutPosition_bdt,bdt>m_cutOnBDT);
+   
+  return acceptBDT;
+}
+
+//=============================================================================
+// Accept method for EFCaloLH in the trigger; do full LH if !CaloCutsOnly
+//=============================================================================
+asg::AcceptData AsgElectronChargeIDSelectorTool::accept(const xAOD::Egamma* eg, double mu ) const
+{
+  //Backwards compatibility
+  return accept(Gaudi::Hive::currentContext(), eg, mu );
+}
+asg::AcceptData AsgElectronChargeIDSelectorTool::accept(const EventContext& ctx,  const xAOD::Egamma* eg, double mu) const
+{
+  double bdt=calculate(ctx,eg,mu);
+    
+  ATH_MSG_VERBOSE("\t accept( ctx, eg, mu ), bdt="<<bdt);
+
+  asg::AcceptData acceptBDT(&m_acceptInfo);    
+  acceptBDT.clear();
+    
+  acceptBDT.setCutResult(m_cutPosition_bdt,bdt>m_cutOnBDT);
+    
+  return acceptBDT;
+}
+
+//=============================================================================
+// The main result method: the actual likelihood is calculated here
+//=============================================================================
+double AsgElectronChargeIDSelectorTool::calculate( const EventContext& ctx, const xAOD::Electron* eg, double mu ) const
+{
+    
+  ATH_MSG_VERBOSE("\t AsgElectronChargeIDSelectorTool::calculate( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
+    
+  if ( !eg ) {
+    ATH_MSG_ERROR ("Failed, no egamma object.");
+    return -1;
+  }
+    
+  const xAOD::CaloCluster* cluster = eg->caloCluster();
+  if ( !cluster ) {
+    ATH_MSG_ERROR ("Failed, no cluster.");
+    return -1;
+  }
+    
+  const double energy =  cluster->e();
+  const float eta = cluster->etaBE(2);
+  if ( fabs(eta) > 300.0 ) {
+    ATH_MSG_ERROR ("Failed, eta range.");
+    return -1;
+  }
+    
+  double et = 0.;// transverse energy of the electron (using the track eta)
+  if (eg->trackParticle() )
+    et     = ( cosh(eg->trackParticle()->eta()) != 0.) ? energy/cosh(eg->trackParticle()->eta()) : 0.;
+  else et  = ( cosh(eta) != 0.) ? energy/cosh(eta) : 0.;
+    
+    
+  // number of track hits and other track quantities
+  uint8_t nSCT(0);
+  float trackqoverp(0.0);
+  float trackqoverpsig(0.0);
+  int   charge(0.0);
+  int   lifeSign(0.0);
+  float trackchi2(0.0);
+  float avgCharge_SCTw(0.0);
+  float d0(0.0);
+  float z0(0.0);
+  float phi0(0.0);
+  float theta(0.0);
+  float EoverP(0.0);
+  float d0sigma(0.0);
+  double dpOverp(0.0);
+  float TRT_PID(0.0);
+  //double trans_TRT_PID(0.0);
+  float deltaPhi1=0, deltaPhi2=0;
+  float deltaPhiFromLM=0;
+  float deltaPhiRescaled2=0;//deltaEta=0,
+  //double rTRT(0.0);
+    
+  TVector2 el_cluster; el_cluster.SetMagPhi(cluster->energyBE(2)/cosh(eta),cluster->phiBE(2));
+    
+  bool allFound = true;
+  // retrieve associated TrackParticle
+  const xAOD::TrackParticle* t = eg->trackParticle();
+  if (t) {
+    trackqoverp = t->qOverP();
+    charge= t->charge();
+    d0 = t->d0();
+
+    if(std::find(m_inputVars.begin(),m_inputVars.end(), "z0sinTheta" )!= m_inputVars.end()) {
+      z0 = t->z0();
+      theta = t->theta();
+    }
+
+    if(std::find(m_inputVars.begin(),m_inputVars.end(), "chi2oftrackfit" )!= m_inputVars.end())
+      trackchi2 = t->chiSquared();
+        
+    phi0 = t->phi() + (d0>=0? M_PI/2 : -M_PI/2);
+    TVector2 d0_direction;    d0_direction.SetMagPhi(fabs(d0),phi0);
+    float inner_product = el_cluster.X()*d0_direction.X() + el_cluster.Y()*d0_direction.Y();
+    lifeSign = inner_product>=0? 1 : -1;
+        
+    EoverP   = energy * fabs(t->qOverP());
+    if(std::find(m_inputVars.begin(),m_inputVars.end(), "d0Err" )!= m_inputVars.end() or
+       std::find(m_inputVars.begin(),m_inputVars.end(), "d0Sig" )!= m_inputVars.end()) {
+      float vard0 = t->definingParametersCovMatrix()(0,0);
+      if (vard0 > 0) {
+        d0sigma=sqrtf(vard0);
+      }
+    }
+        
+    //KM: calculation of SCT-weighted charge
+    float charge = 0, SCT = 0;
+    for (unsigned TPit = 0; TPit < eg->nTrackParticles(); TPit++) {
+      uint8_t temp_NSCTHits;
+      if(eg->trackParticle(TPit)) {
+	eg->trackParticle(TPit)->summaryValue(temp_NSCTHits, xAOD::numberOfSCTHits);
+	
+	SCT += temp_NSCTHits;
+	charge += temp_NSCTHits*eg->trackParticle(TPit)->charge();
+      }
+      else ATH_MSG_WARNING("This electron has no track particle associated!!! Assigning #SCT-hits= 0!!! " );
+    }
+    avgCharge_SCTw= SCT!=0 ? eg->charge()*charge/SCT : 0;
+        
+    const std::vector<float>&cov= t->definingParametersCovMatrixVec();
+    trackqoverpsig= cov[14];
+        
+    if(std::find(m_inputVars.begin(),m_inputVars.end(), "nSctHits" )!= m_inputVars.end() )
+      allFound = allFound && t->summaryValue(nSCT, xAOD::numberOfSCTHits);
+        
+    //Transform the TRT PID output for use in the LH tool.
+    double fEpsilon = 1.0e-30;  // to avoid zero division
+    double pid_tmp = TRT_PID;
+    if (pid_tmp >= 1.0) pid_tmp = 1.0 - 1.0e-15;  //this number comes from TMVA
+    else if (pid_tmp <= fEpsilon) pid_tmp = fEpsilon;
+        
+    if(std::find(m_inputVars.begin(),m_inputVars.end(), "deltaPoverP" )!= m_inputVars.end() ) {
+      unsigned int index;
+      if( t->indexOfParameterAtPosition(index, xAOD::LastMeasurement) ) {
+                
+        double refittedTrack_LMqoverp  =
+          t->charge() / sqrt(std::pow(t->parameterPX(index), 2) +
+                             std::pow(t->parameterPY(index), 2) +
+                             std::pow(t->parameterPZ(index), 2));
+                
+        dpOverp = 1 - trackqoverp/(refittedTrack_LMqoverp);
+      }
+    }
+        
+  }
+  else {
+    allFound=false;
+    ATH_MSG_WARNING ( "Failed, no track particle: et= " << et << "eta= " << eta );
+  }
+    
+  float Rphi(0);//float Reta(0), Rphi(0),  Rhad1(0), Rhad(0), ws3(0), w2(0), f1(0), Eratio(0), f3(0);
+  allFound = allFound && eg->showerShapeValue(Rphi, xAOD::EgammaParameters::Rphi);// rphi e233/e237
+  // allFound = allFound && eg->trackCaloMatchValue(deltaEta, xAOD::EgammaParameters::deltaEta1);
+    
+  // difference between the cluster phi (sampling 2) and the eta of the track extrapolated from the last measurement point.
+  allFound = allFound && eg->trackCaloMatchValue(deltaPhiRescaled2, xAOD::EgammaParameters::deltaPhiRescaled2);
+    
+  //if(m_map_inputs.find("deltaphi1"              )!= m_map_inputs.end())
+  if(std::find(m_inputVars.begin(),m_inputVars.end(), "deltaphi1" )!= m_inputVars.end() )
+    allFound = allFound && eg->trackCaloMatchValue(deltaPhi1, xAOD::EgammaParameters::deltaPhi1);
+  // if(m_map_inputs.find("deltaphi2"              )!= m_map_inputs.end() or
+  //    m_map_inputs.find("deltaDeltaPhiFirstAndLM")!= m_map_inputs.end())
+  if(std::find(m_inputVars.begin(),m_inputVars.end(), "deltaphi2"              )!= m_inputVars.end() or
+     std::find(m_inputVars.begin(),m_inputVars.end(), "deltaDeltaPhiFirstAndLM")!= m_inputVars.end() )
+    allFound = allFound && eg->trackCaloMatchValue(deltaPhi2, xAOD::EgammaParameters::deltaPhi2);
+  //if(m_map_inputs.find("deltaDeltaPhiFirstAndLM")!= m_map_inputs.end())
+  if(std::find(m_inputVars.begin(),m_inputVars.end(), "deltaDeltaPhiFirstAndLM" )!= m_inputVars.end() )
+    allFound = allFound && eg->trackCaloMatchValue(deltaPhiFromLM, xAOD::EgammaParameters::deltaPhiFromLastMeasurement);
+    
+  // Get the number of primary vertices in this event
+  // double ip = static_cast<double>(m_nPVdefault);
+  // if(mu < 0) // use npv if mu is negative (not given)
+  //   ip = static_cast<double>(m_usePVCont ? this->getNPrimVertices() : m_nPVdefault);
+  // else ip = mu;
+    
+  if (!allFound) ATH_MSG_FATAL("Missing input variable for ECIDS BDT calculation");
+    
+  const xAOD::EventInfo* eventInfo = nullptr;
+  if (evtStore()->retrieve(eventInfo,"EventInfo").isFailure()) ATH_MSG_WARNING ( " Cannot access to event info " );
+  // lumiBlock = eventInfo->lumiBlock(), runNumber = eventInfo->runNumber(), eventNumber=eventInfo->eventNumber();
+  //ATH_MSG_DEBUG("event_num%bdt_size="<<eventInfo->eventNumber()<<"%"<<unsigned(m_v_bdts.size())<<"= "<<eventInfo->eventNumber()%unsigned(m_v_bdts.size()));
+  unsigned bdt_index=eventInfo->eventNumber()%unsigned(m_v_bdts.size());
+    
+  std::vector<float> v_inputs;
+  for (auto var: m_inputVars) {
+    if (var == "pt"                     ) v_inputs.push_back(et                	     );
+    if (var == "eta"                    ) v_inputs.push_back(eta               	     );
+    if (var == "abs_eta"                ) v_inputs.push_back(fabs(eta)         	     );
+    if (var == "avgCharge_SCTw"         ) v_inputs.push_back(avgCharge_SCTw    	     );
+    if (var == "d0"                     ) v_inputs.push_back(d0                	     );
+    if (var == "ld0"                    ) v_inputs.push_back(lifeSign*d0       	     );
+    if (var == "cd0"                    ) v_inputs.push_back(charge*d0         	     );
+    if (var == "EoverP"                 ) v_inputs.push_back(EoverP            	     );
+    if (var == "deltaphi1"              ) v_inputs.push_back(deltaPhi1         	     );
+    if (var == "deltaphiRes"            ) v_inputs.push_back(deltaPhiRescaled2 	     );
+    if (var == "Rphi"                   ) v_inputs.push_back(Rphi              	     );
+    if (var == "qoverpSig"              ) v_inputs.push_back(trackqoverpsig    	     );
+    if (var == "nSctHits"               ) v_inputs.push_back(nSCT              	     );
+    if (var == "z0sinTheta"             ) v_inputs.push_back(z0*sin(theta)     	     );
+    if (var == "d0Err"                  ) v_inputs.push_back(d0sigma           	     );
+    if (var == "d0Sig"                  ) v_inputs.push_back(d0/d0sigma        	     );
+    if (var == "deltaphi2"              ) v_inputs.push_back(deltaPhi2         	     );
+    if (var == "chi2oftrackfit"         ) v_inputs.push_back(trackchi2         	     );
+    if (var == "deltaPoverP"            ) v_inputs.push_back(dpOverp           	     );
+    if (var == "deltaDeltaPhiFirstAndLM") v_inputs.push_back(deltaPhi2-deltaPhiFromLM);
+  }
+
+  ATH_MSG_VERBOSE("\t\t event# "                                   <<eventInfo->eventNumber()                                                                                                                         <<std::endl<<
+		  "xAOD variables: pt                           = "<< et                       <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"pt"                     )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: eta                     = "<< eta                      <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"eta"                    )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: abs_eta                 = "<< fabs(eta)                <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"abs_eta"                )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: avgCharge_SCTw          = "<< avgCharge_SCTw           <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"avgCharge_SCTw"         )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: d0                      = "<< d0                       <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"d0"                     )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: ld0                     = "<< lifeSign*d0              <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"ld0"                    )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: cd0                     = "<< charge*d0                <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"cd0"                    )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: EoverP                  = "<< EoverP                   <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"EoverP"                 )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: deltaphi1               = "<< deltaPhi1                <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"deltaphi1"              )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: deltaphiRes             = "<< deltaPhiRescaled2        <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"deltaphiRes"            )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: Rphi                    = "<< Rphi                     <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"Rphi"                   )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: qoverpSig               = "<< trackqoverpsig           <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"qoverpSig"              )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: nSctHits                = "<< unsigned(nSCT)           <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"nSctHits"               )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: z0sinTheta              = "<< z0*sin(theta)            <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"z0sinTheta"             )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: d0Err                   = "<< d0sigma                  <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"d0Err"                  )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: d0Sig                   = "<< d0/d0sigma               <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"d0Sig"                  )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: deltaphi2               = "<< deltaPhi2                <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"deltaphi2"              )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: chi2oftrackfit          = "<< trackchi2                <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"chi2oftrackfit"         )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: deltaPoverP             = "<< dpOverp                  <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"deltaPoverP"            )!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: deltaDeltaPhiFirstandLM = "<< deltaPhi2-deltaPhiFromLM <<",\t isRequested= "<<(std::find(m_inputVars.begin(),m_inputVars.end(),"deltaDeltaPhiFirstAndLM")!=m_inputVars.end() )<<std::endl<<
+                  "\t\t xAOD variables: AllFound                = "<<allFound            );
+  
+  ////KM: dumping variables, only variables used by BDT
+  // std::cout<<"\t\t event# "<<eventInfo->eventNumber()<<std::endl;
+  // unsigned i=0;
+  // for (auto inputVar: m_inputVars) {
+  //   std::cout<<"\t kmdebug: "<<inputVar<<"\t = "<<v_inputs[i]<<std::endl; i++;
+  // }
+  
+  //double bdt_output = m_v_bdts.at(bdt_index)->GetGradBoostMVA(m_v_bdts.at(bdt_index)->GetPointers());
+  double bdt_output = m_v_bdts.at(bdt_index)->GetGradBoostMVA(v_inputs);
+  ATH_MSG_DEBUG("ECIDS-BDT= "<<bdt_output);
+  //std::cout<<"\t kmdebug: \t ECIDS-BDT= "<<bdt_output<<std::endl;
+
+  return bdt_output;
+}
+
+//=============================================================================
+// Calculate method for EFCaloLH in the trigger; do full LH if !CaloCutsOnly
+//=============================================================================
+double AsgElectronChargeIDSelectorTool::calculate( const xAOD::Egamma* eg, double mu ) const
+{
+  //Backward compatibility
+  return calculate(Gaudi::Hive::currentContext(), eg, mu);
+}
+
+double AsgElectronChargeIDSelectorTool::calculate( const EventContext& ctx, const xAOD::Egamma* eg, double mu ) const
+{
+  ATH_MSG_VERBOSE("AsgElectronChargeIDSelectorTool::calculate( &ctx ="<<(&ctx)<<", *eg "<<eg<<", mu= "<<mu<< " )");
+  ATH_MSG_WARNING("Method not implemented for egamma object! Reurning -1!!");
+    
+  return -9;
+}
+
+//=============================================================================
+asg::AcceptData AsgElectronChargeIDSelectorTool::accept(const xAOD::IParticle* part) const
+{
+  //Backward compatibility
+  return accept(Gaudi::Hive::currentContext(), part);
+}
+asg::AcceptData AsgElectronChargeIDSelectorTool::accept(const EventContext& ctx, const xAOD::IParticle* part) const
+{
+  if(part->type() == xAOD::Type::Electron){
+    const xAOD::Electron* el = static_cast<const xAOD::Electron*>(part);
+    return accept(ctx, el);
+  }
+  
+  ATH_MSG_ERROR("Input is not an electron");
+  return asg::AcceptData(&m_acceptInfo);
+}
+
+double AsgElectronChargeIDSelectorTool::calculate(const xAOD::IParticle* part) const
+{
+  //Backward compatibility
+  return calculate(Gaudi::Hive::currentContext(), part);
+}
+
+double AsgElectronChargeIDSelectorTool::calculate(const EventContext& ctx, const xAOD::IParticle* part) const
+{
+  if(part->type() == xAOD::Type::Electron){
+    const xAOD::Electron* el = static_cast<const xAOD::Electron*>(part);
+    return calculate(ctx, el);
+  }
+  
+  ATH_MSG_ERROR ( "Input is not an electron!!" );
+  return -19;
+}
+
+//=============================================================================
+// Helper method to get the number of primary vertices
+// We don't want to iterate over all vertices in the event for each electron!!! 
+//=============================================================================
+unsigned int AsgElectronChargeIDSelectorTool::getNPrimVertices(const EventContext& ctx) const
+{
+  unsigned int nVtx(0);
+  SG::ReadHandle<xAOD::VertexContainer> vtxCont (m_primVtxContKey, ctx); 
+  for ( unsigned int i = 0; i < vtxCont->size(); i++ ) {
+      const xAOD::Vertex* vxcand = vtxCont->at(i);
+      if ( vxcand->nTrackParticles() >= 2 ) nVtx++;
+  }
+  return nVtx;
+}
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/src/components/ElectronPhotonSelectorTools_entries.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/src/components/ElectronPhotonSelectorTools_entries.cxx
index 1cfb85d02dd6965e132c50c633575d024deb5b49..d87fb21cf0e65b877f087a3cab5e75b30920205f 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/src/components/ElectronPhotonSelectorTools_entries.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/src/components/ElectronPhotonSelectorTools_entries.cxx
@@ -3,6 +3,7 @@
 #include "ElectronPhotonSelectorTools/AsgPhotonIsEMSelector.h"
 #include "ElectronPhotonSelectorTools/AsgForwardElectronIsEMSelector.h"
 #include "ElectronPhotonSelectorTools/EGammaAmbiguityTool.h"
+#include "ElectronPhotonSelectorTools/AsgElectronChargeIDSelectorTool.h"
 #include "ElectronPhotonSelectorTools/AsgDeadHVCellRemovalTool.h"
 
 DECLARE_COMPONENT( AsgElectronIsEMSelector )
@@ -10,5 +11,6 @@ DECLARE_COMPONENT( AsgElectronLikelihoodTool )
 DECLARE_COMPONENT( AsgPhotonIsEMSelector )
 DECLARE_COMPONENT( AsgForwardElectronIsEMSelector )
 DECLARE_COMPONENT( EGammaAmbiguityTool )
+DECLARE_COMPONENT( AsgElectronChargeIDSelectorTool )
 DECLARE_COMPONENT( AsgDeadHVCellRemovalTool )