text: #include "PhysicsTools/SelectorUtils/interface/CutApplicatorBase.h"
  #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
  #include "RecoEgamma/EgammaTools/interface/EBEECutValues.h"
  
  class GsfEleHadronicOverEMLinearCut : public CutApplicatorBase {
  public:
    GsfEleHadronicOverEMLinearCut(const edm::ParameterSet& params)
        : CutApplicatorBase(params),
          slopeTerm_(params, "slopeTerm"),
          slopeStart_(params, "slopeStart"),
          constTerm_(params, "constTerm") {}
  
    result_type operator()(const reco::GsfElectronPtr&) const final;
  
    double value(const reco::CandidatePtr& cand) const final;
  
    CandidateType candidateType() const final { return ELECTRON; }
  
  private:
    EBEECutValues slopeTerm_;
    EBEECutValues slopeStart_;
    EBEECutValues constTerm_;
  };
  
  DEFINE_EDM_PLUGIN(CutApplicatorFactory, GsfEleHadronicOverEMLinearCut, "GsfEleHadronicOverEMLinearCut");
  
  CutApplicatorBase::result_type GsfEleHadronicOverEMLinearCut::operator()(const reco::GsfElectronPtr& cand) const {
    const float energy = cand->superCluster()->energy();
    const float cutValue = energy > slopeStart_(cand) ? slopeTerm_(cand) * (energy - slopeStart_(cand)) + constTerm_(cand)
                                                      : constTerm_(cand);
  
    return cand->hadronicOverEm() * energy < cutValue;
  }
  
  double GsfEleHadronicOverEMLinearCut::value(const reco::CandidatePtr& cand) const {
    reco::GsfElectronPtr ele(cand);
    const float energy = ele->superCluster()->energy();
    return ele->hadronicOverEm() * energy;
  }
  