Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BTV] PUPPI ValueMap-compatible Deep taggers info producers #40803

Merged
57 changes: 41 additions & 16 deletions PhysicsTools/PatAlgos/python/tools/jetTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,16 @@ def setupSVClustering(btagInfo, svClustering, algo, rParam, fatJets=cms.InputTag
if groomedFatJets != cms.InputTag(''):
btagInfo.groomedFatJets = groomedFatJets

def setupPackedPuppi(process):
task = getPatAlgosToolsTask(process)
packedPuppiName = "packedpuppi"
if not hasattr(process,packedPuppiName):
from CommonTools.PileupAlgos.Puppi_cff import puppi
addToProcessAndTask(packedPuppiName, puppi.clone(
useExistingWeights = True,
candName = 'packedPFCandidates',
vertexName = 'offlineSlimmedPrimaryVertices') , process, task)
return packedPuppiName

def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSource, elSource, muSource, runIVF, tightBTagNTkHits, loadStdRecoBTag, svClustering, fatJets, groomedFatJets,
algo, rParam, btagDiscriminators, btagInfos, patJets, labelName, btagPrefix, postfix):
Expand Down Expand Up @@ -604,16 +614,13 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou
btag.pixelClusterTagInfos.clone(jets = jetSource, vertices=pvSource),
process, task)



if 'pfBoostedDouble' in btagInfo or 'SecondaryVertex' in btagInfo:
_btagInfo = getattr(process, btagPrefix+btagInfo+labelName+postfix)
if pfCandidates.value() == 'packedPFCandidates':
_btagInfo.weights = cms.InputTag("packedpuppi")
if not hasattr(process,"packedpuppi"):
from CommonTools.PileupAlgos.Puppi_cff import puppi
addToProcessAndTask('packedpuppi', puppi.clone(
useExistingWeights = True,
candName = 'packedPFCandidates',
vertexName = 'offlineSlimmedPrimaryVertices') , process, task)
packedPuppiName = setupPackedPuppi(process)
_btagInfo.weights = cms.InputTag(packedPuppiName)
else:
_btagInfo.weights = cms.InputTag("puppi")

Expand All @@ -626,14 +633,20 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou
else:
deep_csv_tag_infos = 'pfDeepCSVTagInfos'
flip = False

# use right input tags when running with RECO PF candidates, which actually
# depens of wether jets were slimmed or not (check for s/S-limmed in name)
if not ('limmed' in jetSource.value()):
puppi_value_map = cms.InputTag("puppi")
vertex_associator = cms.InputTag("primaryVertexAssociation","original")
# depens of wether jets use "particleFlow"
if pfCandidates.value() == 'packedPFCandidates':
puppi_value_map = setupPackedPuppi(process)
vertex_associator = cms.InputTag("")
else:
puppi_value_map = cms.InputTag("")
vertex_associator = cms.InputTag("")
puppi_value_map = cms.InputTag("puppi")
vertex_associator = cms.InputTag("primaryVertexAssociation","original")

# If this jet is a puppi jet, then set is_weighted_jet to true.
is_weighted_jet = False
if ('puppi' in jetSource.value().lower()):
is_weighted_jet = True
addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
btag.pfDeepFlavourTagInfos.clone(
jets = jetSource,
Expand All @@ -642,29 +655,36 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou
shallow_tag_infos = cms.InputTag(btagPrefix+deep_csv_tag_infos+labelName+postfix),
puppi_value_map = puppi_value_map,
vertex_associator = vertex_associator,
is_weighted_jet = is_weighted_jet,
flip = flip),
process, task)

if btagInfo == 'pfDeepDoubleXTagInfos':
# can only run on PAT jets, so the updater needs to be used
if 'updated' not in jetSource.value().lower():
raise ValueError("Invalid jet collection: %s. pfDeepDoubleXTagInfos only supports running via updateJetCollection." % jetSource.value())
packedPuppiName = setupPackedPuppi(process)
puppi_value_map = cms.InputTag(packedPuppiName)
addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
btag.pfDeepDoubleXTagInfos.clone(
jets = jetSource,
vertices=pvSource,
secondary_vertices=svSource,
shallow_tag_infos = cms.InputTag(btagPrefix+'pfBoostedDoubleSVAK8TagInfos'+labelName+postfix),
puppi_value_map = puppi_value_map,
),
process, task)

if btagInfo == 'pfHiggsInteractionNetTagInfos':
packedPuppiName = setupPackedPuppi(process)
puppi_value_map = cms.InputTag(packedPuppiName)
addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
btag.pfHiggsInteractionNetTagInfos.clone(
jets = jetSource,
vertices = pvSource,
secondary_vertices = svSource,
pf_candidates = pfCandidates,
puppi_value_map = puppi_value_map
),
process, task)

Expand All @@ -673,7 +693,7 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou
# case 1: running over jets whose daughters are PackedCandidates (only via updateJetCollection for now)
if 'updated' not in jetSource.value().lower():
raise ValueError("Invalid jet collection: %s. pfDeepBoostedJetTagInfos only supports running via updateJetCollection." % jetSource.value())
puppi_value_map = ""
puppi_value_map = setupPackedPuppi(process)
vertex_associator = ""
elif pfCandidates.value() == 'particleFlow':
raise ValueError("Running pfDeepBoostedJetTagInfos with reco::PFCandidates is currently not supported.")
Expand All @@ -698,7 +718,7 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou
if btagInfo == 'pfParticleNetTagInfos':
if pfCandidates.value() == 'packedPFCandidates':
# case 1: running over jets whose daughters are PackedCandidates (only via updateJetCollection for now)
puppi_value_map = ""
puppi_value_map = setupPackedPuppi(process)
vertex_associator = ""
elif pfCandidates.value() == 'particleFlow':
raise ValueError("Running pfDeepBoostedJetTagInfos with reco::PFCandidates is currently not supported.")
Expand Down Expand Up @@ -730,7 +750,7 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou
sip3dSigMax = -1
if pfCandidates.value() == 'packedPFCandidates':
# case 1: running over jets whose daughters are PackedCandidates (only via updateJetCollection for now)
puppi_value_map = ""
puppi_value_map = setupPackedPuppi(process)
vertex_associator = ""
elif pfCandidates.value() == 'particleFlow':
raise ValueError("Running pfDeepBoostedJetTagInfos with reco::PFCandidates is currently not supported.")
Expand All @@ -739,6 +759,10 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou
vertex_associator = "primaryVertexAssociation:original"
else:
raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value())
# If this jet is a Puppi jet, use puppi-weighted p4.
use_puppiP4 = False
if "puppi" in jetSource.value().lower():
use_puppiP4 = True
addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix,
btag.pfParticleNetAK4TagInfos.clone(
jets = jetSource,
Expand All @@ -749,6 +773,7 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou
vertex_associator = vertex_associator,
flip_ip_sign = flip_ip_sign,
sip3dSigMax = sip3dSigMax,
use_puppiP4 = use_puppiP4
),
process, task)

Expand Down
17 changes: 14 additions & 3 deletions RecoBTag/FeatureTools/interface/ChargedCandidateConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ namespace btagbtvdeep {
void commonCandidateToFeatures(const CandidateType* c_pf,
const reco::Jet& jet,
const TrackInfoBuilder& track_info,
const bool& isWeightedJet,
const float& drminpfcandsv,
const float& jetR,
const float& puppiw,
ChargedCandidateFeatures& c_pf_features,
const bool flip = false) {
float trackSip2dVal = track_info.getTrackSip2dVal();
Expand All @@ -31,9 +33,15 @@ namespace btagbtvdeep {
}

c_pf_features.deltaR = reco::deltaR(*c_pf, jet);
c_pf_features.ptrel = catch_infs_and_bound(c_pf->pt() / jet.pt(), 0, -1, 0, -1);
c_pf_features.ptrel_noclip = c_pf->pt() / jet.pt();
c_pf_features.erel = c_pf->energy() / jet.energy();

float constituentWeight = 1.;
if (isWeightedJet)
constituentWeight = puppiw;

c_pf_features.ptrel = catch_infs_and_bound((c_pf->pt() * constituentWeight) / jet.pt(), 0, -1, 0, -1);
c_pf_features.ptrel_noclip = (c_pf->pt() * constituentWeight) / jet.pt();
c_pf_features.erel = (c_pf->energy() * constituentWeight) / jet.energy();

const float etasign = jet.eta() > 0 ? 1 : -1;
c_pf_features.etarel = etasign * (c_pf->eta() - jet.eta());

Expand All @@ -59,14 +67,17 @@ namespace btagbtvdeep {
void packedCandidateToFeatures(const pat::PackedCandidate* c_pf,
const pat::Jet& jet,
const TrackInfoBuilder& track_info,
const bool isWeightedJet,
const float drminpfcandsv,
const float jetR,
const float puppiw,
ChargedCandidateFeatures& c_pf_features,
const bool flip = false);

void recoCandidateToFeatures(const reco::PFCandidate* c_pf,
const reco::Jet& jet,
const TrackInfoBuilder& track_info,
const bool isWeightedJet,
const float drminpfcandsv,
const float jetR,
const float puppiw,
Expand Down
17 changes: 14 additions & 3 deletions RecoBTag/FeatureTools/interface/NeutralCandidateConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ namespace btagbtvdeep {

void packedCandidateToFeatures(const pat::PackedCandidate* n_pf,
const pat::Jet& jet,
const bool isWeightedJet,
const float drminpfcandsv,
const float jetR,
const float puppiw,
NeutralCandidateFeatures& n_pf_features);

void recoCandidateToFeatures(const reco::PFCandidate* n_pf,
const reco::Jet& jet,
const bool isWeightedJet,
const float drminpfcandsv,
const float jetR,
const float puppiw,
Expand All @@ -27,19 +30,27 @@ namespace btagbtvdeep {
template <typename CandidateType>
static void commonCandidateToFeatures(const CandidateType* n_pf,
const reco::Jet& jet,
const bool& isWeightedJet,
const float& drminpfcandsv,
const float& jetR,
const float& puppiw,
NeutralCandidateFeatures& n_pf_features) {
std::pair<float, float> drSubjetFeatures = getDRSubjetFeatures(jet, n_pf);
n_pf_features.drsubjet1 = drSubjetFeatures.first;
n_pf_features.drsubjet2 = drSubjetFeatures.second;

float constituentWeight = 1.;
if (isWeightedJet)
constituentWeight = puppiw;

// Jet relative vars
n_pf_features.ptrel = catch_infs_and_bound(n_pf->pt() / jet.pt(), 0, -1, 0, -1);
n_pf_features.ptrel_noclip = n_pf->pt() / jet.pt();
n_pf_features.ptrel = catch_infs_and_bound((n_pf->pt() * constituentWeight) / jet.pt(), 0, -1, 0, -1);
n_pf_features.ptrel_noclip = (n_pf->pt() * constituentWeight) / jet.pt();
n_pf_features.erel = (n_pf->energy() * constituentWeight) / jet.energy();

n_pf_features.deltaR = catch_infs_and_bound(reco::deltaR(*n_pf, jet), 0, -0.6, 0, -0.6);
n_pf_features.deltaR_noclip = reco::deltaR(*n_pf, jet);
n_pf_features.erel = n_pf->energy() / jet.energy();

n_pf_features.isGamma = 0;
if (std::abs(n_pf->pdgId()) == 22)
n_pf_features.isGamma = 1;
Expand Down
17 changes: 13 additions & 4 deletions RecoBTag/FeatureTools/plugins/DeepBoostedJetTagInfoProducer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ DeepBoostedJetTagInfoProducer::DeepBoostedJetTagInfoProducer(const edm::Paramete
if (!puppi_value_map_tag.label().empty()) {
puppi_value_map_token_ = consumes<edm::ValueMap<float>>(puppi_value_map_tag);
use_puppi_value_map_ = true;
} else if (use_puppiP4_) {
throw edm::Exception(edm::errors::Configuration,
"puppi_value_map is not set but use_puppiP4 is set to True. Must also set puppi_value_map.");
}

const auto &pvas_tag = iConfig.getParameter<edm::InputTag>("vertex_associator");
Expand Down Expand Up @@ -323,10 +326,16 @@ void DeepBoostedJetTagInfoProducer::produce(edm::Event &iEvent, const edm::Event
float DeepBoostedJetTagInfoProducer::puppiWgt(const reco::CandidatePtr &cand) {
const auto *pack_cand = dynamic_cast<const pat::PackedCandidate *>(&(*cand));
const auto *reco_cand = dynamic_cast<const reco::PFCandidate *>(&(*cand));
float wgt = 1.;
if (pack_cand)
wgt = pack_cand->puppiWeight();
else if (reco_cand) {

//
// Access puppi weight from ValueMap.
//
float wgt = 1.; // Set to fallback value

if (pack_cand) {
if (use_puppi_value_map_)
wgt = (*puppi_value_map_)[cand];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that accessing the PUPPI weight from the candidate is not supported anymore? Or can you add a

else
    wgt = pack_cand->puppiWeight();

here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I'd like to ask @hqucms and @nurfikri89 for their feedback, what we already discussed before the PR was submitted is the following, which indeed sounds like accessing the PUPPI weight from the candidate is not supported anymore. The full answer was:

Actually, this is not the case anymore but it was for Run-2 releases. In order to be in sync with RECO/AOD level, starting from the Run-3 CMSSW releases (as early as CMSSW_12 I think), 
puppi jet reclustering with MiniAOD input requires to provide packedPFCandidates and the puppi weight ValueMap (produced by the PuppiProducer) to FastJetProducer instead of just the 
new PackedCandidates (produced by the PuppiProducer).

So every time one wants use puppi weights (even if they are the default stored weights in MiniAODs), one has to setup PuppiProducer and then pass the ValueMap to any producers 
that will read in puppi weights. In the case of using the default stored weights, the PuppiProducer has the flag "useExistingWeight" which will enable the PuppiProducer to copy 
the existing weights in MiniAOD into the ValueMap.

[...] this is now the standard practice of reclustering puppi jet with MiniAODs [...]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks for confirming that

} else if (reco_cand) {
if (use_puppi_value_map_)
wgt = (*puppi_value_map_)[cand];
} else
Expand Down
Loading