Example #1
0
    def effective_area(self, area_cone_size, area_table):
        '''Return effective area for this lepton. 
        area_cone_size: should be e.g. '03' or '04'.
        area_table: defines the table of effective areas. 
        It can either be a string EffectiveArea+area_cone_size, e.g. EffectiveArea03, 
        or have be a dict like: 
        
         { '03' : 
              [ (1.000, 0.13),
              (1.479, 0.14),
              (2.000, 0.07),
              (2.200, 0.09),
              (2.300, 0.11),
              (2.400, 0.11),
              (2.500, 0.14) ],
           '04' : 
              [ (1.000, 0.208),
              (1.479, 0.209),
              (2.000, 0.115),
              (2.200, 0.143),
              (2.300, 0.183),
              (2.400, 0.194),
              (2.500, 0.261) ],
           'eta' : lambda x: x.superCluster().eta()
         }
        
        Please see PhysicsTools/Heppy/python/physicsutils/EffectiveAreas.py for 
        more information.

        If a string is provided, the corresponding attribute must be added to the 
        Lepton object beforehand: lepton.EffectiveArea03 = <the_area_table>, 
        or to its class: Electron.EffectiveArea03 = <the_area_table>. 
        '''
        if area_table and not is_ea_table(area_table):
            raise ValueError('area_table is not an area table')
        if area_table is None:
            # area table not provided by the user as argument to the isolation method.
            # try to find it in the object or its class
            ea_attr_name = ''.join(['EffectiveArea', area_cone_size])
            area_table = getattr(self, ea_attr_name, None)
            if area_table is None:
                area_table = getattr(self.__class__, ea_attr_name, None)
                if area_table is None:
                    raise ValueError(
                        ea_attr_name +
                        ' not found. It should be added to the lepton object as an attribute or a class attribute.'
                    )
        return effective_area(self, area_cone_size, area_table)
Example #2
0
    def passed(self, ele, rho, wp):
        '''return true if the electron passes the cut based ID working point.
        see https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedElectronIdentificationRun2#Offline_selection_criteria_for_V
        
        ele: a reco::GsfElectron
        rho: energy density in the event
        wp: working point to test

        example: 
        
            event.getByLabel(('slimmedElectrons'),                 ele_handle)
            event.getByLabel(('fixedGridRhoFastjetAll'),           rho_handle)
            
            electrons = ele_handle.product()
            rho       = rho_handle.product()

            is_veto = passed(electron[0], rho,'cutBasedElectronID-Fall17-94X-V2-veto')
        '''
        if ele.isEB():
            WP = self.working_points[wp][0]
        else:
            WP = self.working_points[wp][1]
        isoInputs = self.working_points[wp][2]

        full5x5_sigmaIetaIeta = ele.full5x5_sigmaIetaIeta()

        dEtaInSeed = sys.float_info.max
        if ele.superCluster().isNonnull() and ele.superCluster().seed(
        ).isNonnull():
            dEtaInSeed = ele.deltaEtaSuperClusterTrackAtVtx(
            ) - ele.superCluster().eta() + ele.superCluster().seed().eta()

        dPhiIn = ele.deltaPhiSuperClusterTrackAtVtx()

        h_over_e = ele.hadronicOverEm()
        h_over_e_cut = WP.hOverECut_C0 + WP.hOverECut_CE / ele.superCluster(
        ).energy() + WP.hOverECut_Cr * rho / ele.superCluster().energy()

        pfIso = ele.pfIsolationVariables()
        chad = pfIso.sumChargedHadronPt
        nhad = pfIso.sumNeutralHadronEt
        pho = pfIso.sumPhotonEt
        area_key = [key for key in areas.keys() if key in WP.idName][0]
        ea_table = effective_area_table(ele, area_key)
        eA = effective_area(ele, '03', ea_table)
        iso = chad + max([0.0, nhad + pho - rho * eA])
        relIsoWithEA = iso / ele.pt()
        relIsoWithEA_cut = WP.relCombIsolationWithEACut_C0 + WP.relCombIsolationWithEACut_Cpt / ele.pt(
        )

        ecal_energy_inverse = 1.0 / ele.ecalEnergy()
        eSCoverP = ele.eSuperClusterOverP()
        absEInverseMinusPInverse = abs(1.0 - eSCoverP) * ecal_energy_inverse

        missingHits = ele.gsfTrack().hitPattern().numberOfLostHits(
            ROOT.reco.HitPattern.MISSING_INNER_HITS)

        if full5x5_sigmaIetaIeta < WP.full5x5_sigmaIEtaIEtaCut and \
                abs(dEtaInSeed) < WP.dEtaInSeedCut and \
                abs(dPhiIn) < WP.dPhiInCut and \
                h_over_e < h_over_e_cut and \
                relIsoWithEA < relIsoWithEA_cut and \
                absEInverseMinusPInverse < WP.absEInverseMinusPInverseCut and \
                missingHits <= WP.missingHitsCut and \
                ele.passConversionVeto() :
            return True
        return False