File indexing completed on 2024-04-06 12:27:33
0001 #include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h"
0002 #include "DataFormats/MuonReco/interface/Muon.h"
0003 #include "DataFormats/MuonReco/interface/MuonCocktails.h"
0004 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0005 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
0006 #include "DataFormats/ParticleFlowReco/interface/PFBlockElement.h"
0007 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
0008 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementTrack.h"
0009 #include "DataFormats/TrackReco/interface/Track.h"
0010 #include <iostream>
0011 #include <memory>
0012
0013 using namespace std;
0014 using namespace reco;
0015 using namespace boost;
0016
0017 PFMuonAlgo::PFMuonAlgo(const edm::ParameterSet& iConfig, bool postMuonCleaning)
0018
0019 : pfCosmicsMuonCleanedCandidates_(std::make_unique<reco::PFCandidateCollection>()),
0020 pfCleanedTrackerAndGlobalMuonCandidates_(std::make_unique<reco::PFCandidateCollection>()),
0021 pfFakeMuonCleanedCandidates_(std::make_unique<reco::PFCandidateCollection>()),
0022 pfPunchThroughMuonCleanedCandidates_(std::make_unique<reco::PFCandidateCollection>()),
0023 pfPunchThroughHadronCleanedCandidates_(std::make_unique<reco::PFCandidateCollection>()),
0024 pfAddedMuonCandidates_(std::make_unique<reco::PFCandidateCollection>()),
0025
0026 maxDPtOPt_(iConfig.getParameter<double>("maxDPtOPt")),
0027 trackQuality_(reco::TrackBase::qualityByName(iConfig.getParameter<std::string>("trackQuality"))),
0028 errorCompScale_(iConfig.getParameter<double>("ptErrorScale")),
0029
0030 postCleaning_(postMuonCleaning),
0031 eventFractionCleaning_(iConfig.getParameter<double>("eventFractionForCleaning")),
0032 minPostCleaningPt_(iConfig.getParameter<double>("minPtForPostCleaning")),
0033 eventFactorCosmics_(iConfig.getParameter<double>("eventFactorForCosmics")),
0034 metSigForCleaning_(iConfig.getParameter<double>("metSignificanceForCleaning")),
0035 metSigForRejection_(iConfig.getParameter<double>("metSignificanceForRejection")),
0036 metFactorCleaning_(iConfig.getParameter<double>("metFactorForCleaning")),
0037 eventFractionRejection_(iConfig.getParameter<double>("eventFractionForRejection")),
0038 metFactorRejection_(iConfig.getParameter<double>("metFactorForRejection")),
0039 metFactorHighEta_(iConfig.getParameter<double>("metFactorForHighEta")),
0040 ptFactorHighEta_(iConfig.getParameter<double>("ptFactorForHighEta")),
0041 metFactorFake_(iConfig.getParameter<double>("metFactorForFakes")),
0042 minPunchThroughMomentum_(iConfig.getParameter<double>("minMomentumForPunchThrough")),
0043 minPunchThroughEnergy_(iConfig.getParameter<double>("minEnergyForPunchThrough")),
0044 punchThroughFactor_(iConfig.getParameter<double>("punchThroughFactor")),
0045 punchThroughMETFactor_(iConfig.getParameter<double>("punchThroughMETFactor")),
0046 cosmicRejDistance_(iConfig.getParameter<double>("cosmicRejectionDistance")) {}
0047
0048 bool PFMuonAlgo::isMuon(const reco::PFBlockElement& elt) {
0049 const auto* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
0050
0051 assert(eltTrack);
0052 reco::MuonRef muonRef = eltTrack->muonRef();
0053
0054 return isMuon(muonRef);
0055 }
0056
0057 bool PFMuonAlgo::isLooseMuon(const reco::PFBlockElement& elt) {
0058 const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
0059
0060 assert(eltTrack);
0061
0062 reco::MuonRef muonRef = eltTrack->muonRef();
0063
0064 return isLooseMuon(muonRef);
0065 }
0066
0067 bool PFMuonAlgo::isGlobalTightMuon(const reco::PFBlockElement& elt) {
0068 const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
0069
0070 assert(eltTrack);
0071 reco::MuonRef muonRef = eltTrack->muonRef();
0072
0073 return isGlobalTightMuon(muonRef);
0074 }
0075
0076 bool PFMuonAlgo::isGlobalLooseMuon(const reco::PFBlockElement& elt) {
0077 const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
0078
0079 assert(eltTrack);
0080 reco::MuonRef muonRef = eltTrack->muonRef();
0081
0082 return isGlobalLooseMuon(muonRef);
0083 }
0084
0085 bool PFMuonAlgo::isTrackerTightMuon(const reco::PFBlockElement& elt) {
0086 const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
0087
0088 assert(eltTrack);
0089 reco::MuonRef muonRef = eltTrack->muonRef();
0090
0091 return isTrackerTightMuon(muonRef);
0092 }
0093
0094 bool PFMuonAlgo::isIsolatedMuon(const reco::PFBlockElement& elt) {
0095 const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
0096
0097 assert(eltTrack);
0098 reco::MuonRef muonRef = eltTrack->muonRef();
0099
0100 return isIsolatedMuon(muonRef);
0101 }
0102
0103 bool PFMuonAlgo::isMuon(const reco::MuonRef& muonRef) {
0104 return isGlobalTightMuon(muonRef) || isTrackerTightMuon(muonRef) || isIsolatedMuon(muonRef);
0105 }
0106
0107 bool PFMuonAlgo::isLooseMuon(const reco::MuonRef& muonRef) {
0108 return (isGlobalLooseMuon(muonRef) || isTrackerLooseMuon(muonRef));
0109 }
0110
0111 bool PFMuonAlgo::isGlobalTightMuon(const reco::MuonRef& muonRef) {
0112 if (!muonRef.isNonnull())
0113 return false;
0114
0115 if (!muonRef->isGlobalMuon())
0116 return false;
0117 if (!muonRef->isStandAloneMuon())
0118 return false;
0119
0120 if (muonRef->isTrackerMuon()) {
0121 bool result = muon::isGoodMuon(*muonRef, muon::GlobalMuonPromptTight);
0122
0123 bool isTM2DCompatibilityTight = muon::isGoodMuon(*muonRef, muon::TM2DCompatibilityTight);
0124 int nMatches = muonRef->numberOfMatches();
0125 bool quality = nMatches > 2 || isTM2DCompatibilityTight;
0126
0127 return result && quality;
0128
0129 } else {
0130 reco::TrackRef standAloneMu = muonRef->standAloneMuon();
0131
0132
0133 bool result = false;
0134
0135
0136
0137 if ((standAloneMu->hitPattern().numberOfValidMuonDTHits() < 22 &&
0138 standAloneMu->hitPattern().numberOfValidMuonCSCHits() < 15) ||
0139 standAloneMu->normalizedChi2() > 10. || standAloneMu->ptError() / standAloneMu->pt() > 0.20) {
0140 result = false;
0141 } else {
0142 reco::TrackRef combinedMu = muonRef->combinedMuon();
0143 reco::TrackRef trackerMu = muonRef->track();
0144
0145
0146 if (combinedMu->normalizedChi2() > standAloneMu->normalizedChi2()) {
0147
0148
0149
0150
0151
0152
0153 result = standAloneMu->pt() > trackerMu->pt();
0154 } else {
0155
0156
0157 result =
0158 combinedMu->ptError() / combinedMu->pt() < std::min(0.20, standAloneMu->ptError() / standAloneMu->pt());
0159 }
0160 }
0161
0162 return result;
0163 }
0164
0165 return false;
0166 }
0167
0168 bool PFMuonAlgo::isTrackerTightMuon(const reco::MuonRef& muonRef) {
0169 if (!muonRef.isNonnull())
0170 return false;
0171
0172 if (!muonRef->isTrackerMuon())
0173 return false;
0174
0175 reco::TrackRef trackerMu = muonRef->track();
0176 const reco::Track& track = *trackerMu;
0177
0178 unsigned nTrackerHits = track.hitPattern().numberOfValidTrackerHits();
0179
0180 if (nTrackerHits <= 12)
0181 return false;
0182
0183 bool isAllArbitrated = muon::isGoodMuon(*muonRef, muon::AllArbitrated);
0184
0185 bool isTM2DCompatibilityTight = muon::isGoodMuon(*muonRef, muon::TM2DCompatibilityTight);
0186
0187 if (!isAllArbitrated || !isTM2DCompatibilityTight)
0188 return false;
0189
0190 if ((trackerMu->ptError() / trackerMu->pt() > 0.10)) {
0191
0192 return false;
0193 }
0194 return true;
0195 }
0196
0197 bool PFMuonAlgo::isGlobalLooseMuon(const reco::MuonRef& muonRef) {
0198 if (!muonRef.isNonnull())
0199 return false;
0200 if (!muonRef->isGlobalMuon())
0201 return false;
0202 if (!muonRef->isStandAloneMuon())
0203 return false;
0204
0205 reco::TrackRef standAloneMu = muonRef->standAloneMuon();
0206 reco::TrackRef combinedMu = muonRef->combinedMuon();
0207 reco::TrackRef trackerMu = muonRef->track();
0208
0209 unsigned nMuonHits =
0210 standAloneMu->hitPattern().numberOfValidMuonDTHits() + 2 * standAloneMu->hitPattern().numberOfValidMuonCSCHits();
0211
0212 bool quality = false;
0213
0214 if (muonRef->isTrackerMuon()) {
0215 bool result = combinedMu->normalizedChi2() < 100.;
0216
0217 bool laststation = muon::isGoodMuon(*muonRef, muon::TMLastStationAngTight);
0218
0219 int nMatches = muonRef->numberOfMatches();
0220
0221 quality = laststation && nMuonHits > 12 && nMatches > 1;
0222
0223 return result && quality;
0224
0225 } else {
0226
0227
0228 if (nMuonHits <= 15 || standAloneMu->normalizedChi2() > 10. ||
0229 standAloneMu->ptError() / standAloneMu->pt() > 0.20) {
0230 quality = false;
0231 } else {
0232
0233 if (combinedMu->normalizedChi2() > standAloneMu->normalizedChi2()) {
0234
0235
0236
0237
0238
0239
0240
0241
0242 if (standAloneMu->pt() > trackerMu->pt() || combinedMu->normalizedChi2() < 5.)
0243 quality = true;
0244 } else {
0245
0246
0247 if (combinedMu->ptError() / combinedMu->pt() < std::min(0.20, standAloneMu->ptError() / standAloneMu->pt()))
0248 quality = true;
0249 }
0250 }
0251 }
0252
0253 return quality;
0254 }
0255
0256 bool PFMuonAlgo::isTrackerLooseMuon(const reco::MuonRef& muonRef) {
0257 if (!muonRef.isNonnull())
0258 return false;
0259 if (!muonRef->isTrackerMuon())
0260 return false;
0261
0262 reco::TrackRef trackerMu = muonRef->track();
0263
0264 if (trackerMu->ptError() / trackerMu->pt() > 0.20)
0265 return false;
0266
0267
0268 if (trackerMu->pt() > 20.)
0269 return false;
0270
0271 bool isAllArbitrated = muon::isGoodMuon(*muonRef, muon::AllArbitrated);
0272 bool isTMLastStationAngTight = muon::isGoodMuon(*muonRef, muon::TMLastStationAngTight);
0273
0274 bool quality = isAllArbitrated && isTMLastStationAngTight;
0275
0276 return quality;
0277 }
0278
0279 bool PFMuonAlgo::isIsolatedMuon(const reco::MuonRef& muonRef) {
0280 if (!muonRef.isNonnull())
0281 return false;
0282 if (!muonRef->isIsolationValid())
0283 return false;
0284
0285
0286 if (!muonRef->isGlobalMuon())
0287 return false;
0288
0289
0290
0291 reco::TrackRef standAloneMu = muonRef->standAloneMuon();
0292
0293 if (!muonRef->isTrackerMuon()) {
0294 if (standAloneMu->hitPattern().numberOfValidMuonDTHits() == 0 &&
0295 standAloneMu->hitPattern().numberOfValidMuonCSCHits() == 0)
0296 return false;
0297 }
0298
0299
0300
0301 reco::TrackRef combinedMu = muonRef->combinedMuon();
0302 double smallestMuPt = combinedMu->pt();
0303
0304 if (standAloneMu->pt() < smallestMuPt)
0305 smallestMuPt = standAloneMu->pt();
0306
0307 if (muonRef->isTrackerMuon()) {
0308 reco::TrackRef trackerMu = muonRef->track();
0309 if (trackerMu->pt() < smallestMuPt)
0310 smallestMuPt = trackerMu->pt();
0311 }
0312
0313 double sumPtR03 = muonRef->isolationR03().sumPt;
0314
0315 double relIso = sumPtR03 / smallestMuPt;
0316
0317 if (relIso < 0.1)
0318 return true;
0319 else
0320 return false;
0321 }
0322
0323 bool PFMuonAlgo::isTightMuonPOG(const reco::MuonRef& muonRef) {
0324 if (!muon::isGoodMuon(*muonRef, muon::GlobalMuonPromptTight))
0325 return false;
0326
0327 if (!muonRef->isTrackerMuon())
0328 return false;
0329
0330 if (muonRef->numberOfMatches() < 2)
0331 return false;
0332
0333
0334 const reco::TrackRef& combinedMuon = muonRef->globalTrack();
0335
0336 if (combinedMuon->hitPattern().numberOfValidTrackerHits() < 11)
0337 return false;
0338
0339 if (combinedMuon->hitPattern().numberOfValidPixelHits() == 0)
0340 return false;
0341
0342 if (combinedMuon->hitPattern().numberOfValidMuonHits() == 0)
0343 return false;
0344
0345 return true;
0346 }
0347
0348 bool PFMuonAlgo::hasValidTrack(const reco::MuonRef& muonRef, bool loose, double maxDPtOPt) {
0349 if (loose)
0350 return !muonTracks(muonRef).empty();
0351 else
0352 return !muonTracks(muonRef, maxDPtOPt).empty();
0353 }
0354
0355 void PFMuonAlgo::printMuonProperties(const reco::MuonRef& muonRef) {
0356 if (!muonRef.isNonnull())
0357 return;
0358
0359 bool isGL = muonRef->isGlobalMuon();
0360 bool isTR = muonRef->isTrackerMuon();
0361 bool isST = muonRef->isStandAloneMuon();
0362
0363 std::cout << " GL: " << isGL << " TR: " << isTR << " ST: " << isST << std::endl;
0364 std::cout << " nMatches " << muonRef->numberOfMatches() << std::endl;
0365
0366 if (muonRef->isGlobalMuon()) {
0367 reco::TrackRef combinedMu = muonRef->combinedMuon();
0368 std::cout << " GL, pt: " << combinedMu->pt() << " +/- " << combinedMu->ptError() / combinedMu->pt()
0369 << " chi**2 GBL : " << combinedMu->normalizedChi2() << std::endl;
0370 std::cout << " Total Muon Hits : " << combinedMu->hitPattern().numberOfValidMuonHits() << "/"
0371 << combinedMu->hitPattern().numberOfLostMuonHits()
0372 << " DT Hits : " << combinedMu->hitPattern().numberOfValidMuonDTHits() << "/"
0373 << combinedMu->hitPattern().numberOfLostMuonDTHits()
0374 << " CSC Hits : " << combinedMu->hitPattern().numberOfValidMuonCSCHits() << "/"
0375 << combinedMu->hitPattern().numberOfLostMuonCSCHits()
0376 << " RPC Hits : " << combinedMu->hitPattern().numberOfValidMuonRPCHits() << "/"
0377 << combinedMu->hitPattern().numberOfLostMuonRPCHits() << std::endl;
0378
0379 std::cout << " # of Valid Tracker Hits " << combinedMu->hitPattern().numberOfValidTrackerHits() << std::endl;
0380 std::cout << " # of Valid Pixel Hits " << combinedMu->hitPattern().numberOfValidPixelHits() << std::endl;
0381 }
0382 if (muonRef->isStandAloneMuon()) {
0383 reco::TrackRef standAloneMu = muonRef->standAloneMuon();
0384 std::cout << " ST, pt: " << standAloneMu->pt() << " +/- " << standAloneMu->ptError() / standAloneMu->pt()
0385 << " eta : " << standAloneMu->eta()
0386 << " DT Hits : " << standAloneMu->hitPattern().numberOfValidMuonDTHits() << "/"
0387 << standAloneMu->hitPattern().numberOfLostMuonDTHits()
0388 << " CSC Hits : " << standAloneMu->hitPattern().numberOfValidMuonCSCHits() << "/"
0389 << standAloneMu->hitPattern().numberOfLostMuonCSCHits()
0390 << " RPC Hits : " << standAloneMu->hitPattern().numberOfValidMuonRPCHits() << "/"
0391 << standAloneMu->hitPattern().numberOfLostMuonRPCHits()
0392 << " chi**2 STA : " << standAloneMu->normalizedChi2() << std::endl;
0393 }
0394
0395 if (muonRef->isTrackerMuon()) {
0396 reco::TrackRef trackerMu = muonRef->track();
0397 const reco::Track& track = *trackerMu;
0398 std::cout << " TR, pt: " << trackerMu->pt() << " +/- " << trackerMu->ptError() / trackerMu->pt()
0399 << " chi**2 TR : " << trackerMu->normalizedChi2() << std::endl;
0400 std::cout << " nTrackerHits " << track.hitPattern().numberOfValidTrackerHits() << std::endl;
0401 std::cout << "TMLastStationAngLoose " << muon::isGoodMuon(*muonRef, muon::TMLastStationAngLoose)
0402 << std::endl
0403 << "TMLastStationAngTight " << muon::isGoodMuon(*muonRef, muon::TMLastStationAngTight)
0404 << std::endl
0405 << "TMLastStationLoose " << muon::isGoodMuon(*muonRef, muon::TMLastStationLoose)
0406 << std::endl
0407 << "TMLastStationTight " << muon::isGoodMuon(*muonRef, muon::TMLastStationTight)
0408 << std::endl
0409 << "TMOneStationLoose " << muon::isGoodMuon(*muonRef, muon::TMOneStationLoose) << std::endl
0410 << "TMOneStationTight " << muon::isGoodMuon(*muonRef, muon::TMOneStationTight) << std::endl
0411 << "TMLastStationOptimizedLowPtLoose "
0412 << muon::isGoodMuon(*muonRef, muon::TMLastStationOptimizedLowPtLoose) << std::endl
0413 << "TMLastStationOptimizedLowPtTight "
0414 << muon::isGoodMuon(*muonRef, muon::TMLastStationOptimizedLowPtTight) << std::endl
0415 << "TMLastStationOptimizedBarrelLowPtLoose "
0416 << muon::isGoodMuon(*muonRef, muon::TMLastStationOptimizedBarrelLowPtLoose) << std::endl
0417 << "TMLastStationOptimizedBarrelLowPtTight "
0418 << muon::isGoodMuon(*muonRef, muon::TMLastStationOptimizedBarrelLowPtTight) << std::endl
0419 << std::endl;
0420 }
0421
0422 std::cout << "TM2DCompatibilityLoose " << muon::isGoodMuon(*muonRef, muon::TM2DCompatibilityLoose)
0423 << std::endl
0424 << "TM2DCompatibilityTight " << muon::isGoodMuon(*muonRef, muon::TM2DCompatibilityTight)
0425 << std::endl;
0426
0427 if (muonRef->isGlobalMuon() && muonRef->isTrackerMuon() && muonRef->isStandAloneMuon()) {
0428 reco::TrackRef combinedMu = muonRef->combinedMuon();
0429 reco::TrackRef trackerMu = muonRef->track();
0430 reco::TrackRef standAloneMu = muonRef->standAloneMuon();
0431
0432 double sigmaCombined = combinedMu->ptError() / (combinedMu->pt() * combinedMu->pt());
0433 double sigmaTracker = trackerMu->ptError() / (trackerMu->pt() * trackerMu->pt());
0434 double sigmaStandAlone = standAloneMu->ptError() / (standAloneMu->pt() * standAloneMu->pt());
0435
0436 bool combined = combinedMu->ptError() / combinedMu->pt() < 0.20;
0437 bool tracker = trackerMu->ptError() / trackerMu->pt() < 0.20;
0438 bool standAlone = standAloneMu->ptError() / standAloneMu->pt() < 0.20;
0439
0440 double delta1 = combined && tracker ? fabs(1. / combinedMu->pt() - 1. / trackerMu->pt()) /
0441 sqrt(sigmaCombined * sigmaCombined + sigmaTracker * sigmaTracker)
0442 : 100.;
0443 double delta2 = combined && standAlone ? fabs(1. / combinedMu->pt() - 1. / standAloneMu->pt()) /
0444 sqrt(sigmaCombined * sigmaCombined + sigmaStandAlone * sigmaStandAlone)
0445 : 100.;
0446 double delta3 = standAlone && tracker ? fabs(1. / standAloneMu->pt() - 1. / trackerMu->pt()) /
0447 sqrt(sigmaStandAlone * sigmaStandAlone + sigmaTracker * sigmaTracker)
0448 : 100.;
0449
0450 double delta =
0451 standAloneMu->hitPattern().numberOfValidMuonDTHits() + standAloneMu->hitPattern().numberOfValidMuonCSCHits() > 0
0452 ? std::min(delta3, std::min(delta1, delta2))
0453 : std::max(delta3, std::max(delta1, delta2));
0454
0455 std::cout << "delta = " << delta << " delta1 " << delta1 << " delta2 " << delta2 << " delta3 " << delta3
0456 << std::endl;
0457
0458 double ratio = combinedMu->ptError() / combinedMu->pt() / (trackerMu->ptError() / trackerMu->pt());
0459
0460 std::cout << " ratio " << ratio << " combined mu pt " << combinedMu->pt() << std::endl;
0461
0462 }
0463
0464 double sumPtR03 = muonRef->isolationR03().sumPt;
0465 double emEtR03 = muonRef->isolationR03().emEt;
0466 double hadEtR03 = muonRef->isolationR03().hadEt;
0467 double relIsoR03 = (sumPtR03 + emEtR03 + hadEtR03) / muonRef->pt();
0468 double sumPtR05 = muonRef->isolationR05().sumPt;
0469 double emEtR05 = muonRef->isolationR05().emEt;
0470 double hadEtR05 = muonRef->isolationR05().hadEt;
0471 double relIsoR05 = (sumPtR05 + emEtR05 + hadEtR05) / muonRef->pt();
0472 std::cout << " 0.3 Radion Rel Iso: " << relIsoR03 << " sumPt " << sumPtR03 << " emEt " << emEtR03 << " hadEt "
0473 << hadEtR03 << std::endl;
0474 std::cout << " 0.5 Radion Rel Iso: " << relIsoR05 << " sumPt " << sumPtR05 << " emEt " << emEtR05 << " hadEt "
0475 << hadEtR05 << std::endl;
0476 return;
0477 }
0478
0479 int PFMuonAlgo::muAssocToTrack(const reco::TrackRef& trackref, const reco::MuonCollection& muons) {
0480 auto muon = std::find_if(muons.cbegin(), muons.cend(), [&](const reco::Muon& m) {
0481 return (m.track().isNonnull() && m.track() == trackref);
0482 });
0483 return (muon != muons.cend() ? std::distance(muons.cbegin(), muon) : -1);
0484 }
0485
0486 std::vector<reco::Muon::MuonTrackTypePair> PFMuonAlgo::muonTracks(const reco::MuonRef& muon,
0487 double maxDPtOPt,
0488 bool includeSA) {
0489 std::vector<reco::Muon::MuonTrackTypePair> out;
0490
0491 if (muon->globalTrack().isNonnull() && muon->globalTrack()->pt() > 0)
0492 if (muon->globalTrack()->ptError() / muon->globalTrack()->pt() < maxDPtOPt)
0493 out.emplace_back(muon->globalTrack(), reco::Muon::CombinedTrack);
0494
0495 if (muon->innerTrack().isNonnull() && muon->innerTrack()->pt() > 0)
0496 if (muon->innerTrack()->ptError() / muon->innerTrack()->pt() < maxDPtOPt)
0497 out.emplace_back(muon->innerTrack(), reco::Muon::InnerTrack);
0498
0499 bool pickyExists = false;
0500 double pickyDpt = 99999.;
0501 if (muon->pickyTrack().isNonnull() && muon->pickyTrack()->pt() > 0) {
0502 pickyDpt = muon->pickyTrack()->ptError() / muon->pickyTrack()->pt();
0503 if (pickyDpt < maxDPtOPt)
0504 out.emplace_back(muon->pickyTrack(), reco::Muon::Picky);
0505 pickyExists = true;
0506 }
0507
0508 bool dytExists = false;
0509 double dytDpt = 99999.;
0510 if (muon->dytTrack().isNonnull() && muon->dytTrack()->pt() > 0) {
0511 dytDpt = muon->dytTrack()->ptError() / muon->dytTrack()->pt();
0512 if (dytDpt < maxDPtOPt)
0513 out.emplace_back(muon->dytTrack(), reco::Muon::DYT);
0514 dytExists = true;
0515 }
0516
0517
0518
0519
0520
0521 if (muon->tpfmsTrack().isNonnull() && muon->tpfmsTrack()->pt() > 0) {
0522 double tpfmsDpt = muon->tpfmsTrack()->ptError() / muon->tpfmsTrack()->pt();
0523 if (((pickyExists && tpfmsDpt < pickyDpt) || (!pickyExists)) &&
0524 ((dytExists && tpfmsDpt < dytDpt) || (!dytExists)) && tpfmsDpt < maxDPtOPt)
0525 out.emplace_back(muon->tpfmsTrack(), reco::Muon::TPFMS);
0526 }
0527
0528 if (includeSA && muon->outerTrack().isNonnull())
0529 if (muon->outerTrack()->ptError() / muon->outerTrack()->pt() < maxDPtOPt)
0530 out.emplace_back(muon->outerTrack(), reco::Muon::OuterTrack);
0531
0532 return out;
0533 }
0534
0535
0536
0537 bool PFMuonAlgo::reconstructMuon(reco::PFCandidate& candidate, const reco::MuonRef& muon, bool allowLoose) {
0538 using namespace std;
0539 using namespace reco;
0540
0541 if (!muon.isNonnull())
0542 return false;
0543
0544 bool isMu = false;
0545
0546 if (allowLoose)
0547 isMu = isMuon(muon) || isLooseMuon(muon);
0548 else
0549 isMu = isMuon(muon);
0550
0551 if (!isMu)
0552 return false;
0553
0554
0555
0556
0557
0558
0559 std::vector<reco::Muon::MuonTrackTypePair> validTracks = muonTracks(muon, maxDPtOPt_);
0560 if (!allowLoose)
0561 validTracks = muonTracks(muon, maxDPtOPt_);
0562 else
0563 validTracks = muonTracks(muon);
0564
0565 if (validTracks.empty())
0566 return false;
0567
0568
0569 reco::Muon::MuonTrackTypePair bestTrackPair = muon::tevOptimized(*muon);
0570
0571 TrackRef bestTrack = bestTrackPair.first;
0572 MuonTrackType trackType = bestTrackPair.second;
0573
0574 MuonTrackTypePair trackPairWithSmallestError = getTrackWithSmallestError(validTracks);
0575 TrackRef trackWithSmallestError = trackPairWithSmallestError.first;
0576
0577 if (trackType == reco::Muon::InnerTrack &&
0578 (!bestTrack->quality(trackQuality_) ||
0579 bestTrack->ptError() / bestTrack->pt() >
0580 errorCompScale_ * trackWithSmallestError->ptError() / trackWithSmallestError->pt())) {
0581 bestTrack = trackWithSmallestError;
0582 trackType = trackPairWithSmallestError.second;
0583 } else if (trackType != reco::Muon::InnerTrack &&
0584 bestTrack->ptError() / bestTrack->pt() >
0585 errorCompScale_ * trackWithSmallestError->ptError() / trackWithSmallestError->pt()) {
0586 bestTrack = trackWithSmallestError;
0587 trackType = trackPairWithSmallestError.second;
0588 }
0589
0590 changeTrack(candidate, std::make_pair(bestTrack, trackType));
0591 candidate.setMuonRef(muon);
0592
0593 return true;
0594 }
0595
0596 void PFMuonAlgo::changeTrack(reco::PFCandidate& candidate, const MuonTrackTypePair& track) {
0597 using namespace reco;
0598 reco::TrackRef bestTrack = track.first;
0599 MuonTrackType trackType = track.second;
0600
0601 double px = bestTrack->px();
0602 double py = bestTrack->py();
0603 double pz = bestTrack->pz();
0604 double energy = sqrt(bestTrack->p() * bestTrack->p() + 0.1057 * 0.1057);
0605
0606 candidate.setCharge(bestTrack->charge() > 0 ? 1 : -1);
0607 candidate.setP4(math::XYZTLorentzVector(px, py, pz, energy));
0608 candidate.setParticleType(reco::PFCandidate::mu);
0609
0610 candidate.setMuonTrackType(trackType);
0611 candidate.setVertex(bestTrack->vertex());
0612 }
0613
0614 reco::Muon::MuonTrackTypePair PFMuonAlgo::getTrackWithSmallestError(
0615 const std::vector<reco::Muon::MuonTrackTypePair>& tracks) {
0616 TrackPtErrorSorter sorter;
0617 return *std::min_element(tracks.begin(), tracks.end(), sorter);
0618 }
0619
0620 void PFMuonAlgo::estimateEventQuantities(const reco::PFCandidateCollection* pfc) {
0621
0622 sumetPU_ = 0.0;
0623 METX_ = 0.;
0624 METY_ = 0.;
0625 sumet_ = 0.0;
0626 for (reco::PFCandidateCollection::const_iterator i = pfc->begin(); i != pfc->end(); ++i) {
0627 sumet_ += i->pt();
0628 METX_ += i->px();
0629 METY_ += i->py();
0630 }
0631 }
0632
0633 void PFMuonAlgo::postClean(reco::PFCandidateCollection* cands) {
0634 using namespace std;
0635 using namespace reco;
0636 if (!postCleaning_)
0637 return;
0638
0639
0640
0641 if (pfCosmicsMuonCleanedCandidates_.get())
0642 pfCosmicsMuonCleanedCandidates_->clear();
0643 else
0644 pfCosmicsMuonCleanedCandidates_ = std::make_unique<reco::PFCandidateCollection>();
0645
0646 if (pfCleanedTrackerAndGlobalMuonCandidates_.get())
0647 pfCleanedTrackerAndGlobalMuonCandidates_->clear();
0648 else
0649 pfCleanedTrackerAndGlobalMuonCandidates_ = std::make_unique<reco::PFCandidateCollection>();
0650
0651 if (pfFakeMuonCleanedCandidates_.get())
0652 pfFakeMuonCleanedCandidates_->clear();
0653 else
0654 pfFakeMuonCleanedCandidates_ = std::make_unique<reco::PFCandidateCollection>();
0655
0656 if (pfPunchThroughMuonCleanedCandidates_.get())
0657 pfPunchThroughMuonCleanedCandidates_->clear();
0658 else
0659 pfPunchThroughMuonCleanedCandidates_ = std::make_unique<reco::PFCandidateCollection>();
0660
0661 if (pfPunchThroughHadronCleanedCandidates_.get())
0662 pfPunchThroughHadronCleanedCandidates_->clear();
0663 else
0664 pfPunchThroughHadronCleanedCandidates_ = std::make_unique<reco::PFCandidateCollection>();
0665
0666 pfPunchThroughHadronCleanedCandidates_->clear();
0667
0668 maskedIndices_.clear();
0669
0670
0671
0672 estimateEventQuantities(cands);
0673
0674 std::vector<int> muons;
0675 std::vector<int> cosmics;
0676
0677 for (unsigned int i = 0; i < cands->size(); ++i) {
0678 const reco::PFCandidate& cand = (*cands)[i];
0679 if (cand.particleId() == reco::PFCandidate::mu)
0680 muons.push_back(i);
0681 }
0682
0683
0684 IndexPtComparator comparator(cands);
0685 std::sort(muons.begin(), muons.end(), comparator);
0686
0687
0688 double METXCosmics = 0;
0689 double METYCosmics = 0;
0690 double SUMETCosmics = 0.0;
0691
0692 for (unsigned int i = 0; i < muons.size(); ++i) {
0693 const PFCandidate& pfc = cands->at(muons[i]);
0694 double origin = 0.0;
0695 if (!vertices_->empty() && vertices_->at(0).isValid() && !vertices_->at(0).isFake())
0696 origin = pfc.muonRef()->muonBestTrack()->dxy(vertices_->at(0).position());
0697
0698 if (origin > cosmicRejDistance_) {
0699 cosmics.push_back(muons[i]);
0700 METXCosmics += pfc.px();
0701 METYCosmics += pfc.py();
0702 SUMETCosmics += pfc.pt();
0703 }
0704 }
0705 double MET2Cosmics = METXCosmics * METXCosmics + METYCosmics * METYCosmics;
0706
0707 if (SUMETCosmics > (sumet_ - sumetPU_) / eventFactorCosmics_ && MET2Cosmics < METX_ * METX_ + METY_ * METY_)
0708 for (unsigned int i = 0; i < cosmics.size(); ++i) {
0709 maskedIndices_.push_back(cosmics[i]);
0710 pfCosmicsMuonCleanedCandidates_->push_back(cands->at(cosmics[i]));
0711 }
0712
0713
0714 for (unsigned int i = 0; i < muons.size(); ++i) {
0715 if (cleanMismeasured(cands->at(muons[i]), muons[i]))
0716 continue;
0717 cleanPunchThroughAndFakes(cands->at(muons[i]), cands, muons[i]);
0718 }
0719
0720
0721 removeDeadCandidates(cands, maskedIndices_);
0722 }
0723
0724 void PFMuonAlgo::addMissingMuons(edm::Handle<reco::MuonCollection> muons, reco::PFCandidateCollection* cands) {
0725 if (!postCleaning_)
0726 return;
0727
0728 if (pfAddedMuonCandidates_.get())
0729 pfAddedMuonCandidates_->clear();
0730 else
0731 pfAddedMuonCandidates_ = std::make_unique<reco::PFCandidateCollection>();
0732
0733
0734 typedef std::pair<edm::ProductID, unsigned> TrackProdIDKey;
0735 std::vector<TrackProdIDKey> vetoed;
0736 if (vetoes_) {
0737 for (const auto& veto : *vetoes_) {
0738 if (veto.trackRef().isNull())
0739 continue;
0740 vetoed.emplace_back(veto.trackRef().id(), veto.trackRef().key());
0741 }
0742 std::sort(vetoed.begin(), vetoed.end());
0743 }
0744
0745 for (unsigned imu = 0; imu < muons->size(); ++imu) {
0746 reco::MuonRef muonRef(muons, imu);
0747 bool used = false;
0748 bool hadron = false;
0749 for (unsigned i = 0; i < cands->size(); i++) {
0750 const PFCandidate& pfc = cands->at(i);
0751 if (!pfc.trackRef().isNonnull())
0752 continue;
0753 if (pfc.trackRef().isNonnull() && pfc.trackRef() == muonRef->track())
0754 hadron = true;
0755 if (!pfc.muonRef().isNonnull())
0756 continue;
0757
0758 if (pfc.muonRef()->innerTrack() == muonRef->innerTrack())
0759 used = true;
0760 else {
0761
0762
0763 if (pfc.muonRef()->isStandAloneMuon() && muonRef->isStandAloneMuon()) {
0764 double dEta = pfc.muonRef()->standAloneMuon()->eta() - muonRef->standAloneMuon()->eta();
0765 double dPhi = pfc.muonRef()->standAloneMuon()->phi() - muonRef->standAloneMuon()->phi();
0766 double dR = sqrt(dEta * dEta + dPhi * dPhi);
0767 if (dR < 0.005) {
0768 used = true;
0769 }
0770 }
0771 }
0772
0773 if (used)
0774 break;
0775 }
0776
0777 if (!vetoed.empty()) {
0778 TrackProdIDKey trk = std::make_pair(muonRef->track().id(), muonRef->track().key());
0779 auto lower = std::lower_bound(vetoed.begin(), vetoed.end(), trk);
0780 bool inVetoList = (lower != vetoed.end() && *lower == trk);
0781 if (inVetoList)
0782 used = true;
0783 }
0784
0785 if (used || hadron || (!muonRef.isNonnull()))
0786 continue;
0787
0788 TrackMETComparator comparator(METX_, METY_);
0789
0790
0791 std::vector<reco::Muon::MuonTrackTypePair> tracks = muonTracks(muonRef, maxDPtOPt_, true);
0792
0793 if (!tracks.empty()) {
0794
0795 std::vector<reco::Muon::MuonTrackTypePair> tracksThatChangeMET = tracksPointingAtMET(tracks);
0796
0797 if (!tracksThatChangeMET.empty()) {
0798 reco::Muon::MuonTrackTypePair bestTrackType =
0799 *std::min_element(tracksThatChangeMET.begin(), tracksThatChangeMET.end(), comparator);
0800
0801
0802 if ((vertices_->empty()) || bestTrackType.first->dz(vertices_->at(0).position()) < cosmicRejDistance_) {
0803
0804 int charge = bestTrackType.first->charge() > 0 ? 1 : -1;
0805 math::XYZTLorentzVector momentum(bestTrackType.first->px(),
0806 bestTrackType.first->py(),
0807 bestTrackType.first->pz(),
0808 sqrt(bestTrackType.first->p() * bestTrackType.first->p() + 0.1057 * 0.1057));
0809
0810 cands->push_back(PFCandidate(charge, momentum, reco::PFCandidate::mu));
0811
0812 changeTrack(cands->back(), bestTrackType);
0813
0814 if (muonRef->track().isNonnull())
0815 cands->back().setTrackRef(muonRef->track());
0816
0817 cands->back().setMuonRef(muonRef);
0818
0819 pfAddedMuonCandidates_->push_back(cands->back());
0820 }
0821 }
0822 }
0823 }
0824 }
0825
0826 std::pair<double, double> PFMuonAlgo::getMinMaxMET2(const reco::PFCandidate& pfc) {
0827 std::vector<reco::Muon::MuonTrackTypePair> tracks = muonTracks((pfc.muonRef()), maxDPtOPt_, true);
0828
0829 double METXNO = METX_ - pfc.px();
0830 double METYNO = METY_ - pfc.py();
0831 std::vector<double> met2;
0832 for (unsigned int i = 0; i < tracks.size(); ++i) {
0833 met2.push_back(pow(METXNO + tracks.at(i).first->px(), 2) + pow(METYNO + tracks.at(i).first->py(), 2));
0834 }
0835
0836
0837
0838
0839 if (tracks.size() > 1)
0840 return std::make_pair(*std::min_element(met2.begin(), met2.end()), *std::max_element(met2.begin(), met2.end()));
0841 else
0842 return std::make_pair(0, 0);
0843 }
0844
0845 bool PFMuonAlgo::cleanMismeasured(reco::PFCandidate& pfc, unsigned int i) {
0846 using namespace std;
0847 using namespace reco;
0848 bool cleaned = false;
0849
0850
0851 double METNOX = METX_ - pfc.px();
0852 double METNOY = METY_ - pfc.py();
0853 double SUMETNO = sumet_ - pfc.pt();
0854
0855 TrackMETComparator comparator(METNOX, METNOY);
0856
0857 if (pfc.pt() < minPostCleaningPt_)
0858 return false;
0859 std::vector<reco::Muon::MuonTrackTypePair> tracks = muonTracks(pfc.muonRef(), maxDPtOPt_, false);
0860
0861
0862 if (tracks.size() > 1) {
0863
0864 std::vector<reco::Muon::MuonTrackTypePair> tracksThatChangeMET = tracksWithBetterMET(tracks, pfc);
0865
0866 if (!tracksThatChangeMET.empty()) {
0867 reco::Muon::MuonTrackTypePair bestTrackType =
0868 *std::min_element(tracksThatChangeMET.begin(), tracksThatChangeMET.end(), comparator);
0869 changeTrack(pfc, bestTrackType);
0870
0871 pfCleanedTrackerAndGlobalMuonCandidates_->push_back(pfc);
0872
0873 METX_ = METNOX + pfc.px();
0874 METY_ = METNOY + pfc.py();
0875 sumet_ = SUMETNO + pfc.pt();
0876 }
0877 }
0878
0879
0880 if (!(pfc.muonRef()->isGlobalMuon() && pfc.muonRef()->isTrackerMuon())) {
0881
0882 double MET2 = METX_ * METX_ + METY_ * METY_;
0883 double newMET2 = METNOX * METNOX + METNOY * METNOY;
0884 double METSig = sqrt(MET2) / sqrt(sumet_ - sumetPU_);
0885 if (METSig > metSigForRejection_)
0886 if ((newMET2 < MET2 / metFactorRejection_) &&
0887 ((SUMETNO - sumetPU_) / (sumet_ - sumetPU_) < eventFractionRejection_)) {
0888 pfFakeMuonCleanedCandidates_->push_back(pfc);
0889 maskedIndices_.push_back(i);
0890 METX_ = METNOX;
0891 METY_ = METNOY;
0892 sumet_ = SUMETNO;
0893 cleaned = true;
0894 }
0895 }
0896 return cleaned;
0897 }
0898
0899 std::vector<reco::Muon::MuonTrackTypePair> PFMuonAlgo::tracksWithBetterMET(
0900 const std::vector<reco::Muon::MuonTrackTypePair>& tracks, const reco::PFCandidate& pfc) {
0901 std::vector<reco::Muon::MuonTrackTypePair> outputTracks;
0902
0903 double METNOX = METX_ - pfc.px();
0904 double METNOY = METY_ - pfc.py();
0905 double SUMETNO = sumet_ - pfc.pt();
0906 double MET2 = METX_ * METX_ + METY_ * METY_;
0907 double newMET2 = 0.0;
0908 double newSUMET = 0.0;
0909 double METSIG = sqrt(MET2) / sqrt(sumet_ - sumetPU_);
0910
0911 if (METSIG > metSigForCleaning_)
0912 for (unsigned int i = 0; i < tracks.size(); ++i) {
0913
0914 newSUMET = SUMETNO + tracks.at(i).first->pt() - sumetPU_;
0915 newMET2 = pow(METNOX + tracks.at(i).first->px(), 2) + pow(METNOY + tracks.at(i).first->py(), 2);
0916
0917 if (newSUMET / (sumet_ - sumetPU_) > eventFractionCleaning_ && newMET2 < MET2 / metFactorCleaning_)
0918 outputTracks.push_back(tracks.at(i));
0919 }
0920
0921 return outputTracks;
0922 }
0923
0924 std::vector<reco::Muon::MuonTrackTypePair> PFMuonAlgo::tracksPointingAtMET(
0925 const std::vector<reco::Muon::MuonTrackTypePair>& tracks) {
0926 std::vector<reco::Muon::MuonTrackTypePair> outputTracks;
0927
0928 double newMET2 = 0.0;
0929
0930 for (unsigned int i = 0; i < tracks.size(); ++i) {
0931
0932 newMET2 = pow(METX_ + tracks.at(i).first->px(), 2) + pow(METY_ + tracks.at(i).first->py(), 2);
0933
0934 if (newMET2 < (METX_ * METX_ + METY_ * METY_) / metFactorCleaning_)
0935 outputTracks.push_back(tracks.at(i));
0936 }
0937
0938 return outputTracks;
0939 }
0940
0941 void PFMuonAlgo::setInputsForCleaning(reco::VertexCollection const& vertices) { vertices_ = &vertices; }
0942
0943 bool PFMuonAlgo::cleanPunchThroughAndFakes(reco::PFCandidate& pfc,
0944 reco::PFCandidateCollection* cands,
0945 unsigned int imu) {
0946 using namespace reco;
0947
0948 bool cleaned = false;
0949
0950 if (pfc.pt() < minPostCleaningPt_)
0951 return false;
0952
0953 double METXNO = METX_ - pfc.pt();
0954 double METYNO = METY_ - pfc.pt();
0955 double MET2NO = METXNO * METXNO + METYNO * METYNO;
0956 double MET2 = METX_ * METX_ + METY_ * METY_;
0957 bool fake1 = false;
0958
0959 std::pair<double, double> met2 = getMinMaxMET2(pfc);
0960
0961
0962 if (pfc.muonRef()->standAloneMuon().isNonnull())
0963 fake1 = fabs(pfc.eta()) > 2.15 && met2.first < met2.second / 2 && MET2NO < MET2 / metFactorHighEta_ &&
0964 pfc.muonRef()->standAloneMuon()->pt() < pfc.pt() / ptFactorHighEta_;
0965
0966 double factor = std::max(2., 2000. / (sumet_ - pfc.pt() - sumetPU_));
0967 bool fake2 =
0968 (pfc.pt() / (sumet_ - sumetPU_) < 0.25 && MET2NO < MET2 / metFactorFake_ && met2.first < met2.second / factor);
0969
0970 bool punchthrough = pfc.p() > minPunchThroughMomentum_ && pfc.rawHcalEnergy() > minPunchThroughEnergy_ &&
0971 pfc.rawEcalEnergy() + pfc.rawHcalEnergy() > pfc.p() / punchThroughFactor_ &&
0972 !isIsolatedMuon(pfc.muonRef()) && MET2NO < MET2 / punchThroughMETFactor_;
0973
0974 if (fake1 || fake2 || punchthrough) {
0975
0976 const PFCandidate::ElementsInBlocks& eleInBlocks = pfc.elementsInBlocks();
0977 if (!eleInBlocks.empty()) {
0978 PFBlockRef blockRefMuon = eleInBlocks[0].first;
0979 unsigned indexMuon = eleInBlocks[0].second;
0980 if (eleInBlocks.size() > 1)
0981 indexMuon = eleInBlocks[1].second;
0982
0983
0984 double iHad = 1E9;
0985 bool hadron = false;
0986 for (unsigned i = imu + 1; i < cands->size(); ++i) {
0987 const PFCandidate& pfcn = cands->at(i);
0988 const PFCandidate::ElementsInBlocks& ele = pfcn.elementsInBlocks();
0989 if (ele.empty()) {
0990 continue;
0991 }
0992 PFBlockRef blockRefHadron = ele[0].first;
0993 unsigned indexHadron = ele[0].second;
0994
0995 if (blockRefHadron.key() != blockRefMuon.key())
0996 break;
0997
0998 if (indexHadron == indexMuon && pfcn.particleId() == reco::PFCandidate::h0) {
0999 iHad = i;
1000 hadron = true;
1001 }
1002 if (hadron)
1003 break;
1004 }
1005
1006 if (hadron) {
1007 double rescaleFactor = cands->at(iHad).p() / cands->at(imu).p();
1008 METX_ -= cands->at(imu).px() + cands->at(iHad).px();
1009 METY_ -= cands->at(imu).py() + cands->at(iHad).py();
1010 sumet_ -= cands->at(imu).pt();
1011 cands->at(imu).rescaleMomentum(rescaleFactor);
1012 maskedIndices_.push_back(iHad);
1013 pfPunchThroughHadronCleanedCandidates_->push_back(cands->at(iHad));
1014 cands->at(imu).setParticleType(reco::PFCandidate::h);
1015 pfPunchThroughMuonCleanedCandidates_->push_back(cands->at(imu));
1016 METX_ += cands->at(imu).px();
1017 METY_ += cands->at(imu).py();
1018 sumet_ += cands->at(imu).pt();
1019
1020 } else if (fake1 || fake2) {
1021 METX_ -= cands->at(imu).px();
1022 METY_ -= cands->at(imu).py();
1023 sumet_ -= cands->at(imu).pt();
1024 maskedIndices_.push_back(imu);
1025 pfFakeMuonCleanedCandidates_->push_back(cands->at(imu));
1026 cleaned = true;
1027 }
1028 }
1029 }
1030 return cleaned;
1031 }
1032
1033 void PFMuonAlgo::removeDeadCandidates(reco::PFCandidateCollection* obj, const std::vector<unsigned int>& indices) {
1034 size_t N = indices.size();
1035 size_t collSize = obj->size();
1036
1037 for (size_t i = 0; i < N; ++i)
1038 obj->at(indices.at(i)) = obj->at(collSize - i - 1);
1039
1040 obj->resize(collSize - indices.size());
1041 }
1042
1043 void PFMuonAlgo::fillPSetDescription(edm::ParameterSetDescription& iDesc) {
1044
1045 iDesc.add<double>("maxDPtOPt", 1.0);
1046 iDesc.add<std::string>("trackQuality", "highPurity");
1047 iDesc.add<double>("ptErrorScale", 8.0);
1048
1049 iDesc.add<double>("eventFractionForCleaning", 0.5);
1050 iDesc.add<double>("minPtForPostCleaning", 20.0);
1051 iDesc.add<double>("eventFactorForCosmics", 10.0);
1052 iDesc.add<double>("metSignificanceForCleaning", 3.0);
1053 iDesc.add<double>("metSignificanceForRejection", 4.0);
1054 iDesc.add<double>("metFactorForCleaning", 4.0);
1055 iDesc.add<double>("eventFractionForRejection", 0.8);
1056 iDesc.add<double>("metFactorForRejection", 4.0);
1057 iDesc.add<double>("metFactorForHighEta", 25.0);
1058 iDesc.add<double>("ptFactorForHighEta", 2.0);
1059 iDesc.add<double>("metFactorForFakes", 4.0);
1060 iDesc.add<double>("minMomentumForPunchThrough", 100.0);
1061 iDesc.add<double>("minEnergyForPunchThrough", 100.0);
1062 iDesc.add<double>("punchThroughFactor", 3.0);
1063 iDesc.add<double>("punchThroughMETFactor", 4.0);
1064 iDesc.add<double>("cosmicRejectionDistance", 1.0);
1065 }