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 OfflineDQM preparations for Run 3 #35985

Merged
merged 24 commits into from Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion Configuration/StandardSequences/python/Harvesting_cff.py
Expand Up @@ -9,6 +9,7 @@
from Validation.RecoHI.HarvestingHI_cff import *
from Validation.RecoJets.JetPostProcessor_cff import *
from Validation.RecoMET.METPostProcessor_cff import *
from DQMOffline.RecoB.bTagMiniDQM_cff import *


dqmHarvesting = cms.Path(DQMOffline_SecondStep*DQMOffline_Certification)
Expand Down Expand Up @@ -66,5 +67,5 @@
alcaHarvesting = cms.Path()
#alcaHarvesting = cms.Sequence()

validationHarvestingMiniAOD = cms.Path(JetPostProcessor*METPostProcessorHarvesting*postValidationMiniAOD)
validationHarvestingMiniAOD = cms.Path(JetPostProcessor*METPostProcessorHarvesting*bTagMiniValidationHarvesting*postValidationMiniAOD)
#validationHarvestingMiniAOD = cms.Sequence(JetPostProcessor*METPostProcessorHarvesting*postValidationMiniAOD)
3 changes: 2 additions & 1 deletion Configuration/StandardSequences/python/Validation_cff.py
Expand Up @@ -31,6 +31,7 @@
from Validation.RecoEgamma.photonMiniAODValidationSequence_cff import *
from Validation.RecoEgamma.egammaValidationMiniAOD_cff import *
from Validation.RecoTau.RecoTauValidation_cff import *
from DQMOffline.RecoB.bTagMiniDQM_cff import *

prevalidationNoHLT = cms.Sequence( cms.SequencePlaceholder("mix") * globalPrevalidation * metPreValidSeq * jetPreValidSeq )
prevalidation = cms.Sequence( cms.SequencePlaceholder("mix") * globalPrevalidation * hltassociation * metPreValidSeq * jetPreValidSeq )
Expand Down Expand Up @@ -66,7 +67,7 @@
validationLiteTracking.replace(globalValidation,globalValidationLiteTracking)
validationLiteTracking.remove(condDataValidation)

validationMiniAOD = cms.Sequence(type0PFMEtCorrectionPFCandToVertexAssociationForValidationMiniAOD * JetValidationMiniAOD * METValidationMiniAOD * tauValidationSequenceMiniAOD)
validationMiniAOD = cms.Sequence(type0PFMEtCorrectionPFCandToVertexAssociationForValidationMiniAOD * JetValidationMiniAOD * METValidationMiniAOD * tauValidationSequenceMiniAOD * bTagMiniValidationSource)

prevalidation_preprod = cms.Sequence( preprodPrevalidation )

Expand Down
3 changes: 2 additions & 1 deletion DQMOffline/Configuration/python/DQMOffline_SecondStep_cff.py
Expand Up @@ -224,7 +224,8 @@

from PhysicsTools.NanoAOD.nanoDQM_cff import *
from Validation.RecoParticleFlow.DQMForPF_MiniAOD_cff import *
from DQMOffline.RecoB.bTagMiniDQM_cff import *

DQMHarvestMiniAOD = cms.Sequence( dataCertificationJetMETSequence * muonQualityTests_miniAOD * DQMHarvestPF )
DQMHarvestMiniAOD = cms.Sequence( dataCertificationJetMETSequence * muonQualityTests_miniAOD * DQMHarvestPF * bTagMiniDQMHarvesting)
DQMHarvestNanoAOD = cms.Sequence( nanoHarvest )

3 changes: 2 additions & 1 deletion DQMOffline/Configuration/python/DQMOffline_cff.py
Expand Up @@ -245,10 +245,11 @@
from Validation.RecoParticleFlow.miniAODDQM_cff import * # On MiniAOD vs RECO
from Validation.RecoParticleFlow.DQMForPF_MiniAOD_cff import * # MiniAOD PF variables
from DQM.TrackingMonitor.tracksDQMMiniAOD_cff import *
from DQMOffline.RecoB.bTagMiniDQM_cff import *
from DQMOffline.Muon.miniAOD_cff import *
from DQM.Physics.DQMTopMiniAOD_cff import *

DQMOfflineMiniAOD = cms.Sequence(jetMETDQMOfflineRedoProductsMiniAOD*muonMonitors_miniAOD*MuonMiniAOD*DQMOfflinePF)
DQMOfflineMiniAOD = cms.Sequence(jetMETDQMOfflineRedoProductsMiniAOD*bTagMiniDQMSource*muonMonitors_miniAOD*MuonMiniAOD*DQMOfflinePF)

#Post sequences are automatically placed in the EndPath by ConfigBuilder if PAT is run.
#miniAOD DQM sequences need to access the filter results.
Expand Down
3 changes: 2 additions & 1 deletion DQMOffline/RecoB/plugins/BuildFile.xml
Expand Up @@ -6,14 +6,15 @@
<use name="DataFormats/Common"/>
<use name="DataFormats/JetReco"/>
<use name="DataFormats/VertexReco"/>
<use name="DataFormats/PatCandidates"/>
<use name="FWCore/Framework"/>
<use name="FWCore/MessageLogger"/>
<use name="FWCore/ParameterSet"/>
<use name="FWCore/ServiceRegistry"/>
<use name="FWCore/Utilities"/>
<use name="JetMETCorrections/JetCorrector"/>
<use name="SimDataFormats/GeneratorProducts"/>
<library file="BTagPerformanceAnalyzerOnData.cc PrimaryVertexMonitor.cc BTagPerformanceHarvester.cc" name="DQMOfflineRecoBPlugins">
<library file="BTagPerformanceAnalyzerOnData.cc PrimaryVertexMonitor.cc BTagPerformanceHarvester.cc MiniAODTaggerAnalyzer.cc MiniAODTaggerHarvester.cc" name="DQMOfflineRecoBPlugins">
<flags EDM_PLUGIN="1"/>
</library>

84 changes: 84 additions & 0 deletions DQMOffline/RecoB/plugins/MiniAODTaggerAnalyzer.cc
@@ -0,0 +1,84 @@
#include "DQMOffline/RecoB/plugins/MiniAODTaggerAnalyzer.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/Framework/interface/Event.h"

MiniAODTaggerAnalyzer::MiniAODTaggerAnalyzer(const edm::ParameterSet& pSet)
: jetToken_(consumes<std::vector<pat::Jet> >(pSet.getParameter<edm::InputTag>("JetTag"))),
disrParameters_(pSet.getParameter<edm::ParameterSet>("parameters")),
marco-link marked this conversation as resolved.
Show resolved Hide resolved

folder_(pSet.getParameter<std::string>("folder")),
discrNumerator_(pSet.getParameter<vstring>("numerator")),
discrDenominator_(pSet.getParameter<vstring>("denominator")),

mclevel_(pSet.getParameter<int>("MClevel")),
doCTagPlots_(pSet.getParameter<bool>("CTagPlots")),
dodifferentialPlots_(pSet.getParameter<bool>("differentialPlots")),
discrCut_(pSet.getParameter<double>("discrCut")),

etaActive_(pSet.getParameter<bool>("etaActive")),
etaMin_(pSet.getParameter<double>("etaMin")),
etaMax_(pSet.getParameter<double>("etaMax")),
ptActive_(pSet.getParameter<bool>("ptActive")),
ptMin_(pSet.getParameter<double>("ptMin")),
ptMax_(pSet.getParameter<double>("ptMax"))

{}

MiniAODTaggerAnalyzer::~MiniAODTaggerAnalyzer() {}

void MiniAODTaggerAnalyzer::bookHistograms(DQMStore::IBooker& ibook, edm::Run const& run, edm::EventSetup const& es) {
jetTagPlotter_ = std::make_unique<JetTagPlotter>(folder_,
EtaPtBin(etaActive_, etaMin_, etaMax_, ptActive_, ptMin_, ptMax_),
disrParameters_,
mclevel_,
false,
ibook,
doCTagPlots_,
dodifferentialPlots_,
discrCut_);
}

void MiniAODTaggerAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
edm::Handle<std::vector<pat::Jet> > jetCollection;
iEvent.getByToken(jetToken_, jetCollection);

const float jec = 1.; // JEC not implemented!
float numerator = 0;
marco-link marked this conversation as resolved.
Show resolved Hide resolved
float denominator = 0;

// Loop over the pat::Jets
for (std::vector<pat::Jet>::const_iterator jet = jetCollection->begin(); jet != jetCollection->end(); ++jet) {
numerator = 0;
denominator = 0;

for (const auto& discrLabel : discrNumerator_) {
numerator = numerator + jet->bDiscriminator(discrLabel);
marco-link marked this conversation as resolved.
Show resolved Hide resolved
}

for (const auto& discrLabel : discrDenominator_) {
denominator = denominator + jet->bDiscriminator(discrLabel);
}

if (discrDenominator_.empty()) {
marco-link marked this conversation as resolved.
Show resolved Hide resolved
denominator = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

I still miss why do you want to add to histograms even when the list of discriminators is empty: is this really needed?
Shouldn't you more conveniently initialize float denominator = 0; and avoid adding to histo if there are no denominators?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is used for BvsAll. In this case the denominator is the sum of all probabilities.
So instead of summing up all probabilities to numerically 1 in the loop, the denominator is set to 1.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, now I understand, thank you.
Still, wouldn't it be more intutitive if in that case the first string in discrDenominator_ is set as (e.g.) "ALL"? With empty lists one normally expects no elements insides, not "the sum of all probabilities"...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This would be intuitive but requires a check for an empty list and a comparison between strings in each event. As the denominator list cannot be empty anyways I think it's a good way to interpret empty lists as no division performed.
I'll add a comment to explain this case.

}

// only fill with valid discriminator values
if (numerator >= 0 && denominator >= 0) {
marco-link marked this conversation as resolved.
Show resolved Hide resolved
reco::Jet recoJet = *jet;
if (jetTagPlotter_->etaPtBin().inBin(recoJet, jec)) {
jetTagPlotter_->analyzeTag(recoJet, jec, numerator / denominator, jet->partonFlavour());
}
}
}

// fill JetMultiplicity
if (mclevel_ > 0) {
jetTagPlotter_->analyzeTag(1.);
} else {
jetTagPlotter_->analyzeTag();
}
}

//define this as a plug-in
DEFINE_FWK_MODULE(MiniAODTaggerAnalyzer);
50 changes: 50 additions & 0 deletions DQMOffline/RecoB/plugins/MiniAODTaggerAnalyzer.h
@@ -0,0 +1,50 @@
#ifndef MiniAODTaggerAnalyzer_H
#define MiniAODTaggerAnalyzer_H

#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "DQMServices/Core/interface/DQMEDAnalyzer.h"
#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "DataFormats/PatCandidates/interface/Jet.h"
#include "DQMOffline/RecoB/interface/JetTagPlotter.h"

/** \class MiniAODTaggerAnalyzer
*
* Tagger analyzer to run on MiniAOD
*
*/

class MiniAODTaggerAnalyzer : public DQMEDAnalyzer {
public:
explicit MiniAODTaggerAnalyzer(const edm::ParameterSet& pSet);
~MiniAODTaggerAnalyzer() override;

void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override;

private:
void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
typedef std::vector<std::string> vstring;

// using JetTagPlotter object for all the hard work ;)
std::unique_ptr<JetTagPlotter> jetTagPlotter_;

edm::EDGetTokenT<std::vector<pat::Jet> > jetToken_;
edm::ParameterSet disrParameters_;

std::string folder_;
marco-link marked this conversation as resolved.
Show resolved Hide resolved
vstring discrNumerator_;
vstring discrDenominator_;

int mclevel_;
bool doCTagPlots_;
bool dodifferentialPlots_;
double discrCut_;

bool etaActive_;
double etaMin_;
double etaMax_;
bool ptActive_;
double ptMin_;
double ptMax_;
};

#endif
40 changes: 40 additions & 0 deletions DQMOffline/RecoB/plugins/MiniAODTaggerHarvester.cc
@@ -0,0 +1,40 @@
#include "DQMOffline/RecoB/plugins/MiniAODTaggerHarvester.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/Framework/interface/Event.h"

MiniAODTaggerHarvester::MiniAODTaggerHarvester(const edm::ParameterSet& pSet)
: folder_(pSet.getParameter<std::string>("folder")),
disrParameters_(pSet.getParameter<edm::ParameterSet>("parameters")),

mclevel_(pSet.getParameter<int>("MClevel")),
doCTagPlots_(pSet.getParameter<bool>("CTagPlots")),
dodifferentialPlots_(pSet.getParameter<bool>("differentialPlots")),
discrCut_(pSet.getParameter<double>("discrCut")),

etaActive_(pSet.getParameter<bool>("etaActive")),
etaMin_(pSet.getParameter<double>("etaMin")),
etaMax_(pSet.getParameter<double>("etaMax")),
ptActive_(pSet.getParameter<bool>("ptActive")),
ptMin_(pSet.getParameter<double>("ptMin")),
ptMax_(pSet.getParameter<double>("ptMax"))

{}

MiniAODTaggerHarvester::~MiniAODTaggerHarvester() {}

void MiniAODTaggerHarvester::dqmEndJob(DQMStore::IBooker& ibook, DQMStore::IGetter& iget) {
jetTagPlotter_ = std::make_unique<JetTagPlotter>(folder_,
EtaPtBin(etaActive_, etaMin_, etaMax_, ptActive_, ptMin_, ptMax_),
disrParameters_,
mclevel_,
true,
ibook,
doCTagPlots_,
dodifferentialPlots_,
discrCut_);

jetTagPlotter_->finalize(ibook, iget);
}

//define this as a plug-in
DEFINE_FWK_MODULE(MiniAODTaggerHarvester);
40 changes: 40 additions & 0 deletions DQMOffline/RecoB/plugins/MiniAODTaggerHarvester.h
@@ -0,0 +1,40 @@
#ifndef MiniAODTaggerHarvester_H
#define MiniAODTaggerHarvester_H

#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "DQMServices/Core/interface/DQMEDHarvester.h"
#include "DQMOffline/RecoB/interface/JetTagPlotter.h"

/** \class MiniAODTaggerHarvester
*
* Tagger harvester to run on MiniAOD
*
*/

class MiniAODTaggerHarvester : public DQMEDHarvester {
public:
explicit MiniAODTaggerHarvester(const edm::ParameterSet& pSet);
~MiniAODTaggerHarvester() override;

private:
void dqmEndJob(DQMStore::IBooker&, DQMStore::IGetter&) override;

std::unique_ptr<JetTagPlotter> jetTagPlotter_;

std::string folder_;
marco-link marked this conversation as resolved.
Show resolved Hide resolved
edm::ParameterSet disrParameters_;

int mclevel_;
bool doCTagPlots_;
bool dodifferentialPlots_;
double discrCut_;

bool etaActive_;
double etaMin_;
double etaMax_;
bool ptActive_;
double ptMin_;
double ptMax_;
};

#endif
24 changes: 0 additions & 24 deletions DQMOffline/RecoB/python/bTagCommon_cff.py
Expand Up @@ -50,29 +50,5 @@
folder = cms.string("JP")
),

cms.PSet(
bTagGenericAnalysisBlock,
label = cms.InputTag("pfDeepCSVDiscriminatorsJetTags:BvsAll"),
folder = cms.string("deepCSV_BvsAll"),
differentialPlots = cms.bool(True),
discrCut = cms.double(0.1522)
),
cms.PSet(
cTagGenericAnalysisBlock,
label = cms.InputTag("pfDeepCSVDiscriminatorsJetTags:CvsL"),
folder = cms.string("deepCSV_CvsL"),
doCTagPlots = cms.bool(True),
differentialPlots = cms.bool(True),
discrCut = cms.double(0.15)
),
cms.PSet(
cTagGenericAnalysisBlock,
label = cms.InputTag("pfDeepCSVDiscriminatorsJetTags:CvsB"),
folder = cms.string("deepCSV_CvsB"),
doCTagPlots = cms.bool(True),
differentialPlots = cms.bool(True),
discrCut = cms.double(0.28)
),

)
)
55 changes: 55 additions & 0 deletions DQMOffline/RecoB/python/bTagMiniDQMDeepCSV.py
@@ -0,0 +1,55 @@
import FWCore.ParameterSet.Config as cms

from DQMOffline.RecoB.bTagGenericAnalysis_cff import bTagGenericAnalysisBlock
from DQMOffline.RecoB.cTagGenericAnalysis_cff import cTagGenericAnalysisBlock


# recommendation for UL18: https://twiki.cern.ch/twiki/bin/view/CMS/BtagRecommendation106XUL18
deepCSVWP = {
'BvsAll': 0.1208, # loose
'CvsL': 0.153, # medium
'CvsB': 0.363, # medium
}


DeepCSVDiscriminators = {
'BvsAll': cms.PSet(
bTagGenericAnalysisBlock,

folder = cms.string('DeepCSV_BvsAll'),
CTagPlots = cms.bool(False),
discrCut = cms.double(deepCSVWP['BvsAll']),
numerator = cms.vstring(
'pfDeepCSVJetTags:probb',
'pfDeepCSVJetTags:probbb',
),
denominator = cms.vstring(),
),

'CvsL': cms.PSet(
cTagGenericAnalysisBlock,

folder = cms.string('DeepCSV_CvsL'),
CTagPlots = cms.bool(True),
discrCut = cms.double(deepCSVWP['CvsL']),
numerator = cms.vstring('pfDeepCSVJetTags:probc'),
denominator = cms.vstring(
'pfDeepCSVJetTags:probc',
'pfDeepCSVJetTags:probudsg',
),
),

'CvsB': cms.PSet(
cTagGenericAnalysisBlock,

folder = cms.string('DeepCSV_CvsB'),
CTagPlots = cms.bool(True),
discrCut = cms.double(deepCSVWP['CvsB']),
numerator = cms.vstring('pfDeepCSVJetTags:probc'),
denominator = cms.vstring(
'pfDeepCSVJetTags:probc',
'pfDeepCSVJetTags:probb',
'pfDeepCSVJetTags:probbb',
),
),
}