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

[EGM] Eta-Extended-Electrons (EEE) #35309

Merged
merged 10 commits into from Sep 30, 2021
Merged
Show file tree
Hide file tree
Changes from 8 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
13 changes: 13 additions & 0 deletions HLTrigger/Configuration/python/customizeHLTforCMSSW.py
Expand Up @@ -17,6 +17,18 @@
# pset.minGoodStripCharge = cms.PSet(refToPSet_ = cms.string('HLTSiStripClusterChargeCutNone'))
# return process

# Eta Extended Electrons
def customiseFor35309(process):
for pset in process._Process__psets.values():
if hasattr(pset,'ComponentType'):
if (pset.ComponentType == 'CkfBaseTrajectoryFilter'):
if not hasattr(pset, 'highEtaSwitch'):
pset.highEtaSwitch = cms.double(5.0)
if not hasattr(pset, 'minHitsAtHighEta'):
pset.minHitsAtHighEta = cms.int32(5)

return process
Copy link
Contributor

Choose a reason for hiding this comment

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

If these added parameters are all in their respective fillDescriptions method, then this customisation would not be needed. Is this the case or could it be achieved?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't seem straightforward to me, as fillDescriptions function is not present in one of the codes where we added new parameter.

Copy link
Contributor

Choose a reason for hiding this comment

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

Which one? Could it be added there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so this part can be deleted:

for esp in esproducers_by_type(process, 'KFFittingSmootherESProducer'):
        if not hasattr(esp, 'HighEtaSwitch'):
            esp.HighEtaSwitch = cms.double(5.0)
        if not hasattr(esp, 'MinNumberOfHitsHighEta'):
            esp.MinNumberOfHitsHighEta = cms.int32(5)

because TrackingTools/TrackFitters/plugins/KFFittingSmootherESProducer.cc already have fillDescriptions, and our new parameters are in there.

But the other part, the following, is needed:

    for pset in process._Process__psets.values():
        if hasattr(pset,'ComponentType'):
            if (pset.ComponentType == 'CkfBaseTrajectoryFilter'):
                if not hasattr(pset, 'highEtaSwitch'):
                    pset.highEtaSwitch = cms.double(5.0)
                if not hasattr(pset, 'minHitsAtHighEta'):
                    pset.minHitsAtHighEta = cms.int32(5)

because new parameters are added in TrackingTools/TrajectoryFiltering/interface/MinHitsTrajectoryFilter.h, and there is no fillDescriptions. Adding fillDescriptions in MinHitsTrajectoryFilter.cc doesn't solve the problem. It's not clear where we need to add fillDescriptions to make it work.

If possible, we would like to proceed with HLT customisation for now, and we will try to figure out fillDescriptions later on together with tracking experts.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you then please remove the 'KFFittingSmootherESProducer' customisation as it is not needed?
Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

BTW, HLTrigger/Configuration/python/customizeHLTforCMSSW.py shows a merge conflict, so it needs to be updated anyway.

Copy link
Contributor

Choose a reason for hiding this comment

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

My bad on the customisation @swagata87; when we discussed it offline, I missed that it was not needed for one of the modules.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've now removed KFFittingSmootherESProducer customisation and resolved the conflict...

My bad on the customisation @swagata87; when we discussed it offline, I missed that it was not needed for one of the modules.

oh no problem!

Copy link
Contributor

Choose a reason for hiding this comment

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

It's not clear where we need to add fillDescriptions to make it work.

From a quick look, it seems that the issue is the lack of a fillDescriptions in CkfTrackCandidateMaker (which in turn would probably be implemented as a function in CkfTrackCandidateMakerBase). That being said, this looks like something beyond the scope of this PR.


def customiseHCALFor2018Input(process):
"""Customise the HLT to run on Run 2 data/MC using the old readout for the HCAL barel"""

Expand Down Expand Up @@ -143,6 +155,7 @@ def customizeHLTforCMSSW(process, menuType="GRun"):
# add call to action function in proper order: newest last!
# process = customiseFor12718(process)

process = customiseFor35309(process)
process = customiseFor35315(process)

return process
1 change: 1 addition & 0 deletions RecoParticleFlow/PFProducer/interface/PFEGammaFilters.h
Expand Up @@ -52,6 +52,7 @@ class PFEGammaFilters {
const int ele_missinghits_;
const float ele_ecalDrivenHademPreselCut_;
const float ele_maxElePtForOnlyMVAPresel_;
const bool allowEEEinPF_;
float ele_maxNtracks_;
float ele_maxHcalE_;
float ele_maxTrackPOverEele_;
Expand Down
4 changes: 4 additions & 0 deletions RecoParticleFlow/PFProducer/python/particleFlow_cff.py
Expand Up @@ -10,6 +10,10 @@

particleFlowTmp = particleFlow.clone()

## temporary for 12_1; EtaExtendedEles do not enter PF because ID/regression of EEEs are not ready yet
## In 12_2, we expect to have EEE's ID/regression, then this switch can flip to True
particleFlowTmp.PFEGammaFiltersParameters.allowEEEinPF = cms.bool(False)

from Configuration.Eras.Modifier_pf_badHcalMitigationOff_cff import pf_badHcalMitigationOff
pf_badHcalMitigationOff.toModify(particleFlowTmp.PFEGammaFiltersParameters,
electron_protectionsForBadHcal = dict(enableProtections = False),
Expand Down
24 changes: 23 additions & 1 deletion RecoParticleFlow/PFProducer/src/PFEGammaFilters.cc
Expand Up @@ -36,7 +36,8 @@ PFEGammaFilters::PFEGammaFilters(const edm::ParameterSet& cfg)
ele_noniso_mva_(cfg.getParameter<double>("electron_noniso_mvaCut")),
ele_missinghits_(cfg.getParameter<unsigned int>("electron_missinghits")),
ele_ecalDrivenHademPreselCut_(cfg.getParameter<double>("electron_ecalDrivenHademPreselCut")),
ele_maxElePtForOnlyMVAPresel_(cfg.getParameter<double>("electron_maxElePtForOnlyMVAPresel")) {
ele_maxElePtForOnlyMVAPresel_(cfg.getParameter<double>("electron_maxElePtForOnlyMVAPresel")),
allowEEEinPF_(cfg.getParameter<bool>("allowEEEinPF")) {
auto const& eleProtectionsForBadHcal = cfg.getParameter<edm::ParameterSet>("electron_protectionsForBadHcal");
auto const& eleProtectionsForJetMET = cfg.getParameter<edm::ParameterSet>("electron_protectionsForJetMET");
auto const& phoProtectionsForBadHcal = cfg.getParameter<edm::ParameterSet>("photon_protectionsForBadHcal");
Expand Down Expand Up @@ -164,6 +165,16 @@ bool PFEGammaFilters::passElectronSelection(const reco::GsfElectron& electron,
}
}

//TEMPORARY hack.
Copy link
Contributor

Choose a reason for hiding this comment

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

please clarify in the code comment: temporary until when, to be fixed by who? better yet, link a github issue in the comment.

//Do not allow new EtaExtendedEle to enter PF, until ID, regression of EEEs are in place.
if (!allowEEEinPF_) {
int nHitGsf = electron.gsfTrack()->numberOfValidHits();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
int nHitGsf = electron.gsfTrack()->numberOfValidHits();
const auto nHitGsf = electron.gsfTrack()->numberOfValidHits();

double absEleEta = fabs(electron.eta());
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
double absEleEta = fabs(electron.eta());
const auto absEleEta = std::abs(electron.eta());

if ((absEleEta > 2.5) && (nHitGsf < 5)) {
passEleSelection = false;
}
}

return passEleSelection && passGsfElePreSelWithOnlyConeHadem(electron);
}

Expand Down Expand Up @@ -323,6 +334,16 @@ bool PFEGammaFilters::isElectronSafeForJetMET(const reco::GsfElectron& electron,
isSafeForJetMET = false;
}

//TEMPORARY hack.
//Do not allow new EtaExtendedEle to be SafeForJetMET, until ID, regression of EEEs are in place.
if (!allowEEEinPF_) {
int nHitGsf = electron.gsfTrack()->numberOfValidHits();
double absEleEta = fabs(electron.eta());
if ((absEleEta > 2.5) && (nHitGsf < 5)) {
isSafeForJetMET = false;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

this looks like a duplication with respect to the new lines 170-176 in the same file. please write a small function that you can call in either place, to avoid code duplication.


return isSafeForJetMET;
}
bool PFEGammaFilters::isPhotonSafeForJetMET(const reco::Photon& photon, const reco::PFCandidate& pfcand) const {
Expand Down Expand Up @@ -411,6 +432,7 @@ void PFEGammaFilters::fillPSetDescription(edm::ParameterSetDescription& iDesc) {
iDesc.add<unsigned int>("electron_missinghits", 1);
iDesc.add<double>("electron_ecalDrivenHademPreselCut", 0.15);
iDesc.add<double>("electron_maxElePtForOnlyMVAPresel", 50.0);
iDesc.add<bool>("allowEEEinPF", false);
{
edm::ParameterSetDescription psd;
psd.add<double>("maxNtracks", 3.0)->setComment("Max tracks pointing at Ele cluster");
Expand Down
Expand Up @@ -21,6 +21,8 @@
maxConsecLostHits = 1,
nSigmaMinPt = 5.0,
minimumNumberOfHits = 5,
highEtaSwitch = 2.5,
minHitsAtHighEta = 3,
maxCCCLostHits = 9999,
minGoodStripCharge = dict(refToPSet_ = 'SiStripClusterChargeCutNone')
)
Expand Down
Expand Up @@ -4,5 +4,7 @@
GsfElectronFittingSmoother = TrackingTools.TrackFitters.KFFittingSmoother_cfi.KFFittingSmoother.clone(
ComponentName = 'GsfElectronFittingSmoother',
Fitter = 'GsfTrajectoryFitter',
Smoother = 'GsfTrajectorySmoother'
Smoother = 'GsfTrajectorySmoother',
MinNumberOfHitsHighEta = 3,
HighEtaSwitch = 2.5
)
38 changes: 33 additions & 5 deletions TrackingTools/TrackFitters/plugins/KFFittingSmootherESProducer.cc
Expand Up @@ -28,6 +28,8 @@ namespace {
theNoOutliersBeginEnd(conf.getParameter<bool>("NoOutliersBeginEnd")),
theMinDof(conf.getParameter<int>("MinDof")),
theMinNumberOfHits(conf.getParameter<int>("MinNumberOfHits")),
theMinNumberOfHitsHighEta(conf.getParameter<int>("MinNumberOfHitsHighEta")),
theHighEtaSwitch(conf.getParameter<double>("HighEtaSwitch")),
rejectTracksFlag(conf.getParameter<bool>("RejectTracks")),
breakTrajWith2ConsecutiveMissing(conf.getParameter<bool>("BreakTrajWith2ConsecutiveMissing")),
noInvalidHitsBeginEnd(conf.getParameter<bool>("NoInvalidHitsBeginEnd")) {}
Expand All @@ -40,6 +42,8 @@ namespace {
int theMinDof;

int theMinNumberOfHits;
int theMinNumberOfHitsHighEta;
double theHighEtaSwitch;
bool rejectTracksFlag;
bool breakTrajWith2ConsecutiveMissing;
bool noInvalidHitsBeginEnd;
Expand All @@ -62,6 +66,8 @@ namespace {
desc.add<int>("MinDof", 2);
desc.add<bool>("NoOutliersBeginEnd", false);
desc.add<int>("MinNumberOfHits", 5);
desc.add<int>("MinNumberOfHitsHighEta", 5);
desc.add<double>("HighEtaSwitch", 5.0);
desc.add<bool>("RejectTracks", true);
desc.add<bool>("BreakTrajWith2ConsecutiveMissing", true);
desc.add<bool>("NoInvalidHitsBeginEnd", true);
Expand Down Expand Up @@ -93,14 +99,25 @@ namespace {
: KFFittingSmootherParam(other), theFitter(aFitter.clone()), theSmoother(aSmoother.clone()) {}

Trajectory smoothingStep(Trajectory&& fitted) const {
double absTrajEta = 99.0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
double absTrajEta = 99.0;
double absTrajEta = std::numeric_limits<double>::max();

if (!fitted.empty()) {
absTrajEta = fabs(fitted.lastMeasurement()
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
absTrajEta = fabs(fitted.lastMeasurement()
absTrajEta = std::abs(fitted.lastMeasurement()

.updatedState()
.freeTrajectoryState()
->momentum()
.eta()); //needed for eta-extended electrons
Copy link
Contributor

@VinInn VinInn Sep 21, 2021

Choose a reason for hiding this comment

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

This is very expensive.
I suggest to use pz^2/pt^2 instead of eta...
(actually the 'cut" should be: auto largeEta = pz*pz > theCut*pt2;
(where "theCut" is sinh(theHighEtaSwitch)^2;)

}
int thisHitCut = theMinNumberOfHits;
if (absTrajEta > theHighEtaSwitch)
thisHitCut = theMinNumberOfHitsHighEta;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
int thisHitCut = theMinNumberOfHits;
if (absTrajEta > theHighEtaSwitch)
thisHitCut = theMinNumberOfHitsHighEta;
const auto thisHitCut = absTrajEta > theHighEtaSwitch ? theMinNumberOfHitsHighEta : theMinNumberOfHits;

if (theEstimateCut > 0) {
// remove "outlier" at the end of Traj
while (
!fitted.empty() && fitted.foundHits() >= theMinNumberOfHits &&
!fitted.empty() && fitted.foundHits() >= thisHitCut &&
(!fitted.lastMeasurement().recHitR().isValid() || (fitted.lastMeasurement().recHitR().det() != nullptr &&
fitted.lastMeasurement().estimate() > theEstimateCut)))
fitted.pop();
if (fitted.foundHits() < theMinNumberOfHits)
if (fitted.foundHits() < thisHitCut)
return Trajectory();
}
return theSmoother->trajectory(fitted);
Expand Down Expand Up @@ -199,11 +216,22 @@ namespace {
#endif

bool hasNaN = false;
if (!smoothed.isValid() || (hasNaN = !checkForNans(smoothed)) || (smoothed.foundHits() < theMinNumberOfHits)) {
double absTrajEta = 99.0;
if (smoothed.isValid()) {
absTrajEta = fabs(smoothed.lastMeasurement()
.updatedState()
.freeTrajectoryState()
->momentum()
.eta()); //needed for eta-extended electrons
}
int thisHitCut = theMinNumberOfHits;
if (absTrajEta > theHighEtaSwitch)
thisHitCut = theMinNumberOfHitsHighEta;
if (!smoothed.isValid() || (hasNaN = !checkForNans(smoothed)) || (smoothed.foundHits() < thisHitCut)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

seems like code duplication with respect to L102-112. can you make this a function?

if (hasNaN)
edm::LogWarning("TrackNaN") << "Track has NaN or the cov is not pos-definite";
if (smoothed.foundHits() < theMinNumberOfHits)
LogTrace("TrackFitters") << "smoothed.foundHits()<theMinNumberOfHits";
if (smoothed.foundHits() < thisHitCut)
LogTrace("TrackFitters") << "smoothed.foundHits()<thisHitCut";
DPRINT("TrackFitters") << "smoothed invalid => trajectory rejected with nhits/chi2 " << smoothed.foundHits()
<< '/' << smoothed.chiSquared() << "\n";
if (rejectTracksFlag) {
Expand Down
Expand Up @@ -12,11 +12,19 @@

class MinHitsTrajectoryFilter final : public TrajectoryFilter {
public:
explicit MinHitsTrajectoryFilter(int minHits = 5, int seedPairPenalty = 0)
: theMinHits(minHits), theSeedPairPenalty(seedPairPenalty) {}
explicit MinHitsTrajectoryFilter(int minHits = 5,
double highEtaSwitch = 5.0,
int minHitsAtHighEta = 5,
int seedPairPenalty = 0)
: theMinHits(minHits),
theHighEtaSwitch(highEtaSwitch),
theMinHitsAtHighEta(minHitsAtHighEta),
theSeedPairPenalty(seedPairPenalty) {}

MinHitsTrajectoryFilter(const edm::ParameterSet& pset, edm::ConsumesCollector& iC)
: theMinHits(pset.getParameter<int>("minimumNumberOfHits")),
theHighEtaSwitch(pset.getParameter<double>("highEtaSwitch")),
theMinHitsAtHighEta(pset.getParameter<int>("minHitsAtHighEta")),
theSeedPairPenalty(pset.getParameter<int>("seedPairPenalty")) {}

bool qualityFilter(const Trajectory& traj) const override { return QF<Trajectory>(traj); }
Expand All @@ -30,6 +38,8 @@ class MinHitsTrajectoryFilter final : public TrajectoryFilter {
inline edm::ParameterSetDescription getFilledConfigurationDescription() {
edm::ParameterSetDescription desc;
desc.add<int>("minimumNumberOfHits", 5);
desc.add<double>("highEtaSwitch", 5.0);
desc.add<int>("minHitsAtHighEta", 5);
desc.add<int>("seedPairPenalty", 0);
return desc;
}
Expand All @@ -38,10 +48,21 @@ class MinHitsTrajectoryFilter final : public TrajectoryFilter {
template <class T>
bool QF(const T& traj) const {
int seedPenalty = (2 == traj.seedNHits()) ? theSeedPairPenalty : 0; // increase by one if seed-doublet...
return (traj.foundHits() >= theMinHits + seedPenalty);
bool passed = false;
double absTrajEta = fabs(traj.lastMeasurement().updatedState().freeTrajectoryState()->momentum().eta());
if (absTrajEta < theHighEtaSwitch) {
if (traj.foundHits() >= theMinHits + seedPenalty)
passed = true;
} else { //absTrajEta>theHighEtaSwitch, so apply relaxed cuts
if (traj.foundHits() >= theMinHitsAtHighEta + seedPenalty)
passed = true;
}
return passed;
}

int theMinHits;
double theHighEtaSwitch;
int theMinHitsAtHighEta;
int theSeedPairPenalty;
};

Expand Down
Expand Up @@ -8,6 +8,8 @@
#--- Cuts applied to completed trajectory
# At least this many hits (counting matched hits as 1)
minimumNumberOfHits = cms.int32(5),
highEtaSwitch = cms.double(5.0),
minHitsAtHighEta = cms.int32(5),
# add this if seed is a Pair (opposed to a triplet)
seedPairPenalty = cms.int32(0),
# What is this ?
Expand Down Expand Up @@ -68,7 +70,9 @@
)
MinHitsTrajectoryFilter_block = cms.PSet(
ComponentType = cms.string('MinHitsTrajectoryFilter'),
minimumNumberOfHits = cms.int32(5)
minimumNumberOfHits = cms.int32(5),
highEtaSwitch = cms.double(5.0),
minHitsAtHighEta = cms.int32(5)
)
MinPtTrajectoryFilter_block = cms.PSet(
ComponentType = cms.string('MinPtTrajectoryFilter'),
Expand Down