Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-01-26 04:12:34

0001 from __future__ import print_function
0002 import FWCore.ParameterSet.Config as cms
0003 
0004 from PhysicsTools.PatAlgos.tools.ConfigToolBase import *
0005 import PhysicsTools.PatAlgos.tools.helpers as configtools
0006 from PhysicsTools.PatAlgos.tools.helpers import getPatAlgosToolsTask, addToProcessAndTask
0007 from PhysicsTools.PatAlgos.tools.jetTools import switchJetCollection
0008 import CommonTools.CandAlgos.candPtrProjector_cfi as _mod
0009 from PhysicsTools.PatUtils.tools.pfforTrkMET_cff import *
0010 import JetMETCorrections.Type1MET.BadPFCandidateJetsEEnoiseProducer_cfi as _modbad
0011 import JetMETCorrections.Type1MET.UnclusteredBlobProducer_cfi as _modunc
0012 
0013 def isValidInputTag(input):
0014     input_str = input
0015     if isinstance(input, cms.InputTag):
0016         input_str = input.value()
0017     if input is None or input_str == '""':
0018         return False
0019     else:
0020         return True
0021 
0022 
0023 class RunMETCorrectionsAndUncertainties(ConfigToolBase):
0024 
0025     _label='RunMETCorrectionsAndUncertainties'
0026     _defaultParameters=dicttypes.SortedKeysDict()
0027 
0028     def __init__(self):
0029         ConfigToolBase.__init__(self)
0030         self.addParameter(self._defaultParameters, 'metType', "PF",
0031                           "Type of considered MET (only PF and Puppi supported so far)", Type=str)
0032         self.addParameter(self._defaultParameters, 'correctionLevel', [""],
0033                           "level of correction : available corrections for pfMet are T0, T1, T2, Txy and Smear; irrelevant entry for MVAMet)",
0034                           allowedValues=["T0","T1","T2","Txy","Smear",""])
0035         self.addParameter(self._defaultParameters, 'computeUncertainties', True,
0036                           "enable/disable the uncertainty computation", Type=bool)
0037         self.addParameter(self._defaultParameters, 'produceIntermediateCorrections', False,
0038                           "enable/disable the production of all correction schemes (only for the most common)", Type=bool)
0039         self.addParameter(self._defaultParameters, 'electronCollection', cms.InputTag('selectedPatElectrons'),
0040                           "Input electron collection", Type=cms.InputTag, acceptNoneValue=True)
0041 #  empty default InputTag for photons to avoid double-counting wrt. cleanPatElectrons collection
0042         self.addParameter(self._defaultParameters, 'photonCollection', cms.InputTag('selectedPatPhotons'),
0043                           "Input photon collection", Type=cms.InputTag, acceptNoneValue=True)
0044         self.addParameter(self._defaultParameters, 'muonCollection', cms.InputTag('selectedPatMuons'),
0045                           "Input muon collection", Type=cms.InputTag, acceptNoneValue=True)
0046         self.addParameter(self._defaultParameters, 'tauCollection', cms.InputTag('selectedPatTaus'),
0047                           "Input tau collection", Type=cms.InputTag, acceptNoneValue=True)
0048         self.addParameter(self._defaultParameters, 'jetCollectionUnskimmed', cms.InputTag('patJets'),
0049                           "Input unskimmed jet collection for T1 MET computation", Type=cms.InputTag, acceptNoneValue=True)
0050         self.addParameter(self._defaultParameters, 'pfCandCollection', cms.InputTag('particleFlow'),
0051                           "pf Candidate collection", Type=cms.InputTag, acceptNoneValue=True)
0052         self.addParameter(self._defaultParameters, 'autoJetCleaning', 'LepClean',
0053                           "Enable the jet cleaning for the uncertainty computation: Full for tau/photons/jet cleaning, Partial for jet cleaning, LepClean for jet cleaning with muon and electrons only, None or Manual for no cleaning", Type=str)
0054         self.addParameter(self._defaultParameters, 'jetFlavor', 'AK4PFchs',
0055                           "Use AK4PF/AK4PFchs for PFJets,AK4Calo for CaloJets", Type=str)
0056         self.addParameter(self._defaultParameters, 'jetCorrectionType', 'L1L2L3-L1',
0057                           "Use L1L2L3-L1 for the standard L1 removal / L1L2L3-RC for the random-cone correction", Type=str)
0058 
0059         self.addParameter(self._defaultParameters, 'jetCorLabelUpToL3', "ak4PFCHSL1FastL2L3Corrector", "Use ak4PFL1FastL2L3Corrector (ak4PFCHSL1FastL2L3Corrector) for PFJets with (without) charged hadron subtraction, ak4CaloL1FastL2L3Corrector for CaloJets", Type=str)
0060         self.addParameter(self._defaultParameters, 'jetCorLabelL3Res', "ak4PFCHSL1FastL2L3ResidualCorrector", "Use ak4PFL1FastL2L3ResidualCorrector (ak4PFCHSL1FastL2L3ResidualCorrector) for PFJets with (without) charged hadron subtraction, ak4CaloL1FastL2L3ResidualCorrector for CaloJets", Type=str)
0061 
0062 # the file is used only for local running
0063         self.addParameter(self._defaultParameters, 'jecUncertaintyFile', '',
0064                           "Extra JES uncertainty file", Type=str)
0065         self.addParameter(self._defaultParameters, 'jecUncertaintyTag', None,
0066                           "JES uncertainty Tag", acceptNoneValue=True) # Type=str,
0067 
0068         self.addParameter(self._defaultParameters, 'mvaMetLeptons',["Electrons","Muons"],
0069                           "Leptons to be used for recoil computation in the MVA MET, available values are: Electrons, Muons, Taus, Photons", allowedValues=["Electrons","Muons","Taus","Photons",""])
0070 
0071         self.addParameter(self._defaultParameters, 'addToPatDefaultSequence', False,
0072                           "Flag to enable/disable that metUncertaintySequence is inserted into patDefaultSequence", Type=bool)
0073         self.addParameter(self._defaultParameters, 'manualJetConfig', False,
0074                   "Enable jet configuration options", Type=bool)
0075         self.addParameter(self._defaultParameters, 'jetSelection', 'pt>15 && abs(eta)<9.9',
0076                           "Advanced jet kinematic selection", Type=str)
0077         self.addParameter(self._defaultParameters, 'recoMetFromPFCs', False,
0078                   "Recompute the MET from scratch using the pfCandidate collection", Type=bool)
0079         self.addParameter(self._defaultParameters, 'reapplyJEC', True,
0080                   "Flag to enable/disable JEC update", Type=bool)
0081         self.addParameter(self._defaultParameters, 'reclusterJets', False,
0082                   "Flag to enable/disable the jet reclustering", Type=bool)
0083         self.addParameter(self._defaultParameters, 'computeMETSignificance', True,
0084                   "Flag to enable/disable the MET significance computation", Type=bool)
0085         self.addParameter(self._defaultParameters, 'CHS', False,
0086                   "Flag to enable/disable the CHS jets", Type=bool)
0087         self.addParameter(self._defaultParameters, 'runOnData', False,
0088                           "Switch for data/MC processing", Type=bool)
0089         self.addParameter(self._defaultParameters, 'onMiniAOD', False,
0090                           "Switch on miniAOD configuration", Type=bool)
0091         self.addParameter(self._defaultParameters, 'postfix', '',
0092                           "Technical parameter to identify the resulting sequence and its modules (allows multiple calls in a job)", Type=str)
0093         self.addParameter(self._defaultParameters,'fixEE2017', False,
0094                           "Exclude jets and PF candidates with EE noise characteristics (fix for 2017 run)", Type=bool)
0095         self.addParameter(self._defaultParameters,'fixEE2017Params', {'userawPt': True, 'ptThreshold': 50.0, 'minEtaThreshold': 2.65, 'maxEtaThreshold': 3.139},
0096                           "Parameters dict for fixEE2017: userawPt, ptThreshold, minEtaThreshold, maxEtaThreshold", Type=dict)
0097         self.addParameter(self._defaultParameters, 'extractDeepMETs', False,
0098                           "Extract DeepMETs from miniAOD, instead of recomputing them.", Type=bool)
0099 
0100         #private parameters
0101         self.addParameter(self._defaultParameters, 'Puppi', False,
0102                           "Puppi algorithm (private)", Type=bool)
0103 
0104 
0105 
0106         self._parameters = copy.deepcopy(self._defaultParameters)
0107         self._comment = ""
0108 
0109     def getDefaultParameters(self):
0110         return self._defaultParameters
0111 
0112 #=========================================================================================
0113     def __call__(self, process,
0114                  metType                 =None,
0115                  correctionLevel         =None,
0116                  computeUncertainties    =None,
0117                  produceIntermediateCorrections = None,
0118                  electronCollection      =None,
0119                  photonCollection        =None,
0120                  muonCollection          =None,
0121                  tauCollection           =None,
0122                  jetCollectionUnskimmed  =None,
0123                  pfCandCollection        =None,
0124                  autoJetCleaning         =None,
0125                  jetFlavor               =None,
0126                  jetCorr                 =None,
0127                  jetCorLabelUpToL3       =None,
0128                  jetCorLabelL3Res        =None,
0129                  jecUncertaintyFile      =None,
0130                  jecUncertaintyTag       =None,
0131                  mvaMetLeptons           =None,
0132                  addToPatDefaultSequence =None,
0133                  manualJetConfig         =None,
0134                  jetSelection            =None,
0135                  recoMetFromPFCs         =None,
0136                  reapplyJEC              =None,
0137                  reclusterJets           =None,
0138                  computeMETSignificance  =None,
0139                  CHS                     =None,
0140                  runOnData               =None,
0141                  onMiniAOD               =None,
0142                  fixEE2017               =None,
0143                  fixEE2017Params         =None,
0144                  extractDeepMETs         =None,
0145                  postfix                 =None):
0146         electronCollection = self.initializeInputTag(electronCollection, 'electronCollection')
0147         photonCollection = self.initializeInputTag(photonCollection, 'photonCollection')
0148         muonCollection = self.initializeInputTag(muonCollection, 'muonCollection')
0149         tauCollection = self.initializeInputTag(tauCollection, 'tauCollection')
0150         jetCollectionUnskimmed = self.initializeInputTag(jetCollectionUnskimmed, 'jetCollectionUnskimmed')
0151         pfCandCollection = self.initializeInputTag(pfCandCollection, 'pfCandCollection')
0152         if metType is None :
0153             metType =  self._defaultParameters['metType'].value
0154         if correctionLevel is None :
0155             correctionLevel = self._defaultParameters['correctionLevel'].value
0156         if computeUncertainties is None :
0157             computeUncertainties = self._defaultParameters['computeUncertainties'].value
0158         if produceIntermediateCorrections is None :
0159             produceIntermediateCorrections = self._defaultParameters['produceIntermediateCorrections'].value
0160         if electronCollection is None :
0161             electronCollection = self._defaultParameters['electronCollection'].value
0162         if photonCollection is None :
0163             photonCollection = self._defaultParameters['photonCollection'].value
0164         if muonCollection is None :
0165             muonCollection = self._defaultParameters['muonCollection'].value
0166         if tauCollection is None :
0167             tauCollection = self._defaultParameters['tauCollection'].value
0168         if jetCollectionUnskimmed is None :
0169             jetCollectionUnskimmed = self._defaultParameters['jetCollectionUnskimmed'].value
0170         if pfCandCollection is None :
0171             pfCandCollection = self._defaultParameters['pfCandCollection'].value
0172         if autoJetCleaning is None :
0173             autoJetCleaning = self._defaultParameters['autoJetCleaning'].value
0174         if jetFlavor is None :
0175             jetFlavor = self._defaultParameters['jetFlavor'].value
0176         if jetCorr is None :
0177             jetCorr = self._defaultParameters['jetCorrectionType'].value
0178         if jetCorLabelUpToL3  is None:
0179             jetCorLabelUpToL3 = self._defaultParameters['jetCorLabelUpToL3'].value
0180         if jetCorLabelL3Res   is None:
0181             jetCorLabelL3Res = self._defaultParameters['jetCorLabelL3Res'].value
0182         if jecUncertaintyFile is None:
0183             jecUncertaintyFile = self._defaultParameters['jecUncertaintyFile'].value
0184         if jecUncertaintyTag  is None:
0185             jecUncertaintyTag = self._defaultParameters['jecUncertaintyTag'].value
0186 
0187         if mvaMetLeptons is None:
0188             mvaMetLeptons = self._defaultParameters['mvaMetLeptons'].value
0189 
0190         if addToPatDefaultSequence is None :
0191             addToPatDefaultSequence = self._defaultParameters['addToPatDefaultSequence'].value
0192         if manualJetConfig is None :
0193             manualJetConfig =  self._defaultParameters['manualJetConfig'].value
0194         if jetSelection is None :
0195             jetSelection = self._defaultParameters['jetSelection'].value
0196         recoMetFromPFCsIsNone = (recoMetFromPFCs is None)
0197         if recoMetFromPFCs is None :
0198             recoMetFromPFCs =  self._defaultParameters['recoMetFromPFCs'].value
0199         if reapplyJEC is None :
0200             reapplyJEC = self._defaultParameters['reapplyJEC'].value
0201         reclusterJetsIsNone = (reclusterJets is None)
0202         if reclusterJets is None :
0203             reclusterJets = self._defaultParameters['reclusterJets'].value
0204         if computeMETSignificance is None :
0205             computeMETSignificance = self._defaultParameters['computeMETSignificance'].value
0206         if CHS is None :
0207             CHS = self._defaultParameters['CHS'].value
0208         if runOnData is None :
0209             runOnData = self._defaultParameters['runOnData'].value
0210         if onMiniAOD is None :
0211             onMiniAOD = self._defaultParameters['onMiniAOD'].value
0212         if postfix is None :
0213             postfix = self._defaultParameters['postfix'].value
0214         if fixEE2017 is None :
0215             fixEE2017 = self._defaultParameters['fixEE2017'].value
0216         if fixEE2017Params is None :
0217             fixEE2017Params = self._defaultParameters['fixEE2017Params'].value
0218         if extractDeepMETs is None :
0219             extractDeepMETs = self._defaultParameters['extractDeepMETs'].value
0220 
0221         self.setParameter('metType',metType),
0222         self.setParameter('correctionLevel',correctionLevel),
0223         self.setParameter('computeUncertainties',computeUncertainties),
0224         self.setParameter('produceIntermediateCorrections',produceIntermediateCorrections),
0225         self.setParameter('electronCollection',electronCollection),
0226         self.setParameter('photonCollection',photonCollection),
0227         self.setParameter('muonCollection',muonCollection),
0228         self.setParameter('tauCollection',tauCollection),
0229         self.setParameter('jetCollectionUnskimmed',jetCollectionUnskimmed),
0230         self.setParameter('pfCandCollection',pfCandCollection),
0231 
0232         self.setParameter('autoJetCleaning',autoJetCleaning),
0233         self.setParameter('jetFlavor',jetFlavor),
0234 
0235         #optional
0236         self.setParameter('jecUncertaintyFile',jecUncertaintyFile),
0237         self.setParameter('jecUncertaintyTag',jecUncertaintyTag),
0238 
0239         self.setParameter('mvaMetLeptons',mvaMetLeptons),
0240 
0241         self.setParameter('addToPatDefaultSequence',addToPatDefaultSequence),
0242         self.setParameter('jetSelection',jetSelection),
0243         self.setParameter('recoMetFromPFCs',recoMetFromPFCs),
0244         self.setParameter('reclusterJets',reclusterJets),
0245         self.setParameter('computeMETSignificance',computeMETSignificance),
0246         self.setParameter('reapplyJEC',reapplyJEC),
0247         self.setParameter('CHS',CHS),
0248         self.setParameter('runOnData',runOnData),
0249         self.setParameter('onMiniAOD',onMiniAOD),
0250         self.setParameter('postfix',postfix),
0251         self.setParameter('fixEE2017',fixEE2017),
0252         self.setParameter('fixEE2017Params',fixEE2017Params),
0253         self.setParameter('extractDeepMETs',extractDeepMETs),
0254 
0255         #if mva/puppi MET, autoswitch to std jets
0256         if metType == "MVA" or metType == "Puppi":
0257             self.setParameter('CHS',False),
0258 
0259         #enabling puppi flag
0260         self.setParameter('Puppi',self._defaultParameters['Puppi'].value)
0261         if metType == "Puppi":
0262             self.setParameter('metType',"PF")
0263             self.setParameter('Puppi',True)
0264 
0265         #jet energy scale uncertainty needs
0266         if manualJetConfig:
0267             self.setParameter('CHS',CHS)
0268             self.setParameter('jetCorLabelUpToL3',jetCorLabelUpToL3)
0269             self.setParameter('jetCorLabelL3Res',jetCorLabelL3Res)
0270             self.setParameter('reclusterJets',reclusterJets)
0271         else:
0272              #internal jet configuration
0273             self.jetConfiguration()
0274 
0275         #defaults for 2017 fix
0276         #(don't need to recluster, just uses a subset of the input jet coll)
0277         if fixEE2017:
0278             if recoMetFromPFCsIsNone: self.setParameter('recoMetFromPFCs',True)
0279             if reclusterJetsIsNone: self.setParameter('reclusterJets',False)
0280 
0281         #met reprocessing and jet reclustering
0282         if recoMetFromPFCs and reclusterJetsIsNone and not fixEE2017:
0283             self.setParameter('reclusterJets',True)
0284 
0285         self.apply(process)
0286 
0287 
0288     def toolCode(self, process):
0289         metType                 = self._parameters['metType'].value
0290         correctionLevel         = self._parameters['correctionLevel'].value
0291         computeUncertainties    = self._parameters['computeUncertainties'].value
0292         produceIntermediateCorrections = self._parameters['produceIntermediateCorrections'].value
0293         electronCollection      = self._parameters['electronCollection'].value
0294         photonCollection        = self._parameters['photonCollection'].value
0295         muonCollection          = self._parameters['muonCollection'].value
0296         tauCollection           = self._parameters['tauCollection'].value
0297         jetCollectionUnskimmed  = self._parameters['jetCollectionUnskimmed'].value
0298         pfCandCollection        = self._parameters['pfCandCollection'].value
0299         autoJetCleaning         = self._parameters['autoJetCleaning'].value
0300         jetFlavor               = self._parameters['jetFlavor'].value
0301         jetCorLabelUpToL3       = self._parameters['jetCorLabelUpToL3'].value
0302         jetCorLabelL3Res        = self._parameters['jetCorLabelL3Res'].value
0303         jecUncertaintyFile      = self._parameters['jecUncertaintyFile'].value
0304         jecUncertaintyTag       = self._parameters['jecUncertaintyTag'].value
0305 
0306         mvaMetLeptons           = self._parameters['mvaMetLeptons'].value
0307         addToPatDefaultSequence = self._parameters['addToPatDefaultSequence'].value
0308         jetSelection            = self._parameters['jetSelection'].value
0309         recoMetFromPFCs         = self._parameters['recoMetFromPFCs'].value
0310         reapplyJEC              = self._parameters['reapplyJEC'].value
0311         reclusterJets           = self._parameters['reclusterJets'].value
0312         computeMETSignificance  = self._parameters['computeMETSignificance'].value
0313         onMiniAOD               = self._parameters['onMiniAOD'].value
0314         postfix                 = self._parameters['postfix'].value
0315         fixEE2017               = self._parameters['fixEE2017'].value
0316         fixEE2017Params         = self._parameters['fixEE2017Params'].value
0317         extractDeepMETs         = self._parameters['extractDeepMETs'].value
0318 
0319         #prepare jet configuration
0320         jetUncInfos = { "jCorrPayload":jetFlavor, "jCorLabelUpToL3":jetCorLabelUpToL3,
0321                         "jCorLabelL3Res":jetCorLabelL3Res, "jecUncFile":jecUncertaintyFile,
0322                         "jecUncTag":"Uncertainty" }
0323 
0324         if (jecUncertaintyFile!="" and jecUncertaintyTag==None):
0325             jetUncInfos[ "jecUncTag" ] = ""
0326         elif(jecUncertaintyTag!=None):
0327             jetUncInfos[ "jecUncTag" ] = jecUncertaintyTag
0328 
0329         patMetModuleSequence = cms.Sequence()
0330 
0331         # 2017 EE fix will modify pf cand and jet collections used downstream
0332         if fixEE2017:
0333             pfCandCollection, jetCollectionUnskimmed = self.runFixEE2017(process,
0334                 fixEE2017Params,
0335                 jetCollectionUnskimmed,
0336                 pfCandCollection,
0337                 [electronCollection,muonCollection,tauCollection,photonCollection],
0338                 patMetModuleSequence,
0339                 postfix,
0340             )
0341 
0342         # recompute the MET (and thus the jets as well for correction) from scratch
0343         if recoMetFromPFCs:
0344             self.recomputeRawMetFromPfcs(process,
0345                                          pfCandCollection,
0346                                          onMiniAOD,
0347                                          patMetModuleSequence,
0348                                          postfix)
0349 
0350         elif onMiniAOD: #raw MET extraction if running on miniAODs
0351             self.extractMET(process, "raw", patMetModuleSequence, postfix)
0352 
0353         #jet AK4 reclustering if needed for JECs
0354 
0355         if reclusterJets:
0356             jetCollectionUnskimmed = self.ak4JetReclustering(process, pfCandCollection,
0357                                                              patMetModuleSequence, postfix)
0358 
0359         # or reapplication of jecs
0360         if onMiniAOD:
0361             if not reclusterJets and reapplyJEC:
0362                 jetCollectionUnskimmed = self.updateJECs(process, jetCollectionUnskimmed, patMetModuleSequence, postfix)
0363 
0364 
0365         #getting the jet collection that will be used for corrections
0366         #and uncertainty computation
0367         jetCollection = self.getJetCollectionForCorsAndUncs(process,
0368                                                             jetCollectionUnskimmed,
0369                                                             jetSelection,
0370                                                             autoJetCleaning,
0371                                                             patMetModuleSequence,
0372                                                             postfix)
0373 
0374         #pre-preparation to run over miniAOD
0375         if onMiniAOD:
0376             self.miniAODConfigurationPre(process, patMetModuleSequence, pfCandCollection, postfix)
0377         else:
0378             from PhysicsTools.PatUtils.pfeGammaToCandidate_cfi import pfeGammaToCandidate
0379             task = getPatAlgosToolsTask(process)
0380             addToProcessAndTask("pfeGammaToCandidate", pfeGammaToCandidate.clone(
0381                                   electrons = copy.copy(electronCollection),
0382                                   photons = copy.copy(photonCollection)),
0383                                 process, task)
0384             if hasattr(process,"patElectrons") and process.patElectrons.electronSource == cms.InputTag("reducedEgamma","reducedGedGsfElectrons"):
0385                 process.pfeGammaToCandidate.electron2pf = "reducedEgamma:reducedGsfElectronPfCandMap"
0386             if hasattr(process,"patPhotons") and process.patPhotons.photonSource == cms.InputTag("reducedEgamma","reducedGedPhotons"):
0387                 process.pfeGammaToCandidate.photon2pf = "reducedEgamma:reducedPhotonPfCandMap"
0388 
0389         #default MET production
0390         self.produceMET(process, metType,patMetModuleSequence, postfix)
0391 
0392 
0393 
0394         #preparation to run over miniAOD (met reproduction)
0395         if onMiniAOD:
0396             self.miniAODConfiguration(process,
0397                                       pfCandCollection,
0398                                       jetCollection,
0399                                       patMetModuleSequence,
0400                                       postfix
0401                                       )
0402 
0403         # correct the MET
0404         patMetCorrectionSequence, metModName = self.getCorrectedMET(process, metType, correctionLevel,
0405                                                                     produceIntermediateCorrections,
0406                                                                     jetCollection,
0407                                                                     patMetModuleSequence, postfix )
0408 
0409         #fix the default jets for the type1 computation to those used to compute the uncertainties
0410         #in order to be consistent with what is done in the correction and uncertainty step
0411         #particularly true for miniAODs
0412         if "T1" in metModName:
0413             getattr(process,"patPFMetT1T2Corr"+postfix).src = jetCollection
0414             getattr(process,"patPFMetT2Corr"+postfix).src = jetCollection
0415             #ZD:puppi currently doesn't have the L1 corrections in the GT
0416             if self._parameters["Puppi"].value:
0417                 getattr(process,"patPFMetT1T2Corr"+postfix).offsetCorrLabel = cms.InputTag("")
0418                 getattr(process,"patPFMetT2Corr"+postfix).offsetCorrLabel = cms.InputTag("")
0419         if "Smear" in metModName:
0420             getattr(process,"patSmearedJets"+postfix).src = jetCollection
0421             if self._parameters["Puppi"].value:
0422                 getattr(process,"patPFMetT1T2SmearCorr"+postfix).offsetCorrLabel = cms.InputTag("")
0423 
0424 
0425         #compute the uncertainty on the MET
0426         patMetUncertaintySequence = cms.Sequence()
0427         tmpUncSequence =cms.Sequence()
0428         if not hasattr(process, "patMetUncertaintySequence"+postfix):
0429             if self._parameters["Puppi"].value:
0430                 patMetUncertaintySequence=cms.Sequence(getattr(process, "ak4PFPuppiL1FastL2L3CorrectorChain")+getattr(process, "ak4PFPuppiL1FastL2L3ResidualCorrectorChain"))
0431             else:
0432                 patMetUncertaintySequence=cms.Sequence(getattr(process, "ak4PFCHSL1FastL2L3CorrectorChain")+getattr(process, "ak4PFCHSL1FastL2L3ResidualCorrectorChain"))
0433         patShiftedModuleSequence = cms.Sequence()
0434         if computeUncertainties:
0435             tmpUncSequence,patShiftedModuleSequence =  self.getMETUncertainties(process, metType, metModName,
0436                                                                   electronCollection,
0437                                                                   photonCollection,
0438                                                                   muonCollection,
0439                                                                   tauCollection,
0440                                                                   pfCandCollection,
0441                                                                   jetCollection,
0442                                                                   jetUncInfos,
0443                                                                   postfix)
0444 
0445         if not hasattr(process, "patMetCorrectionSequence"+postfix):
0446             setattr(process, "patMetCorrectionSequence"+postfix, patMetCorrectionSequence)
0447         if not hasattr(process, "patMetUncertaintySequence"+postfix):
0448             patMetUncertaintySequence += tmpUncSequence
0449             setattr(process, "patMetUncertaintySequence"+postfix, patMetUncertaintySequence)
0450         else:
0451             if not len(configtools.listModules(tmpUncSequence))==0:
0452                 setattr(process, metModName+"patMetUncertaintySequence"+postfix , tmpUncSequence)
0453                 tmpSeq = getattr(process, "patMetUncertaintySequence"+postfix)
0454                 tmpSeq += getattr(process, metModName+"patMetUncertaintySequence"+postfix)
0455 
0456         if not hasattr(process, "patShiftedModuleSequence"+postfix):
0457             setattr(process, "patShiftedModuleSequence"+postfix, patShiftedModuleSequence)
0458         else:
0459             if not len(configtools.listModules(patShiftedModuleSequence))==0:
0460                 setattr(process, metModName+"patShiftedModuleSequence"+postfix , patShiftedModuleSequence)
0461                 tmpSeq = getattr(process, "patShiftedModuleSequence"+postfix)
0462                 tmpSeq += getattr(process, metModName+"patShiftedModuleSequence"+postfix)
0463 
0464         if not hasattr(process, "patMetModuleSequence"+postfix):
0465             setattr(process, "patMetModuleSequence"+postfix, patMetModuleSequence)
0466 
0467         #prepare and fill the final sequence containing all the sub-sequence
0468         fullPatMetSequence = cms.Sequence()
0469         fullPatMetSequence += getattr(process, "patMetModuleSequence"+postfix)
0470         fullPatMetSequence += getattr(process, "patMetCorrectionSequence"+postfix)
0471         fullPatMetSequence += getattr(process, "patMetUncertaintySequence"+postfix)
0472         fullPatMetSequence += getattr(process, "patShiftedModuleSequence"+postfix)
0473 
0474         #adding the slimmed MET
0475         if hasattr(process, "patCaloMet"):
0476             fullPatMetSequence +=getattr(process, "patCaloMet")
0477         # include deepMETsResolutionTune and deepMETsResponseTune into fullPatMetSequence
0478         if hasattr(process, "deepMETsResolutionTune"):
0479             fullPatMetSequence +=getattr(process, "deepMETsResolutionTune")
0480         if hasattr(process, "deepMETsResponseTune"):
0481             fullPatMetSequence += getattr(process, "deepMETsResponseTune")
0482         if hasattr(process, "slimmedMETs"+postfix):
0483             fullPatMetSequence +=getattr(process, "slimmedMETs"+postfix)
0484 
0485         setattr(process,"fullPatMetSequence"+postfix,fullPatMetSequence)
0486 
0487         #removing the non used jet selectors
0488         configtools.removeIfInSequence(process, "selectedPatJetsForMetT1T2Corr", "patPFMetT1T2CorrSequence", postfix )
0489 
0490         #last modification for miniAODs
0491         self.miniAODConfigurationPost(process, postfix)
0492 
0493         # insert the fullPatMetSequence into patDefaultSequence if needed
0494         if addToPatDefaultSequence:
0495             if not hasattr(process, "patDefaultSequence"):
0496                 raise ValueError("PAT default sequence is not defined !!")
0497             process.patDefaultSequence += getattr(process, "fullPatMetSequence"+postfix)
0498 
0499 #====================================================================================================
0500     def produceMET(self, process,  metType, metModuleSequence, postfix):
0501 
0502         task = getPatAlgosToolsTask(process)
0503 
0504         if metType == "PF" and not hasattr(process, 'pat'+metType+'Met'):
0505             process.load("PhysicsTools.PatUtils.patPFMETCorrections_cff")
0506             task.add(process.producePatPFMETCorrectionsTask)
0507             task.add(process.patPFMetT2SmearCorrTask)
0508             task.add(process.patPFMetTxyCorrTask)
0509             task.add(process.jetCorrectorsTask)
0510 
0511         _myPatMet = 'pat'+metType+'Met'+postfix
0512         if postfix != "" and metType == "PF" and not hasattr(process, _myPatMet):
0513             noClonesTmp = [ "particleFlowDisplacedVertex", "pfCandidateToVertexAssociation" ]
0514             configtools.cloneProcessingSnippet(process, getattr(process,"producePatPFMETCorrections"), postfix, noClones = noClonesTmp, addToTask = True)
0515             addToProcessAndTask(_myPatMet,  getattr(process,'patPFMet').clone(), process, task)
0516             getattr(process, _myPatMet).metSource = cms.InputTag("pfMet"+postfix)
0517             getattr(process, _myPatMet).srcPFCands = copy.copy(self.getvalue("pfCandCollection"))
0518             if self.getvalue("Puppi"):
0519                 getattr(process, _myPatMet).srcWeights = "puppiNoLep"
0520         if metType == "PF":
0521             getattr(process, _myPatMet).srcLeptons = \
0522               cms.VInputTag(copy.copy(self.getvalue("electronCollection")) if self.getvalue("onMiniAOD") else
0523                               cms.InputTag("pfeGammaToCandidate","electrons"),
0524                             copy.copy(self.getvalue("muonCollection")),
0525                             copy.copy(self.getvalue("photonCollection")) if self.getvalue("onMiniAOD") else
0526                               cms.InputTag("pfeGammaToCandidate","photons"))
0527 
0528         if self.getvalue("runOnData"):
0529             getattr(process, _myPatMet).addGenMET  = False
0530 
0531 
0532         #MM: FIXME MVA
0533         if metType == "MVA": # and not hasattr(process, 'pat'+metType+'Met'):
0534            # process.load("PhysicsTools.PatUtils.patPFMETCorrections_cff")
0535             mvaMetProducer = self.createMVAMETModule(process)
0536             addToProcessAndTask('pfMVAMet'+postfix, mvaMetProducer, process, task)
0537             addToProcessAndTask(_myPatMet,
0538                                 getattr(process,'patPFMet' ).clone(metSource = cms.InputTag('pfMVAMet')),
0539                                 process, task)
0540 
0541         metModuleSequence += getattr(process, _myPatMet )
0542 
0543 #====================================================================================================
0544     def getCorrectedMET(self, process, metType, correctionLevel,produceIntermediateCorrections,
0545                         jetCollection, metModuleSequence, postfix ):
0546 
0547         # default outputs
0548         patMetCorrectionSequence = cms.Sequence()
0549         metModName = "pat"+metType+"Met"+postfix
0550 
0551         if metType == "MVA": #corrections are irrelevant for the MVA MET (except jet smearing?)
0552             return patMetCorrectionSequence, metModName
0553 
0554         corNames = { #not really needed but in case we have changes in the future....
0555             "T0":"T0pc",
0556             "T1":"T1",
0557             "T2":"T2",
0558             "Txy":"Txy",
0559             "Smear":"Smear",
0560             }
0561 
0562 
0563         #if empty correction level, no need to try something
0564         for cor in correctionLevel:
0565             if cor not in corNames.keys():
0566                 if cor != "":
0567                     print("ERROR : ",cor," is not a proper MET correction name! aborting the MET correction production")
0568                 return patMetCorrectionSequence, metModName
0569 
0570         corModNames = {
0571             "T0": "patPFMetT0CorrSequence"+postfix,
0572             "T1": "patPFMetT1T2CorrSequence"+postfix,
0573             "T2": "patPFMetT2CorrSequence"+postfix,
0574             "Txy": "patPFMetTxyCorrSequence"+postfix,
0575             "Smear": "patPFMetSmearCorrSequence"+postfix,
0576             "T2Smear": "patPFMetT2SmearCorrSequence"+postfix
0577             }
0578 
0579         if postfix != "":
0580             noClonesTmp = [ "particleFlowDisplacedVertex", "pfCandidateToVertexAssociation" ]
0581             if not hasattr(process, "patPFMetT0CorrSequence"+postfix):
0582                 configtools.cloneProcessingSnippet(process, getattr(process,"patPFMetT0CorrSequence"), postfix, noClones = noClonesTmp, addToTask = True)
0583             if not hasattr(process, "patPFMetT1T2CorrSequence"+postfix):
0584                 configtools.cloneProcessingSnippet(process, getattr(process,"patPFMetT1T2CorrSequence"), postfix, addToTask = True)
0585             if not hasattr(process, "patPFMetT2CorrSequence"+postfix):
0586                 configtools.cloneProcessingSnippet(process, getattr(process,"patPFMetT2CorrSequence"), postfix, addToTask = True)
0587             if not hasattr(process, "patPFMetTxyCorrSequence"+postfix):
0588                 configtools.cloneProcessingSnippet(process, getattr(process,"patPFMetTxyCorrSequence"), postfix, addToTask = True)
0589             if not hasattr(process, "patPFMetSmearCorrSequence"+postfix):
0590                 configtools.cloneProcessingSnippet(process, getattr(process,"patPFMetSmearCorrSequence"), postfix, addToTask = True)
0591             if not hasattr(process, "patPFMetT2SmearCorrSequence"+postfix):
0592                 configtools.cloneProcessingSnippet(process, getattr(process,"patPFMetT2SmearCorrSequence"), postfix, addToTask = True)
0593 
0594         corModules = {}
0595         for mod in corModNames.keys():
0596             corModules[mod] = getattr(process, corModNames[mod] )
0597 
0598         corTags = {
0599             #"T0":cms.InputTag('patPFMetT0Corr'+postfix),
0600             #"T1":cms.InputTag('patPFMetT1T2Corr'+postfix, 'type1'),
0601             #"T2":cms.InputTag('patPFMetT2Corr'+postfix,   'type2'),
0602             #"Txy": cms.InputTag('patPFMetTxyCorr'+postfix),
0603             #"Smear":cms.InputTag('patPFMetT1T2SmearCorr'+postfix, 'type1'),
0604             #"T2Smear":cms.InputTag('patPFMetT2SmearCorr'+postfix, 'type2')
0605             "T0":['patPFMetT0Corr'+postfix,''],
0606             "T1":['patPFMetT1T2Corr'+postfix, 'type1'],
0607             "T2":['patPFMetT2Corr'+postfix,   'type2'],
0608             "Txy": ['patPFMetTxyCorr'+postfix,''],
0609             "Smear":['patPFMetT1T2SmearCorr'+postfix, 'type1'],
0610             "T2Smear":['patPFMetT2SmearCorr'+postfix, 'type2']
0611             }
0612 
0613         corScheme=""
0614         corrections = []
0615         correctionSequence = []
0616         for cor in correctionLevel:
0617             corScheme += corNames[cor]
0618             corrections.append(cms.InputTag(corTags[cor][0],corTags[cor][1]))
0619             correctionSequence.append(corModules[cor])
0620 
0621         #T2 and smearing corModuleTag switch, specific case
0622         if "T2" in correctionLevel and "Smear" in correctionLevel:
0623             corrections.append(cms.InputTag(corTags["T2Smear"][0],corTags["T2Smear"][1]))
0624             correctionSequence.append(corModules["T2Smear"])
0625 
0626         #if both are here, consider smeared corJets for the full T1+Smear correction
0627         if "T1" in correctionLevel and "Smear" in correctionLevel:
0628             corrections.remove(cms.InputTag(corTags["T1"][0],corTags["T1"][1]))
0629 
0630         #Txy parameter tuning
0631         if "Txy" in correctionLevel:
0632             self.tuneTxyParameters(process, corScheme, postfix)
0633             getattr(process, "patPFMetTxyCorr"+postfix).srcPFlow = self._parameters["pfCandCollection"].value
0634             if self.getvalue("Puppi"):
0635                 getattr(process, "patPFMetTxyCorr"+postfix).srcWeights = "puppiNoLep"
0636 
0637 
0638         #Enable MET significance if the type1 MET is computed
0639         if "T1" in correctionLevel:
0640             _myPatMet = "pat"+metType+"Met"+postfix
0641             getattr(process, _myPatMet).computeMETSignificance = cms.bool(self.getvalue("computeMETSignificance"))
0642             getattr(process, _myPatMet).srcPFCands = copy.copy(self.getvalue("pfCandCollection"))
0643             getattr(process, _myPatMet).srcLeptons = \
0644               cms.VInputTag(copy.copy(self.getvalue("electronCollection")) if self.getvalue("onMiniAOD") else
0645                               cms.InputTag("pfeGammaToCandidate","electrons"),
0646                             copy.copy(self.getvalue("muonCollection")),
0647                             copy.copy(self.getvalue("photonCollection")) if self.getvalue("onMiniAOD") else
0648                               cms.InputTag("pfeGammaToCandidate","photons"))
0649             if postfix=="NoHF":
0650                 getattr(process, _myPatMet).computeMETSignificance = cms.bool(False)
0651             if self.getvalue("runOnData"):
0652                 from RecoMET.METProducers.METSignificanceParams_cfi import METSignificanceParams_Data
0653                 getattr(process, _myPatMet).parameters = METSignificanceParams_Data
0654             if self.getvalue("Puppi"):
0655                 getattr(process, _myPatMet).srcWeights = "puppiNoLep"
0656                 getattr(process, _myPatMet).srcJets = cms.InputTag('cleanedPatJets'+postfix)
0657                 getattr(process, _myPatMet).srcJetSF = 'AK4PFPuppi'
0658                 getattr(process, _myPatMet).srcJetResPt = 'AK4PFPuppi_pt'
0659                 getattr(process, _myPatMet).srcJetResPhi = 'AK4PFPuppi_phi'
0660 
0661         #MET significance bypass for the patMETs from AOD
0662         if not self._parameters["onMiniAOD"].value and not postfix=="NoHF":
0663             _myPatMet = "patMETs"+postfix
0664             getattr(process, _myPatMet).computeMETSignificance = cms.bool(self.getvalue("computeMETSignificance"))
0665             getattr(process, _myPatMet).srcPFCands=copy.copy(self.getvalue("pfCandCollection"))
0666             getattr(process, _myPatMet).srcLeptons = \
0667               cms.VInputTag(copy.copy(self.getvalue("electronCollection")) if self.getvalue("onMiniAOD") else
0668                               cms.InputTag("pfeGammaToCandidate","electrons"),
0669                             copy.copy(self.getvalue("muonCollection")),
0670                             copy.copy(self.getvalue("photonCollection")) if self.getvalue("onMiniAOD") else
0671                               cms.InputTag("pfeGammaToCandidate","photons"))
0672             if self.getvalue("Puppi"):
0673                 getattr(process, _myPatMet).srcWeights = "puppiNoLep"
0674 
0675         if hasattr(process, "patCaloMet"):
0676             getattr(process, "patCaloMet").computeMETSignificance = cms.bool(False)
0677 
0678         task = getPatAlgosToolsTask(process)
0679 
0680         #T1 parameter tuning when CHS jets are not used
0681         if "T1" in correctionLevel and not self._parameters["CHS"].value:
0682             addToProcessAndTask("corrPfMetType1"+postfix, getattr(process, "corrPfMetType1" ).clone(), process, task)
0683             getattr(process, "corrPfMetType1"+postfix).src =  cms.InputTag("ak4PFJets"+postfix)
0684             getattr(process, "corrPfMetType1"+postfix).jetCorrLabel = cms.InputTag("ak4PFL1FastL2L3Corrector")
0685             getattr(process, "corrPfMetType1"+postfix).jetCorrLabelRes = cms.InputTag("ak4PFL1FastL2L3ResidualCorrector")
0686             getattr(process, "corrPfMetType1"+postfix).offsetCorrLabel = cms.InputTag("ak4PFL1FastjetCorrector")
0687             getattr(process, "basicJetsForMet"+postfix).offsetCorrLabel = cms.InputTag("ak4PFL1FastjetCorrector")
0688 
0689         if "T1" in correctionLevel and self._parameters["Puppi"].value:
0690             addToProcessAndTask("corrPfMetType1"+postfix, getattr(process, "corrPfMetType1" ).clone(), process, task)
0691             getattr(process, "corrPfMetType1"+postfix).src =  cms.InputTag("ak4PFJets"+postfix)
0692             getattr(process, "corrPfMetType1"+postfix).jetCorrLabel = cms.InputTag("ak4PFPuppiL1FastL2L3Corrector")
0693             getattr(process, "corrPfMetType1"+postfix).jetCorrLabelRes = cms.InputTag("ak4PFPuppiL1FastL2L3ResidualCorrector")
0694             getattr(process, "corrPfMetType1"+postfix).offsetCorrLabel = cms.InputTag("ak4PFPuppiL1FastjetCorrector")
0695             getattr(process, "basicJetsForMet"+postfix).offsetCorrLabel = cms.InputTag("L1FastJet")
0696 
0697         if "T1" in correctionLevel and self._parameters["CHS"].value and self._parameters["reclusterJets"].value:
0698             getattr(process, "corrPfMetType1"+postfix).src =  cms.InputTag("ak4PFJetsCHS"+postfix)
0699 
0700         #create the main MET producer
0701         metModName = "pat"+metType+"Met"+corScheme+postfix
0702 
0703         sequenceName=""
0704         corMetProducer=None
0705         if metType == "PF":
0706             corMetProducer = cms.EDProducer("CorrectedPATMETProducer",
0707                        src = cms.InputTag('pat'+metType+'Met' + postfix),
0708                        srcCorrections = cms.VInputTag(corrections)
0709                      )
0710             sequenceName="patMetCorrectionSequence"
0711 
0712         #MM: FIXME MVA
0713         #if metType == "MVA":
0714         #    return patMetCorrectionSequence, metModName #FIXME
0715         #    corMetProducer = self.createMVAMETModule(process)
0716         #    sequenceName="pfMVAMEtSequence"
0717 
0718         addToProcessAndTask(metModName, corMetProducer, process, task)
0719 
0720         # adding the full sequence only if it does not exist
0721         if not hasattr(process, sequenceName+postfix):
0722 
0723             for corModule in correctionSequence:
0724                 patMetCorrectionSequence += corModule
0725 
0726             setattr(process, sequenceName+postfix, patMetCorrectionSequence)
0727 
0728         else: #if it exists, only add the missing correction modules, no need to redo everything
0729             patMetCorrectionSequence = getattr(process, "patMetCorrectionSequence"+postfix)#cms.Sequence()
0730 
0731             #setattr(process, sequenceName+postfix,patMetCorrectionSequence)
0732             for cor in corModNames.keys():
0733                 if not configtools.contains(patMetCorrectionSequence, corTags[cor][0]) and cor in correctionLevel:
0734                     patMetCorrectionSequence += corModules[cor]
0735 
0736         #plug the main patMetproducer
0737         patMetCorrectionSequence += getattr(process, metModName)
0738 
0739         #create the intermediate MET steps
0740         #and finally add the met producers in the sequence for scheduled mode
0741         if produceIntermediateCorrections:
0742             interMets = self.addIntermediateMETs(process, metType, correctionLevel, corScheme, corTags,corNames, postfix)
0743             for met in interMets.keys():
0744                 addToProcessAndTask(met, interMets[met], process, task)
0745                 patMetCorrectionSequence += getattr(process, met)
0746 
0747         return patMetCorrectionSequence, metModName
0748 
0749 
0750 #====================================================================================================
0751     def addIntermediateMETs(self, process, metType, correctionLevel, corScheme, corTags, corNames, postfix):
0752         interMets = {}
0753 
0754         # we don't want to duplicate an exisiting module if we ask for a simple 1-corr scheme
0755         if len(correctionLevel) == 1:
0756             return interMets
0757 
0758         #ugly, but it works
0759         nCor=len(correctionLevel)+1
0760         ids = [0]*nCor
0761         for i in range(nCor**nCor):
0762             tmp=i
0763             exists=False
0764             corName=""
0765             corrections = []
0766             for j in range(nCor):
0767                 ids[j] = tmp%nCor
0768                 tmp = tmp//nCor
0769 
0770                 if j != 0 and ids[j-1] < ids[j]:
0771                     exists=True
0772                 for k in range(0,j):
0773                     if ids[k] == ids[j] and ids[k]!=0:
0774                         exists=True
0775 
0776             if exists or sum(ids[j] for j in range(nCor))==0:
0777                 continue
0778 
0779             for cor in range(nCor):
0780                 cid = ids[nCor-cor-1]
0781                 cKey = correctionLevel[cid-1]
0782                 if cid ==0:#empty correction
0783                     continue
0784                 else :
0785                     corName += corNames[cKey]
0786                     corrections.append( cms.InputTag(corTags[ cKey ][0], corTags[ cKey ][1]) )
0787 
0788             if corName == corScheme:
0789                 continue
0790 
0791             corName='pat'+metType+'Met' + corName + postfix
0792             if configtools.contains(getattr(process,"patMetCorrectionSequence"+postfix), corName ) and hasattr(process, corName):
0793                 continue
0794 
0795             interMets[corName] =  cms.EDProducer("CorrectedPATMETProducer",
0796                  src = cms.InputTag('pat'+metType+'Met' + postfix),
0797                  srcCorrections = cms.VInputTag(corrections)
0798                )
0799 
0800 
0801         return interMets
0802 
0803 
0804 #====================================================================================================
0805     def getMETUncertainties(self, process, metType, metModName, electronCollection,
0806                             photonCollection, muonCollection, tauCollection,
0807                             pfCandCollection, jetCollection, jetUncInfos,
0808                             postfix):
0809 
0810 
0811         # uncertainty sequence
0812         metUncSequence = cms.Sequence()
0813         shiftedModuleSequence = cms.Sequence()
0814 
0815         task = getPatAlgosToolsTask(process)
0816 
0817         #===================================================================================
0818         # jet energy resolution shifts
0819         #===================================================================================
0820         if not isValidInputTag(jetCollection): #or jetCollection=="":
0821             print("INFO : jet collection %s does not exists, no energy resolution shifting will be performed in MET uncertainty tools" % jetCollection)
0822         else:
0823             preId=""
0824             if "Smear" in metModName:
0825                 preId="Smeared"
0826 
0827             metJERUncModules = self.getVariations(process, metModName, "Jet",preId, jetCollection, "Res", metUncSequence, postfix=postfix )
0828 
0829             for mod in metJERUncModules.keys():
0830                 addToProcessAndTask(mod, metJERUncModules[mod], process, task)
0831                 shiftedModuleSequence += getattr(process, mod)
0832 
0833         #===================================================================================
0834         # Unclustered energy candidates
0835         #===================================================================================
0836         if not hasattr(process, "pfCandsForUnclusteredUnc"+postfix):
0837 
0838             #Jet projection ==
0839             pfCandsNoJets = _mod.candPtrProjector.clone( 
0840                                            src = pfCandCollection,
0841                                            veto = jetCollection,
0842                                            )
0843             addToProcessAndTask("pfCandsNoJets"+postfix, pfCandsNoJets, process, task)
0844             metUncSequence += getattr(process, "pfCandsNoJets"+postfix)
0845 
0846             #electron projection ==
0847             pfCandsNoJetsNoEle = _mod.candPtrProjector.clone(
0848                                                 src = "pfCandsNoJets"+postfix,
0849                                                 veto = electronCollection,
0850                                                 )
0851             if not self.getvalue("onMiniAOD"):
0852               pfCandsNoJetsNoEle.veto = "pfeGammaToCandidate:electrons"
0853             addToProcessAndTask("pfCandsNoJetsNoEle"+postfix, pfCandsNoJetsNoEle, process, task)
0854             metUncSequence += getattr(process, "pfCandsNoJetsNoEle"+postfix)
0855 
0856             #muon projection ==
0857             pfCandsNoJetsNoEleNoMu = _mod.candPtrProjector.clone(
0858                                               src = "pfCandsNoJetsNoEle"+postfix,
0859                                               veto = muonCollection,
0860                                               )
0861             addToProcessAndTask("pfCandsNoJetsNoEleNoMu"+postfix, pfCandsNoJetsNoEleNoMu, process, task)
0862             metUncSequence += getattr(process, "pfCandsNoJetsNoEleNoMu"+postfix)
0863 
0864             #tau projection ==
0865             pfCandsNoJetsNoEleNoMuNoTau = _mod.candPtrProjector.clone(
0866                                               src = "pfCandsNoJetsNoEleNoMu"+postfix,
0867                                               veto = tauCollection,
0868                                               )
0869             addToProcessAndTask("pfCandsNoJetsNoEleNoMuNoTau"+postfix, pfCandsNoJetsNoEleNoMuNoTau, process, task)
0870             metUncSequence += getattr(process, "pfCandsNoJetsNoEleNoMuNoTau"+postfix)
0871 
0872             #photon projection ==
0873             pfCandsForUnclusteredUnc = _mod.candPtrProjector.clone(
0874                                               src = "pfCandsNoJetsNoEleNoMuNoTau"+postfix,
0875                                               veto = photonCollection,
0876                                               )
0877             if not self.getvalue("onMiniAOD"):
0878               pfCandsForUnclusteredUnc.veto = "pfeGammaToCandidate:photons"
0879             addToProcessAndTask("pfCandsForUnclusteredUnc"+postfix, pfCandsForUnclusteredUnc, process, task)
0880             metUncSequence += getattr(process, "pfCandsForUnclusteredUnc"+postfix)
0881 
0882         #===================================================================================
0883         # energy shifts
0884         #===================================================================================
0885         # PFMuons, PFElectrons, PFPhotons, and PFTaus will be used
0886         # to calculate MET Uncertainties.
0887         #===================================================================================
0888         #--------------
0889         # PFElectrons :
0890         #--------------
0891         pfElectrons = cms.EDFilter("CandPtrSelector",
0892                                    src = electronCollection,
0893                                    cut = cms.string("pt > 5 && isPF && gsfTrack.isAvailable() && gsfTrack.hitPattern().numberOfLostHits(\'MISSING_INNER_HITS\') < 2")
0894                                    )
0895         addToProcessAndTask("pfElectrons"+postfix, pfElectrons, process, task)
0896         metUncSequence += getattr(process, "pfElectrons"+postfix)
0897         #--------------------------------------------------------------------
0898         # PFTaus :
0899         #---------
0900         pfTaus = cms.EDFilter("PATTauRefSelector",
0901                               src = tauCollection,
0902                               cut = cms.string('pt > 18.0 & abs(eta) < 2.6 & tauID("decayModeFinding") > 0.5 & isPFTau')
0903                               )
0904         addToProcessAndTask("pfTaus"+postfix, pfTaus, process, task)
0905         metUncSequence += getattr(process, "pfTaus"+postfix)
0906         #---------------------------------------------------------------------
0907         # PFMuons :
0908         #----------
0909         pfMuons = cms.EDFilter("CandPtrSelector",
0910                                src = muonCollection,
0911                                cut = cms.string("pt > 5.0 && isPFMuon && abs(eta) < 2.4")
0912                                )
0913         addToProcessAndTask("pfMuons"+postfix, pfMuons, process, task)
0914         metUncSequence += getattr(process, "pfMuons"+postfix)
0915         #---------------------------------------------------------------------
0916         # PFPhotons :
0917         #------------
0918         pfPhotons = cms.EDFilter("CandPtrSelector",
0919                                  src = pfCandCollection if self._parameters["Puppi"].value or not self._parameters["onMiniAOD"].value else cms.InputTag("pfCHS"),
0920                                  cut = cms.string("abs(pdgId) = 22")
0921                                  )
0922         addToProcessAndTask("pfPhotons"+postfix, pfPhotons, process, task)
0923         metUncSequence += getattr(process, "pfPhotons"+postfix)
0924         #-------------------------------------------------------------------------
0925         # Collections which have only PF Objects for calculating MET uncertainties
0926         #-------------------------------------------------------------------------
0927         electronCollection = cms.InputTag("pfElectrons"+postfix)
0928         muonCollection     = cms.InputTag("pfMuons"+postfix)
0929         tauCollection      = cms.InputTag("pfTaus"+postfix)
0930         photonCollection   = cms.InputTag("pfPhotons"+postfix)
0931 
0932 
0933         objectCollections = { "Jet":jetCollection,
0934                               "Electron":electronCollection,
0935                               "Photon":photonCollection,
0936                               "Muon":muonCollection,
0937                               "Unclustered":cms.InputTag("pfCandsForUnclusteredUnc"+postfix),
0938                               "Tau":tauCollection,
0939                               }
0940 
0941         for obj in objectCollections.keys():
0942             if not isValidInputTag(objectCollections[obj]): # or objectCollections[obj]=="":
0943                 print("INFO : %s collection %s does not exists, no energy scale shifting will be performed in MET uncertainty tools" %(obj, objectCollections[obj]))
0944             else:
0945                 metObjUncModules = self.getVariations(process, metModName, obj,"", objectCollections[obj], "En", metUncSequence, jetUncInfos, postfix )
0946 
0947                 #adding the shifted MET produced to the proper patMetModuleSequence
0948                 for mod in metObjUncModules.keys():
0949                     addToProcessAndTask(mod, metObjUncModules[mod], process, task)
0950                     shiftedModuleSequence += getattr(process, mod)
0951 
0952         #return the sequence containing the shifted collections producers
0953         return metUncSequence, shiftedModuleSequence
0954 
0955 #====================================================================================================
0956     def createEnergyScaleShiftedUpModule(self, process,identifier, objectCollection,
0957                                          varyByNsigmas, jetUncInfos=None, postfix=""):
0958 
0959         shiftedModuleUp = None
0960 
0961         if identifier == "Electron":
0962             shiftedModuleUp = cms.EDProducer("ShiftedParticleProducer",
0963                                              src = objectCollection,
0964                                              uncertainty = cms.string('((abs(y)<1.479)?(0.006+0*x):(0.015+0*x))'),
0965                                              shiftBy = cms.double(+1.*varyByNsigmas),
0966                                              srcWeights = cms.InputTag("")
0967                                              )
0968 
0969         if identifier == "Photon":
0970             shiftedModuleUp = cms.EDProducer("ShiftedParticleProducer",
0971                                              src = objectCollection,
0972                                              uncertainty = cms.string('((abs(y)<1.479)?(0.01+0*x):(0.025+0*x))'),
0973                                              shiftBy = cms.double(+1.*varyByNsigmas),
0974                                              srcWeights = cms.InputTag("")
0975                                              )
0976 
0977         if identifier == "Muon":
0978             shiftedModuleUp = cms.EDProducer("ShiftedParticleProducer",
0979                                              src = objectCollection,
0980                                              uncertainty = cms.string('((x<100)?(0.002+0*y):(0.05+0*y))'),
0981                                              shiftBy = cms.double(+1.*varyByNsigmas),
0982                                              srcWeights = cms.InputTag("")
0983                                              )
0984 
0985         if identifier == "Tau":
0986             shiftedModuleUp = cms.EDProducer("ShiftedParticleProducer",
0987                                              src = objectCollection,
0988                                              uncertainty = cms.string('0.03+0*x*y'),
0989                                              shiftBy = cms.double(+1.*varyByNsigmas),
0990                                              srcWeights = cms.InputTag("")
0991                                              )
0992 
0993         if identifier == "Unclustered":
0994             shiftedModuleUp = cms.EDProducer("ShiftedParticleProducer",
0995                                              src = objectCollection,
0996                                              binning = cms.VPSet(
0997                     # charged PF hadrons - tracker resolution
0998                     cms.PSet(
0999                         binSelection = cms.string('charge!=0'),
1000                         binUncertainty = cms.string('sqrt(pow(0.00009*x,2)+pow(0.0085/sqrt(sin(2*atan(exp(-y)))),2))')
1001                         ),
1002                     # neutral PF hadrons - HCAL resolution
1003                     cms.PSet(
1004                         binSelection = cms.string('pdgId==130'),
1005                         energyDependency = cms.bool(True),
1006                         binUncertainty = cms.string('((abs(y)<1.3)?(min(0.25,sqrt(0.64/x+0.0025))):(min(0.30,sqrt(1.0/x+0.0016))))')
1007                         ),
1008                     # photon - ECAL resolution
1009                     cms.PSet(
1010                         binSelection = cms.string('pdgId==22'),
1011                         energyDependency = cms.bool(True),
1012                         binUncertainty = cms.string('sqrt(0.0009/x+0.000001)+0*y')
1013                         ),
1014                     # HF particules - HF resolution
1015                     cms.PSet(
1016                         binSelection = cms.string('pdgId==1 || pdgId==2'),
1017                         energyDependency = cms.bool(True),
1018                         binUncertainty = cms.string('sqrt(1./x+0.0025)+0*y')
1019                         ),
1020                     ),
1021                                              shiftBy = cms.double(+1.*varyByNsigmas),
1022                                              srcWeights = cms.InputTag("")
1023                                              )
1024 
1025         if identifier == "Jet":
1026             moduleType="ShiftedPATJetProducer"
1027             #MM: FIXME MVA
1028             #if self._parameters["metType"].value == "MVA":
1029             #    moduleType="ShiftedPFJetProducer"
1030 
1031             if jetUncInfos["jecUncFile"] == "":
1032                 shiftedModuleUp = cms.EDProducer(moduleType,
1033                                                  src = objectCollection,
1034                                                  jetCorrUncertaintyTag = cms.string(jetUncInfos["jecUncTag"] ),
1035                                                  addResidualJES = cms.bool(True),
1036                                                  jetCorrLabelUpToL3 = cms.InputTag(jetUncInfos["jCorLabelUpToL3"] ),
1037                                                  jetCorrLabelUpToL3Res = cms.InputTag(jetUncInfos["jCorLabelL3Res"] ),
1038                                                  jetCorrPayloadName =  cms.string(jetUncInfos["jCorrPayload"] ),
1039                                                  shiftBy = cms.double(+1.*varyByNsigmas),
1040                                                  )
1041             else:
1042                 shiftedModuleUp = cms.EDProducer(moduleType,
1043                                                  src = objectCollection,
1044                                                  jetCorrInputFileName = cms.FileInPath(jetUncInfos["jecUncFile"] ),
1045                                                  jetCorrUncertaintyTag = cms.string(jetUncInfos["jecUncTag"] ),
1046                                                  addResidualJES = cms.bool(True),
1047                                                  jetCorrLabelUpToL3 = cms.InputTag(jetUncInfos["jCorLabelUpToL3"] ),
1048                                                  jetCorrLabelUpToL3Res = cms.InputTag(jetUncInfos["jCorLabelL3Res"] ),
1049                                                  jetCorrPayloadName =  cms.string(jetUncInfos["jCorrPayload"] ),
1050                                                  shiftBy = cms.double(+1.*varyByNsigmas),
1051                                                  )
1052 
1053 
1054         return shiftedModuleUp
1055 
1056 
1057 #====================================================================================================
1058 
1059 
1060 #====================================================================================================
1061     def removePostfix(self, name, postfix):
1062 
1063         if postfix=="":
1064             return name
1065 
1066         baseName = name
1067         if baseName[-len(postfix):] == postfix:
1068             baseName = baseName[0:-len(postfix)]
1069         else:
1070             raise Exception("Tried to remove postfix %s from %s, but it wasn't there" % (postfix, baseName))
1071 
1072         return baseName
1073 
1074 #====================================================================================================
1075     def tuneTxyParameters(self, process, corScheme, postfix):
1076         import PhysicsTools.PatUtils.patPFMETCorrections_cff as metCors
1077         xyTags = {
1078             "Txy_50ns":metCors.patMultPhiCorrParams_Txy_50ns,
1079             "T1Txy_50ns":metCors.patMultPhiCorrParams_T1Txy_50ns,
1080             "T0pcTxy_50ns":metCors.patMultPhiCorrParams_T0pcTxy_50ns,
1081             "T0pcT1Txy_50ns":metCors.patMultPhiCorrParams_T0pcT1Txy_50ns,
1082             "T1T2Txy_50ns":metCors.patMultPhiCorrParams_T1T2Txy_50ns,
1083             "T0pcT1T2Txy_50ns":metCors.patMultPhiCorrParams_T0pcT1T2Txy_50ns,
1084             "T1SmearTxy_50ns":metCors.patMultPhiCorrParams_T1SmearTxy_50ns,
1085             "T1T2SmearTxy_50ns":metCors.patMultPhiCorrParams_T1T2SmearTxy_50ns,
1086             "T0pcT1SmearTxy_50ns":metCors.patMultPhiCorrParams_T0pcT1SmearTxy_50ns,
1087             "T0pcT1T2SmearTxy_50ns":metCors.patMultPhiCorrParams_T0pcT1T2SmearTxy_50ns,
1088 
1089             "Txy_25ns":metCors.patMultPhiCorrParams_Txy_25ns,
1090             "T1Txy_25ns":metCors.patMultPhiCorrParams_T1Txy_25ns,
1091             "T0pcTxy_25ns":metCors.patMultPhiCorrParams_T0pcTxy_25ns,
1092             "T0pcT1Txy_25ns":metCors.patMultPhiCorrParams_T0pcT1Txy_25ns,
1093             "T1T2Txy_25ns":metCors.patMultPhiCorrParams_T1T2Txy_25ns,
1094             "T0pcT1T2Txy_25ns":metCors.patMultPhiCorrParams_T0pcT1T2Txy_25ns,
1095             "T1SmearTxy_25ns":metCors.patMultPhiCorrParams_T1SmearTxy_25ns,
1096             "T1T2SmearTxy_25ns":metCors.patMultPhiCorrParams_T1T2SmearTxy_25ns,
1097             "T0pcT1SmearTxy_25ns":metCors.patMultPhiCorrParams_T0pcT1SmearTxy_25ns,
1098             "T0pcT1T2SmearTxy_25ns":metCors.patMultPhiCorrParams_T0pcT1T2SmearTxy_25ns
1099             }
1100 
1101         getattr(process, "patPFMetTxyCorr"+postfix).parameters = xyTags[corScheme+"_25ns"]
1102 
1103 
1104 #====================================================================================================
1105     def getVariations(self, process, metModName, identifier,preId, objectCollection, varType,
1106                       metUncSequence, jetUncInfos=None, postfix="" ):
1107 
1108         # temporary hardcoded varyByNSigma value
1109         varyByNsigmas=1
1110 
1111         # remove the postfix to put it at the end
1112         baseName = self.removePostfix(metModName, postfix)
1113 
1114         #default shifted MET producers
1115         shiftedMetProducers = {preId+identifier+varType+'Up':None, preId+identifier+varType+'Down':None}
1116 
1117         #create the shifted collection producers=========================================
1118         shiftedCollModules = {'Up':None, 'Down':None}
1119 
1120         if identifier=="Jet" and varType=="Res":
1121             smear=False
1122             if "Smear" in metModName:
1123                 smear=True
1124             else:
1125                 smear=True
1126                 varyByNsigmas=101
1127 
1128             shiftedCollModules['Up'] = self.createShiftedJetResModule(process, smear, objectCollection, +1.*varyByNsigmas,
1129                                                                       "Up", postfix)
1130             shiftedCollModules['Down'] = self.createShiftedJetResModule(process, smear, objectCollection, -1.*varyByNsigmas,
1131                                                                         "Down", postfix)
1132         else:
1133             shiftedCollModules['Up'] = self.createEnergyScaleShiftedUpModule(process, identifier, objectCollection, varyByNsigmas, jetUncInfos, postfix)
1134             shiftedCollModules['Down'] = shiftedCollModules['Up'].clone( shiftBy = cms.double(-1.*varyByNsigmas) )
1135 
1136         if identifier=="Jet" and varType=="Res":
1137             smear=False
1138             if "Smear" in metModName:
1139                 objectCollection=cms.InputTag("selectedPatJetsForMetT1T2SmearCorr"+postfix)
1140 
1141 
1142 
1143         #and the MET producers
1144         if identifier=="Jet" and varType=="Res" and self._parameters["runOnData"].value:
1145             shiftedMetProducers = self.copyCentralMETProducer(process, shiftedCollModules, identifier, metModName, varType, postfix)
1146         else:
1147             shiftedMetProducers = self.createShiftedModules(process, shiftedCollModules, identifier, preId, objectCollection,
1148                                                             metModName, varType, metUncSequence, postfix)
1149 
1150         return shiftedMetProducers
1151 
1152 
1153 #========================================================================================
1154     def copyCentralMETProducer(self, process, shiftedCollModules, identifier, metModName, varType, postfix):
1155 
1156         # remove the postfix to put it at the end
1157         shiftedMetProducers = {}
1158         baseName = self.removePostfix(metModName, postfix)
1159         for mod in shiftedCollModules.keys():
1160             modName = baseName+identifier+varType+mod+postfix
1161             shiftedMETModule = getattr(process, metModName).clone()
1162             shiftedMetProducers[ modName ] = shiftedMETModule
1163 
1164         return shiftedMetProducers
1165 
1166 
1167 #========================================================================================
1168     def createShiftedJetResModule(self, process, smear, objectCollection, varyByNsigmas, varDir, postfix ):
1169 
1170         smearedJetModule = self.createSmearedJetModule(process, objectCollection, smear, varyByNsigmas, varDir, postfix)
1171 
1172         return smearedJetModule
1173 
1174 
1175 #========================================================================================
1176     def createShiftedModules(self, process, shiftedCollModules, identifier, preId, objectCollection,
1177                              metModName, varType, metUncSequence, postfix):
1178 
1179         shiftedMetProducers = {}
1180 
1181         task = getPatAlgosToolsTask(process)
1182 
1183         # remove the postfix to put it at the end
1184         baseName = self.removePostfix(metModName, postfix)
1185 
1186         #adding the shifted collection producers to the sequence, create the shifted MET correction Modules and add them as well
1187         for mod in shiftedCollModules.keys():
1188             modName = "shiftedPat"+preId+identifier+varType+mod+postfix
1189             #MM: FIXME MVA
1190             #if  "MVA" in metModName and identifier == "Jet": #dummy fix
1191             #    modName = "uncorrectedshiftedPat"+preId+identifier+varType+mod+postfix
1192             if (identifier=="Photon" or identifier=="Unclustered") and self.getvalue("Puppi"):
1193                 shiftedCollModules[mod].srcWeights = "puppiNoLep"
1194             if not hasattr(process, modName):
1195                 addToProcessAndTask(modName, shiftedCollModules[mod], process, task)
1196                 metUncSequence += getattr(process, modName)
1197 
1198             #removing the uncorrected
1199             modName = "shiftedPat"+preId+identifier+varType+mod+postfix
1200 
1201             #PF MET =================================================================================
1202             if "PF" in metModName:
1203                 #create the MET shifts and add them to the sequence
1204                 shiftedMETCorrModule = self.createShiftedMETModule(process, objectCollection, modName)
1205                 if (identifier=="Photon" or identifier=="Unclustered") and self.getvalue("Puppi"):
1206                    shiftedMETCorrModule.srcWeights = "puppiNoLep"
1207                 modMETShiftName = "shiftedPatMETCorr"+preId+identifier+varType+mod+postfix
1208                 if not hasattr(process, modMETShiftName):
1209                     addToProcessAndTask(modMETShiftName, shiftedMETCorrModule, process, task)
1210                     metUncSequence += getattr(process, modMETShiftName)
1211 
1212                 #and finally prepare the shifted MET producers
1213                 modName = baseName+identifier+varType+mod+postfix
1214                 shiftedMETModule = getattr(process, metModName).clone(
1215                     src = cms.InputTag( metModName ),
1216                     srcCorrections = cms.VInputTag( cms.InputTag(modMETShiftName) )
1217                     )
1218                 shiftedMetProducers[ modName ] = shiftedMETModule
1219 
1220             #MM: FIXME MVA
1221             #MVA MET, duplication of the MVA MET producer ============================================
1222             #if "MVA" in metModName:
1223             #    print "name: ",metModName, modName
1224             #    shiftedMETModule = self.createMVAMETModule(process, identifier, modName, True)
1225             #    modName = baseName+identifier+varType+mod+postfix
1226             #    setattr(process, modName, shiftedMETModule)
1227             #    shiftedMetProducers[ modName ] = shiftedMETModule
1228             #
1229             #     #pileupjetId and  =====
1230             #    if identifier == "Jet":
1231             #        #special collection replacement for the MVAMET for the jet case ======
1232             #        origCollection = cms.InputTag("calibratedAK4PFJetsForPFMVAMEt"+postfix) #self._parameters["jetCollection"].value
1233             #        newCollection = cms.InputTag("uncorrectedshiftedPat"+preId+identifier+varType+mod+postfix)
1234             #        moduleName = "shiftedPat"+preId+identifier+varType+mod+postfix
1235             #        corrShiftedModule = getattr(process,"calibratedAK4PFJetsForPFMVAMEt").clone(
1236             #            src=newCollection
1237             # )
1238 
1239             #        setattr(process, moduleName, corrShiftedModule)
1240             #        metUncSequence += getattr(process, moduleName)
1241 
1242             #        puJetIdProducer = getattr(process, "puJetIdForPFMVAMEt").clone(
1243             #            jets = moduleName
1244             #            )
1245             #        puJetIdName = "puJetIdForPFMVAMEt"+preId+identifier+varType+mod+postfix
1246             #        setattr(process, puJetIdName, puJetIdProducer)
1247             #        metUncSequence += getattr(process, puJetIdName)
1248             #        shiftedMETModule.srcMVAPileupJetId = cms.InputTag(puJetIdName,"fullDiscriminant")
1249 
1250            #==========================================================================================
1251 
1252         return shiftedMetProducers
1253 
1254 
1255 #========================================================================================
1256     def createShiftedMETModule(self, process, originCollection, shiftedCollection):
1257 
1258         shiftedModule = cms.EDProducer("ShiftedParticleMETcorrInputProducer",
1259                                        srcOriginal = originCollection,
1260                                        srcShifted = cms.InputTag(shiftedCollection),
1261                                        srcWeights = cms.InputTag("")
1262                                        )
1263 
1264         return shiftedModule
1265 
1266 #========================================================================================
1267     def createMVAMETModule(self, process, identifier="", shiftedCollection="", isShifted=False, postfix="" ):
1268 
1269         task = getPatAlgosToolsTask(process)
1270 
1271         if not hasattr(process, "pfMVAMEt"):
1272             process.load("RecoMET.METPUSubtraction.mvaPFMET_cff")
1273 
1274         #retrieve collections
1275         electronCollection = self._parameters["electronCollection"].value
1276         muonCollection = self._parameters["electronCollection"].value
1277         photonCollection = self._parameters["photonCollection"].value
1278         tauCollection = self._parameters["tauCollection"].value
1279         pfCandCollection = self._parameters["pfCandCollection"].value
1280         corJetCollection = cms.InputTag("calibratedAK4PFJetsForPFMVAMEt"+postfix)
1281         uncorJetCollection = cms.InputTag("ak4PFJets")
1282 
1283         #shift if needed===
1284         if isShifted:
1285             if identifier == "Electron":
1286                 electronCollection = cms.InputTag(shiftedCollection)
1287             if identifier == "Muon":
1288                 muonCollection = cms.InputTag(shiftedCollection)
1289             if identifier == "Tau":
1290                 tauCollection = cms.InputTag(shiftedCollection)
1291             if identifier == "Photon":
1292                 photonCollection = cms.InputTag(shiftedCollection)
1293             if identifier == "Unclustered":
1294                 pfCandCollection = cms.InputTag(shiftedCollection)
1295             if identifier == "Jet":
1296                 corJetCollection = cms.InputTag(shiftedCollection)
1297                 uncorJetCollection = cms.InputTag("uncorrected"+shiftedCollection)
1298 
1299 
1300         #leptons
1301         mvaMetLeptons = self._parameters["mvaMetLeptons"].value
1302         leptons = cms.VInputTag([])
1303         if "Electrons" in mvaMetLeptons and isValidInputTag(electronCollection):
1304             leptons.append = electronCollection
1305         if "Muons" in mvaMetLeptons and isValidInputTag(muonCollection):
1306             leptons.append = muonCollection
1307         if "Photons" in mvaMetLeptons and isValidInputTag(photonCollection):
1308             leptons.append = photonCollection
1309         if "Taus" in mvaMetLeptons and isValidInputTag(tauCollection):
1310             leptons.append = tauCollection
1311 
1312 
1313         mvaMetProducer=getattr(process, "pfMVAMEt").clone(
1314             srcCorrJets = corJetCollection,
1315             srcUncorrJets = uncorJetCollection,
1316             srcPFCandidates = pfCandCollection,
1317             srcLeptons = leptons,
1318             )
1319 
1320         return mvaMetProducer
1321 
1322 #========================================================================================
1323     def getUnclusteredVariationsForMVAMET(self, process, var, val,  metUncSequence, postfix ):
1324 
1325         if not hasattr(process, "pfCandsNotInJetsForMetCorr"):
1326             process.load("JetMETCorrections.Type1MET.correctionTerms.PfMetType1Type2_cff")
1327 
1328         #MM: it's bloody stupid to make it that way....
1329         # compute the shifted particles ====
1330         unclCandModule = cms.EDProducer("ShiftedPFCandidateProducer",
1331                                         src = cms.InputTag('pfCandsNotInJetsForMetCorr'),
1332                                         shiftBy = cms.double(val),
1333                                         uncertainty = cms.double(0.10)
1334                                         )
1335         setattr(process, "pfCandsNotInJetsUnclusteredEn"+var+postfix, unclCandModule)
1336         metUncSequence += getattr(process, "pfCandsNotInJetsUnclusteredEn"+var+postfix)
1337 
1338 
1339 
1340         #replace the old unclustered particles by the shifted ones....
1341         pfCandCollection = self._parameters["pfCandCollection"].value
1342 
1343         #top projection on jets
1344         pfCandsNotInJets = _mod.candPtrProjector.clone(
1345                                           src = pfCandCollection,
1346                                           veto = "ak4PFJets"
1347                                           )
1348         setattr(process, "pfCandsNotInJetsUnclusteredEn"+var+postfix, pfCandsNotInJets)
1349         metUncSequence += getattr(process,"pfCandsNotInJetsUnclusteredEn"+var+postfix)
1350 
1351         fullShiftedModule = self.createShiftedObjectModuleForMVAMET(pfCandCollection, cms.InputTag("pfCandsNotInJetsUnclusteredEn"+var+postfix), 0.01 )
1352         setattr(process, "pfCandidatesEn"+var+postfix, fullShiftedModule)
1353         metUncSequence += getattr(process, "pfCandidatesEn"+var+postfix)
1354 
1355         # duplication of the MVA MET producer ============================================
1356         shiftedMETModule = self.createMVAMETModule(process, "Unclustered", "pfCandidatesEn"+var+postfix, True)
1357         return shiftedMETModule
1358 
1359 #========================================================================================
1360     def createShiftedObjectModuleForMVAMET(self, origCollection, shiftedCollection, dr=0.5):
1361         fullShiftedModule = cms.EDProducer("ShiftedPFCandidateProducerByMatchedObject",
1362                  srcPFCandidates = origCollection,
1363                  srcUnshiftedObjects = origCollection,
1364                  dRmatch_PFCandidate = cms.double(dr),
1365                  srcShiftedObjects = shiftedCollection
1366                )
1367         return fullShiftedModule
1368 
1369 #========================================================================================
1370     def createSmearedJetModule(self, process, jetCollection, smear, varyByNsigmas, varDir, postfix):
1371 
1372         smearedJetModule = None
1373 
1374         modName = "pat"
1375         selJetModName= "selectedPatJetsForMetT1T2"
1376         if smear:
1377             modName += "SmearedJets"
1378             selJetModName += "SmearCorr"
1379         else:
1380             modName += "Jets"
1381 
1382 
1383         if varDir != "":
1384             modName += "Res"+varDir
1385             selJetModName += "Res"+varDir
1386 
1387         modName += postfix
1388         selJetModName += postfix
1389 
1390         genJetsCollection=cms.InputTag('ak4GenJetsNoNu')
1391         if self._parameters["onMiniAOD"].value:
1392             genJetsCollection=cms.InputTag("slimmedGenJets")
1393 
1394         if self._parameters["Puppi"].value:
1395             getattr(process, "patSmearedJets"+postfix).algo = 'AK4PFPuppi'
1396             getattr(process, "patSmearedJets"+postfix).algopt = 'AK4PFPuppi_pt'
1397 
1398         if "PF" == self._parameters["metType"].value:
1399             smearedJetModule = getattr(process, "patSmearedJets"+postfix).clone(
1400                 src = jetCollection,
1401                 enabled = cms.bool(smear),
1402                 variation = cms.int32( int(varyByNsigmas) ),
1403                 genJets = genJetsCollection,
1404                 )
1405 
1406         #MM: FIXME MVA
1407         #if "MVA" == self._parameters["metType"].value:
1408         #    from RecoMET.METProducers.METSigParams_cfi import *
1409 
1410         #    genJetsCollection=cms.InputTag('ak4GenJetsNoNu')
1411         #    if self._parameters["onMiniAOD"].value:
1412         #        genJetsCollection=cms.InputTag("slimmedGenJets")
1413 
1414         #    smearedJetModule = cms.EDProducer("SmearedPFJetProducer",
1415         #            src = cms.InputTag('ak4PFJets'),
1416         #            jetCorrLabel = cms.InputTag("ak4PFL1FastL2L3Corrector"),
1417         #            dRmaxGenJetMatch = cms.string('min(0.5, 0.1 + 0.3*exp(-0.05*(genJetPt - 10.)))'),
1418         #            sigmaMaxGenJetMatch = cms.double(3.),
1419         #            inputFileName = cms.FileInPath('PhysicsTools/PatUtils/data/pfJetResolutionMCtoDataCorrLUT.root'),
1420         #            lutName = cms.string('pfJetResolutionMCtoDataCorrLUT'),
1421         #            jetResolutions = METSignificance_params,
1422         #            skipRawJetPtThreshold = cms.double(10.), # GeV
1423         #            skipCorrJetPtThreshold = cms.double(1.e-2),
1424         #            srcGenJets = genJetsCollection,
1425         #            shiftBy = cms.double(varyByNsigmas),
1426         #            #verbosity = cms.int32(1)
1427         #            )
1428 
1429         return smearedJetModule
1430 
1431 
1432 ### Utilities ====================================================================
1433     def labelsInSequence(process, sequenceLabel, postfix=""):
1434         result = [ m.label()[:-len(postfix)] for m in listModules( getattr(process,sequenceLabel+postfix))]
1435         result.extend([ m.label()[:-len(postfix)] for m in listSequences( getattr(process,sequenceLabel+postfix))]  )
1436         if postfix == "":
1437             result = [ m.label() for m in listModules( getattr(process,sequenceLabel+postfix))]
1438             result.extend([ m.label() for m in listSequences( getattr(process,sequenceLabel+postfix))]  )
1439         return result
1440 
1441     def initializeInputTag(self, input, default):
1442         retVal = None
1443         if input is None:
1444             retVal = self._defaultParameters[default].value
1445         elif isinstance(input, str):
1446             retVal = cms.InputTag(input)
1447         else:
1448             retVal = input
1449         return retVal
1450 
1451 
1452     def recomputeRawMetFromPfcs(self, process, pfCandCollection, onMiniAOD, patMetModuleSequence,  postfix):
1453 
1454         task = getPatAlgosToolsTask(process)
1455 
1456         #RECO MET
1457         if not hasattr(process, "pfMet"+postfix) and self._parameters["metType"].value == "PF":
1458             #common to AOD/mAOD processing
1459             #raw MET
1460             from RecoMET.METProducers.pfMet_cfi import pfMet
1461             addToProcessAndTask("pfMet"+postfix, pfMet.clone(), process, task)
1462             getattr(process, "pfMet"+postfix).src = pfCandCollection
1463             getattr(process, "pfMet"+postfix).calculateSignificance = False
1464             if self.getvalue("Puppi"):
1465                 getattr(process, "pfMet"+postfix).applyWeight = True
1466                 getattr(process, "pfMet"+postfix).srcWeights = "puppiNoLep"
1467             patMetModuleSequence += getattr(process, "pfMet"+postfix)
1468 
1469         #PAT METs
1470         if not hasattr(process, "patMETs"+postfix) and self._parameters["metType"].value == "PF":
1471             process.load("PhysicsTools.PatAlgos.producersLayer1.metProducer_cff")
1472             task.add(process.makePatMETsTask)
1473             configtools.cloneProcessingSnippet(process, getattr(process,"patMETCorrections"), postfix, addToTask = True)
1474 
1475             #T1 pfMet for AOD to mAOD only
1476             if not onMiniAOD: #or self._parameters["Puppi"].value:
1477                 #correction duplication needed
1478                 getattr(process, "pfMetT1"+postfix).src = cms.InputTag("pfMet"+postfix)
1479                 patMetModuleSequence += getattr(process, "pfMetT1"+postfix)
1480                 _myPatMet = 'patMETs'+postfix
1481                 addToProcessAndTask(_myPatMet, getattr(process,'patMETs' ).clone(), process, task)
1482                 getattr(process, _myPatMet).metSource = cms.InputTag("pfMetT1"+postfix)
1483                 getattr(process, _myPatMet).computeMETSignificance = cms.bool(self.getvalue("computeMETSignificance"))
1484                 getattr(process, _myPatMet).srcLeptons = \
1485                   cms.VInputTag(copy.copy(self.getvalue("electronCollection")) if self.getvalue("onMiniAOD") else
1486                                   cms.InputTag("pfeGammaToCandidate","electrons"),
1487                                 copy.copy(self.getvalue("muonCollection")),
1488                                 copy.copy(self.getvalue("photonCollection")) if self.getvalue("onMiniAOD") else
1489                                   cms.InputTag("pfeGammaToCandidate","photons"))
1490                 if postfix=="NoHF":
1491                     getattr(process, _myPatMet).computeMETSignificance = cms.bool(False)
1492 
1493                 if self.getvalue("Puppi"):
1494                     getattr(process, _myPatMet).srcWeights = "puppiNoLep"
1495                     getattr(process, _myPatMet).srcJets = cms.InputTag('cleanedPatJets'+postfix)
1496                     getattr(process, _myPatMet).srcJetSF = cms.string('AK4PFPuppi')
1497                     getattr(process, _myPatMet).srcJetResPt = cms.string('AK4PFPuppi_pt')
1498                     getattr(process, _myPatMet).srcJetResPhi = cms.string('AK4PFPuppi_phi')
1499 
1500 
1501     def extractMET(self, process, correctionLevel, patMetModuleSequence, postfix):
1502 
1503         task = getPatAlgosToolsTask(process)
1504 
1505         pfMet = cms.EDProducer("RecoMETExtractor",
1506                                metSource= cms.InputTag("slimmedMETs" if not self._parameters["Puppi"].value else "slimmedMETsPuppi",processName=cms.InputTag.skipCurrentProcess()),
1507                                correctionLevel = cms.string(correctionLevel)
1508                                )
1509         if(correctionLevel=="raw"):
1510             addToProcessAndTask("pfMet"+postfix, pfMet, process, task)
1511             patMetModuleSequence += getattr(process, "pfMet"+postfix)
1512         else:
1513             addToProcessAndTask("met"+correctionLevel+postfix, pfMet, process, task)
1514             patMetModuleSequence += getattr(process, "met"+correctionLevel+postfix)
1515 
1516         if not hasattr(process, "genMetExtractor"+postfix) and not self._parameters["runOnData"].value:
1517             genMetExtractor = cms.EDProducer("GenMETExtractor",
1518                                              metSource= cms.InputTag("slimmedMETs",processName=cms.InputTag.skipCurrentProcess())
1519                                              )
1520             addToProcessAndTask("genMetExtractor"+postfix, genMetExtractor, process, task)
1521             patMetModuleSequence += getattr(process, "genMetExtractor"+postfix)
1522 
1523 
1524     def updateJECs(self,process,jetCollection, patMetModuleSequence, postfix):
1525         from PhysicsTools.PatAlgos.producersLayer1.jetUpdater_cff import updatedPatJetCorrFactors
1526 
1527         patJetCorrFactorsReapplyJEC = updatedPatJetCorrFactors.clone(
1528             src = jetCollection if not self._parameters["Puppi"].value else cms.InputTag("slimmedJetsPuppi"),
1529             levels = ['L1FastJet',
1530                       'L2Relative',
1531                       'L3Absolute'],
1532             payload = 'AK4PFchs' if not self._parameters["Puppi"].value else 'AK4PFPuppi' ) # always CHS from miniAODs, except for puppi
1533 
1534         if self._parameters["runOnData"].value:
1535             patJetCorrFactorsReapplyJEC.levels.append("L2L3Residual")
1536 
1537         from PhysicsTools.PatAlgos.producersLayer1.jetUpdater_cff import updatedPatJets
1538         patJetsReapplyJEC = updatedPatJets.clone(
1539             jetSource = jetCollection if not self._parameters["Puppi"].value else cms.InputTag("slimmedJetsPuppi"),
1540             jetCorrFactorsSource = cms.VInputTag(cms.InputTag("patJetCorrFactorsReapplyJEC"+postfix))
1541             )
1542 
1543         task = getPatAlgosToolsTask(process)
1544         addToProcessAndTask("patJetCorrFactorsReapplyJEC"+postfix, patJetCorrFactorsReapplyJEC, process, task)
1545         addToProcessAndTask("patJetsReapplyJEC"+postfix, patJetsReapplyJEC.clone(), process, task)
1546 
1547         patMetModuleSequence += getattr(process,"patJetCorrFactorsReapplyJEC"+postfix)
1548         patMetModuleSequence += getattr(process,"patJetsReapplyJEC"+postfix)
1549 
1550         return  cms.InputTag("patJetsReapplyJEC"+postfix)
1551 
1552 
1553     def getJetCollectionForCorsAndUncs(self, process, jetCollectionUnskimmed,
1554                                        jetSelection, autoJetCleaning,patMetModuleSequence, postfix):
1555 
1556         task = getPatAlgosToolsTask(process)
1557 
1558         basicJetsForMet = cms.EDProducer("PATJetCleanerForType1MET",
1559                                          src = jetCollectionUnskimmed,
1560                                          jetCorrEtaMax = cms.double(9.9),
1561                                          jetCorrLabel = cms.InputTag("L3Absolute"),
1562                                          jetCorrLabelRes = cms.InputTag("L2L3Residual"),
1563                                          offsetCorrLabel = cms.InputTag("L1FastJet"),
1564                                          skipEM = cms.bool(True),
1565                                          skipEMfractionThreshold = cms.double(0.9),
1566                                          skipMuonSelection = cms.string('isGlobalMuon | isStandAloneMuon'),
1567                                          skipMuons = cms.bool(True),
1568                                          type1JetPtThreshold = cms.double(15.0)
1569                                          )
1570         addToProcessAndTask("basicJetsForMet"+postfix, basicJetsForMet, process, task)
1571         patMetModuleSequence += getattr(process, "basicJetsForMet"+postfix)
1572 
1573         from PhysicsTools.PatAlgos.selectionLayer1.jetSelector_cfi import selectedPatJets
1574         jetSelector = selectedPatJets.clone(
1575             src = cms.InputTag("basicJetsForMet"+postfix),
1576             cut = cms.string(jetSelection)
1577             )
1578         addToProcessAndTask("jetSelectorForMet"+postfix, jetSelector, process, task)
1579         patMetModuleSequence += getattr(process, "jetSelectorForMet"+postfix)
1580 
1581         jetCollection = self.jetCleaning(process, "jetSelectorForMet"+postfix, autoJetCleaning, patMetModuleSequence, postfix)
1582 
1583         return jetCollection
1584 
1585 
1586     def ak4JetReclustering(self,process, pfCandCollection, patMetModuleSequence, postfix):
1587 
1588         task = getPatAlgosToolsTask(process)
1589 
1590         chs = self._parameters["CHS"].value
1591         jetColName="ak4PFJets"
1592         CHSname=""
1593         pfCandColl=pfCandCollection
1594         if chs:
1595             CHSname="chs"
1596             jetColName="ak4PFJetsCHS"
1597             if self._parameters["onMiniAOD"].value: 
1598                 pfCandColl = cms.InputTag("pfCHS")
1599             else:
1600                 addToProcessAndTask("tmpPFCandCollPtr"+postfix,
1601                                     cms.EDProducer("PFCandidateFwdPtrProducer",
1602                                                    src = pfCandCollection ),
1603                                     process, task)
1604                 process.load("CommonTools.ParticleFlow.pfNoPileUpJME_cff")
1605                 task.add(process.pfNoPileUpJMETask)
1606                 configtools.cloneProcessingSnippet(process, getattr(process,"pfNoPileUpJMESequence"), postfix, addToTask = True )
1607                 getattr(process, "pfPileUpJME"+postfix).PFCandidates = "tmpPFCandCollPtr"+postfix
1608                 getattr(process, "pfNoPileUpJME"+postfix).bottomCollection = "tmpPFCandCollPtr"+postfix
1609                 pfCandColl = "pfNoPileUpJME"+postfix
1610                 patMetModuleSequence += getattr(process, "tmpPFCandCollPtr"+postfix)
1611                 patMetModuleSequence += getattr(process, "pfNoPileUpJME"+postfix)
1612 
1613         jetColName+=postfix
1614         if not hasattr(process, jetColName):
1615             #process.load("RecoJets.JetProducers.ak4PFJets_cfi")
1616             #task.add(process.ak4PFJets)
1617             from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets
1618             #if chs:
1619             addToProcessAndTask(jetColName, ak4PFJets.clone(), process, task)
1620             getattr(process, jetColName).src = pfCandColl
1621             getattr(process, jetColName).doAreaFastjet = True
1622 
1623             #puppi
1624             if self._parameters["Puppi"].value:
1625                 getattr(process, jetColName).srcWeights = cms.InputTag("puppi")
1626                 getattr(process, jetColName).applyWeight = True
1627 
1628             patMetModuleSequence += getattr(process, jetColName)
1629 
1630             corLevels=['L1FastJet', 'L2Relative', 'L3Absolute']
1631             if self._parameters["runOnData"].value:
1632                 corLevels.append("L2L3Residual")
1633 
1634             switchJetCollection(process,
1635                                 jetSource = cms.InputTag(jetColName),
1636                                 jetCorrections = ('AK4PF'+CHSname, corLevels , ''),
1637                                 postfix=postfix
1638                                 )
1639 
1640             getattr(process,"patJets"+postfix).addGenJetMatch = False
1641             getattr(process,"patJets"+postfix).addGenPartonMatch = False
1642             getattr(process,"patJets"+postfix).addPartonJetMatch = False
1643             getattr(process,"patJets"+postfix).embedGenPartonMatch = False
1644             getattr(process,"patJets"+postfix).embedGenJetMatch = False
1645             if self._parameters['onMiniAOD'].value:
1646                 del getattr(process,"patJets"+postfix).JetFlavourInfoSource
1647                 del getattr(process,"patJets"+postfix).JetPartonMapSource
1648                 del getattr(process,"patJets"+postfix).genPartonMatch
1649                 del getattr(process,"patJets"+postfix).genJetMatch
1650             getattr(process,"patJets"+postfix).getJetMCFlavour = False
1651 
1652             getattr(process,"patJetCorrFactors"+postfix).src=cms.InputTag(jetColName)
1653             getattr(process,"patJetCorrFactors"+postfix).primaryVertices= cms.InputTag("offlineSlimmedPrimaryVertices")
1654             if self._parameters["Puppi"].value:
1655                 getattr(process,"patJetCorrFactors"+postfix).payload=cms.string('AK4PFPuppi')
1656             patMetModuleSequence += getattr(process, "patJetCorrFactors"+postfix)
1657             patMetModuleSequence += getattr(process, "patJets"+postfix)
1658 
1659         return cms.InputTag("patJets"+postfix)
1660 
1661 
1662 
1663     def miniAODConfigurationPre(self, process, patMetModuleSequence, pfCandCollection, postfix):
1664 
1665             #extractor for caloMET === temporary for the beginning of the data taking
1666         self.extractMET(process,"rawCalo",patMetModuleSequence,postfix)
1667         caloMetName="metrawCalo" if hasattr(process,"metrawCalo") else "metrawCalo"+postfix
1668         from PhysicsTools.PatAlgos.tools.metTools import addMETCollection
1669         addMETCollection(process,
1670                          labelName = "patCaloMet",
1671                          metSource = caloMetName
1672                          )
1673         getattr(process,"patCaloMet").addGenMET = False
1674 
1675         # extract DeepMETs (ResponseTune and ResolutionTune) from miniAOD
1676         if self._parameters["extractDeepMETs"].value:
1677             self.extractMET(process, "rawDeepResponseTune", patMetModuleSequence, postfix)
1678             deepMetResponseTuneName = "metrawDeepResponseTune" if hasattr(process, "metrawDeepResponseTune") else "metrawDeepResponseTune"+postfix
1679             addMETCollection(process,
1680                              labelName = "deepMETsResponseTune",
1681                              metSource = deepMetResponseTuneName
1682                             )
1683             getattr(process, "deepMETsResponseTune").addGenMET = False
1684             getattr(process, "deepMETsResponseTune").computeMETSignificance = cms.bool(False)
1685 
1686             self.extractMET(process, "rawDeepResolutionTune", patMetModuleSequence, postfix)
1687             deepMetResolutionTuneName = "metrawDeepResolutionTune" if hasattr(process, "metrawDeepResolutionTune") else "metrawDeepResolutionTune"+postfix
1688             addMETCollection(process,
1689                              labelName = "deepMETsResolutionTune",
1690                              metSource = deepMetResolutionTuneName
1691                             )
1692             getattr(process, "deepMETsResolutionTune").addGenMET = False
1693             getattr(process, "deepMETsResolutionTune").computeMETSignificance = cms.bool(False)
1694 
1695         ##adding the necessary chs and track met configuration
1696         task = getPatAlgosToolsTask(process)
1697 
1698         from CommonTools.ParticleFlow.pfCHS_cff import pfCHS
1699         addToProcessAndTask("pfCHS", pfCHS.clone(), process, task)
1700         from RecoMET.METProducers.pfMet_cfi import pfMet
1701         pfMetCHS = pfMet.clone(src = "pfCHS")
1702         addToProcessAndTask("pfMetCHS", pfMetCHS, process, task)
1703 
1704         addMETCollection(process,
1705                          labelName = "patCHSMet",
1706                          metSource = "pfMetCHS"
1707                          )
1708 
1709         process.patCHSMet.computeMETSignificant = cms.bool(False)
1710         process.patCHSMet.addGenMET = cms.bool(False)
1711 
1712         patMetModuleSequence += getattr(process, "pfCHS")
1713         patMetModuleSequence += getattr(process, "pfMetCHS")
1714         patMetModuleSequence += getattr(process, "patCHSMet")
1715         
1716         pfTrk = chargedPackedCandsForTkMet.clone()
1717         addToProcessAndTask("pfTrk", pfTrk, process, task)
1718         pfMetTrk = pfMet.clone(src = 'pfTrk')
1719         addToProcessAndTask("pfMetTrk", pfMetTrk, process, task)
1720 
1721         addMETCollection(process,
1722                          labelName = "patTrkMet",
1723                          metSource = "pfMetTrk"
1724                          )
1725 
1726         process.patTrkMet.computeMETSignificant = cms.bool(False)
1727         process.patTrkMet.addGenMET = cms.bool(False)
1728 
1729         patMetModuleSequence += getattr(process, "pfTrk")
1730         patMetModuleSequence += getattr(process, "pfMetTrk")
1731         patMetModuleSequence += getattr(process, "patTrkMet")
1732 
1733 
1734     def miniAODConfigurationPost(self, process, postfix):
1735 
1736         if self._parameters["metType"].value == "PF":
1737             if hasattr(process, "patPFMetTxyCorr"+postfix):
1738                 getattr(process, "patPFMetTxyCorr"+postfix).vertexCollection = cms.InputTag("offlineSlimmedPrimaryVertices")
1739 
1740         if self._parameters['computeUncertainties'].value and not self._parameters["runOnData"]:
1741             getattr(process, "shiftedPatJetResDown"+postfix).genJets = cms.InputTag("slimmedGenJets")
1742             getattr(process, "shiftedPatJetResUp"+postfix).genJets = cms.InputTag("slimmedGenJets")
1743 
1744 
1745     def miniAODConfiguration(self, process, pfCandCollection, jetCollection,
1746                              patMetModuleSequence, postfix ):
1747         if self._parameters["metType"].value == "PF": # not hasattr(process, "pfMet"+postfix)
1748             if "T1" in self._parameters['correctionLevel'].value:
1749                 getattr(process, "patPFMet"+postfix).srcJets = jetCollection
1750             getattr(process, "patPFMet"+postfix).addGenMET  = False
1751             if not self._parameters["runOnData"].value:
1752                 getattr(process, "patPFMet"+postfix).addGenMET  = True
1753                 getattr(process, "patPFMet"+postfix).genMETSource = cms.InputTag("genMetExtractor"+postfix)
1754 
1755 
1756         if "Smear" in self._parameters['correctionLevel'].value:
1757             getattr(process, "patSmearedJets"+postfix).genJets = cms.InputTag("slimmedGenJets")
1758 
1759         if not hasattr(process, "slimmedMETs"+postfix) and self._parameters["metType"].value == "PF":
1760 
1761             task = getPatAlgosToolsTask(process)
1762 
1763             from PhysicsTools.PatAlgos.slimming.slimmedMETs_cfi import slimmedMETs
1764             addToProcessAndTask("slimmedMETs"+postfix, slimmedMETs.clone(), process, task)
1765             getattr(process,"slimmedMETs"+postfix).src = cms.InputTag("patPFMetT1"+postfix)
1766             getattr(process,"slimmedMETs"+postfix).rawVariation = cms.InputTag("patPFMet"+postfix)
1767             getattr(process,"slimmedMETs"+postfix).t1Uncertainties = cms.InputTag("patPFMetT1%s"+postfix)
1768             getattr(process,"slimmedMETs"+postfix).t01Variation = cms.InputTag("patPFMetT0pcT1"+postfix)
1769             getattr(process,"slimmedMETs"+postfix).t1SmearedVarsAndUncs = cms.InputTag("patPFMetT1Smear%s"+postfix)
1770 
1771             getattr(process,"slimmedMETs"+postfix).tXYUncForRaw = cms.InputTag("patPFMetTxy"+postfix)
1772             getattr(process,"slimmedMETs"+postfix).tXYUncForT1 = cms.InputTag("patPFMetT1Txy"+postfix)
1773             getattr(process,"slimmedMETs"+postfix).tXYUncForT01 = cms.InputTag("patPFMetT0pcT1Txy"+postfix)
1774             getattr(process,"slimmedMETs"+postfix).tXYUncForT1Smear = cms.InputTag("patPFMetT1SmearTxy"+postfix)
1775             getattr(process,"slimmedMETs"+postfix).tXYUncForT01Smear = cms.InputTag("patPFMetT0pcT1SmearTxy"+postfix)
1776 
1777             getattr(process,"slimmedMETs"+postfix).runningOnMiniAOD = True
1778             getattr(process,"slimmedMETs"+postfix).t01Variation = cms.InputTag("slimmedMETs" if not self._parameters["Puppi"].value else "slimmedMETsPuppi",processName=cms.InputTag.skipCurrentProcess())
1779 
1780             if hasattr(process, "deepMETsResolutionTune") and hasattr(process, "deepMETsResponseTune"):
1781                 # process includes producing/extracting deepMETsResolutionTune and deepMETsResponseTune
1782                 # add them to the slimmedMETs
1783                 getattr(process,"slimmedMETs"+postfix).addDeepMETs = True
1784 
1785             #smearing and type0 variations not yet supported in reprocessing
1786             #del getattr(process,"slimmedMETs"+postfix).t1SmearedVarsAndUncs
1787             del getattr(process,"slimmedMETs"+postfix).tXYUncForRaw
1788             del getattr(process,"slimmedMETs"+postfix).tXYUncForT01
1789             del getattr(process,"slimmedMETs"+postfix).tXYUncForT1Smear
1790             del getattr(process,"slimmedMETs"+postfix).tXYUncForT01Smear
1791             #del getattr(process,"slimmedMETs"+postfix).caloMET
1792 
1793 
1794     def jetConfiguration(self):
1795 
1796         jetFlavor = self._parameters["jetFlavor"].value
1797         jetCorr = self._parameters["jetCorrectionType"].value
1798 
1799         jetCorLabelUpToL3Name="ak4PF"
1800         jetCorLabelL3ResName="ak4PF"
1801 
1802         # normal or CHS jets =============================
1803         if "chs" in jetFlavor:
1804             self.setParameter("CHS",True)
1805             jetCorLabelUpToL3Name += "CHS" #chs
1806             jetCorLabelL3ResName += "CHS"
1807         elif "Puppi" in jetFlavor:
1808             self.setParameter("CHS",False)
1809             jetCorLabelUpToL3Name += "Puppi"
1810             jetCorLabelL3ResName += "Puppi"
1811 
1812         else:
1813             self.setParameter("CHS",False)
1814 
1815         # change the correction type =====================
1816         if jetCorr == "L1L2L3-L1":
1817             jetCorLabelUpToL3Name += "L1FastL2L3Corrector"
1818             jetCorLabelL3ResName  += "L1FastL2L3ResidualCorrector"
1819         elif jetCorr == "L1L2L3-RC": #to be fixed
1820             jetCorLabelUpToL3Name += "L1FastL2L3Corrector"
1821             jetCorLabelL3ResName  += "L1FastL2L3ResidualCorrector"
1822 
1823         self.setParameter("jetCorLabelUpToL3",jetCorLabelUpToL3Name )
1824         self.setParameter("jetCorLabelL3Res",jetCorLabelL3ResName )
1825 
1826     # function enabling the auto jet cleaning for uncertainties ===============
1827     def jetCleaning(self, process, jetCollectionName, autoJetCleaning, jetProductionSequence, postfix ):
1828 
1829         if autoJetCleaning == "None" or autoJetCleaning == "Manual" :
1830             return cms.InputTag(jetCollectionName)
1831 
1832         #retrieve collections
1833         electronCollection = self._parameters["electronCollection"].value
1834         muonCollection = self._parameters["muonCollection"].value
1835         photonCollection = self._parameters["photonCollection"].value
1836         tauCollection = self._parameters["tauCollection"].value
1837 
1838         task = getPatAlgosToolsTask(process)
1839 
1840         if autoJetCleaning == "Full" : # auto clean taus, photons and jets
1841             if isValidInputTag(tauCollection):
1842                 process.load("PhysicsTools.PatAlgos.cleaningLayer1.tauCleaner_cfi")
1843                 task.add(process.cleanPatTaus)
1844                 cleanPatTauProducer = getattr(process, "cleanPatTaus").clone(
1845                     src = tauCollection
1846                     )
1847                 cleanPatTauProducer.checkOverlaps.electrons.src = electronCollection
1848                 cleanPatTauProducer.checkOverlaps.muons.src = muonCollection
1849                 addToProcessAndTask("cleanedPatTaus"+postfix, cleanPatTauProducer, process, task)
1850                 jetProductionSequence += getattr(process, "cleanedPatTaus"+postfix)
1851                 tauCollection = cms.InputTag("cleanedPatTaus"+postfix)
1852 
1853             if isValidInputTag(photonCollection):
1854                 process.load("PhysicsTools.PatAlgos.cleaningLayer1.photonCleaner_cfi")
1855                 task.add(process.cleanPatPhotons)
1856                 cleanPatPhotonProducer = getattr(process, "cleanPatPhotons").clone(
1857                     src = photonCollection
1858                     )
1859                 cleanPatPhotonProducer.checkOverlaps.electrons.src = electronCollection
1860                 addToProcessAndTask("cleanedPatPhotons"+postfix, cleanPatPhotonProducer, process, task)
1861                 jetProductionSequence += getattr(process, "cleanedPatPhotons"+postfix)
1862                 photonCollection = cms.InputTag("cleanedPatPhotons"+postfix)
1863 
1864         #jet cleaning
1865         have_cleanPatJets = hasattr(process, "cleanPatJets")
1866         process.load("PhysicsTools.PatAlgos.cleaningLayer1.jetCleaner_cfi")
1867         cleanPatJetProducer = getattr(process, "cleanPatJets").clone(
1868                      src = cms.InputTag(jetCollectionName)
1869             )
1870         #do not leave it hanging
1871         if not have_cleanPatJets:
1872             del process.cleanPatJets
1873         cleanPatJetProducer.checkOverlaps.muons.src = muonCollection
1874         cleanPatJetProducer.checkOverlaps.electrons.src = electronCollection
1875         if isValidInputTag(photonCollection) and autoJetCleaning != "LepClean":
1876             cleanPatJetProducer.checkOverlaps.photons.src = photonCollection
1877         else:
1878             del cleanPatJetProducer.checkOverlaps.photons
1879 
1880         if isValidInputTag(tauCollection) and autoJetCleaning != "LepClean":
1881             cleanPatJetProducer.checkOverlaps.taus.src = tauCollection
1882         else:
1883             del cleanPatJetProducer.checkOverlaps.taus
1884 
1885         # not used at all and electrons are already cleaned
1886         del cleanPatJetProducer.checkOverlaps.tkIsoElectrons
1887 
1888         addToProcessAndTask("cleanedPatJets"+postfix, cleanPatJetProducer, process, task)
1889         jetProductionSequence += getattr(process, "cleanedPatJets"+postfix)
1890         return cms.InputTag("cleanedPatJets"+postfix)
1891 
1892     # function to implement the 2017 EE fix
1893     def runFixEE2017(self,process,params,jets,cands,goodcolls,patMetModuleSequence,postfix):
1894 
1895         task = getPatAlgosToolsTask(process)
1896 
1897         pfCandidateJetsWithEEnoise = _modbad.BadPFCandidateJetsEEnoiseProducer.clone(
1898             jetsrc = jets,
1899             userawPt = params["userawPt"],
1900             ptThreshold = params["ptThreshold"],
1901             minEtaThreshold = params["minEtaThreshold"],
1902             maxEtaThreshold = params["maxEtaThreshold"],
1903         )
1904         addToProcessAndTask("pfCandidateJetsWithEEnoise"+postfix, pfCandidateJetsWithEEnoise, process, task)
1905         patMetModuleSequence += getattr(process,"pfCandidateJetsWithEEnoise"+postfix)
1906         pfcandidateClustered = cms.EDProducer("CandViewMerger",
1907             src = cms.VInputTag(goodcolls+[jets])
1908         )
1909         addToProcessAndTask("pfcandidateClustered"+postfix, pfcandidateClustered, process, task)
1910         patMetModuleSequence += getattr(process,"pfcandidateClustered"+postfix)
1911         pfcandidateForUnclusteredUnc = _mod.candPtrProjector.clone(
1912             src  = cands,
1913             veto = "pfcandidateClustered"+postfix,
1914         )
1915         addToProcessAndTask("pfcandidateForUnclusteredUnc"+postfix, pfcandidateForUnclusteredUnc, process, task)
1916         patMetModuleSequence += getattr(process,"pfcandidateForUnclusteredUnc"+postfix)
1917         badUnclustered = cms.EDFilter("CandPtrSelector",
1918             src = cms.InputTag("pfcandidateForUnclusteredUnc"+postfix),
1919             cut = cms.string("abs(eta) > "+str(params["minEtaThreshold"])+" && abs(eta) < "+str(params["maxEtaThreshold"])),
1920         )
1921         addToProcessAndTask("badUnclustered"+postfix, badUnclustered, process, task)
1922         patMetModuleSequence += getattr(process,"badUnclustered"+postfix)
1923         blobUnclustered = _modunc.UnclusteredBlobProducer.clone(
1924             candsrc = "badUnclustered"+postfix,
1925         )
1926         addToProcessAndTask("blobUnclustered"+postfix, blobUnclustered, process, task)
1927         patMetModuleSequence += getattr(process,"blobUnclustered"+postfix)
1928         superbad = cms.EDProducer("CandViewMerger",
1929             src = cms.VInputTag(
1930                 cms.InputTag("blobUnclustered"+postfix),
1931                 cms.InputTag("pfCandidateJetsWithEEnoise"+postfix,"bad"),
1932             )
1933         )
1934         addToProcessAndTask("superbad"+postfix, superbad, process, task)
1935         patMetModuleSequence += getattr(process,"superbad"+postfix)
1936         pfCandidatesGoodEE2017 = _mod.candPtrProjector.clone(
1937             src  = cands,
1938             veto = "superbad"+postfix,
1939         )
1940         addToProcessAndTask("pfCandidatesGoodEE2017"+postfix, pfCandidatesGoodEE2017, process, task)
1941         patMetModuleSequence += getattr(process,"pfCandidatesGoodEE2017"+postfix)
1942         # return good cands and jets
1943         return (cms.InputTag("pfCandidatesGoodEE2017"+postfix), cms.InputTag("pfCandidateJetsWithEEnoise"+postfix,"good"))
1944 
1945 #========================================================================================
1946 runMETCorrectionsAndUncertainties = RunMETCorrectionsAndUncertainties()
1947 
1948 
1949 
1950 #predefined functions for miniAOD production and reproduction
1951 # miniAOD production ===========================
1952 def runMetCorAndUncForMiniAODProduction(process, metType="PF",
1953                                         jetCollUnskimmed="patJets",
1954                                         photonColl="selectedPatPhotons",
1955                                         electronColl="selectedPatElectrons",
1956                                         muonColl="selectedPatMuons",
1957                                         tauColl="selectedPatTaus",
1958                                         pfCandColl = "particleFlow",
1959                                         jetCleaning="LepClean",
1960                                         jetSelection="pt>15 && abs(eta)<9.9",
1961                                         jecUnFile="",
1962                                         jetFlavor="AK4PFchs",
1963                                         recoMetFromPFCs=False,
1964                                         postfix=""):
1965 
1966     runMETCorrectionsAndUncertainties = RunMETCorrectionsAndUncertainties()
1967 
1968     #MET flavors
1969     runMETCorrectionsAndUncertainties(process, metType=metType,
1970                                       correctionLevel=["T0","T1","T2","Smear","Txy"],
1971                                       computeUncertainties=False,
1972                                       produceIntermediateCorrections=True,
1973                                       addToPatDefaultSequence=False,
1974                                       jetCollectionUnskimmed=jetCollUnskimmed,
1975                                       photonCollection=photonColl,
1976                                       electronCollection=electronColl,
1977                                       muonCollection=muonColl,
1978                                       tauCollection=tauColl,
1979                                       pfCandCollection =pfCandColl,
1980                                       autoJetCleaning=jetCleaning,
1981                                       jecUncertaintyFile=jecUnFile,
1982                                       jetSelection=jetSelection,
1983                                       jetFlavor=jetFlavor,
1984                                       recoMetFromPFCs=recoMetFromPFCs,
1985                                       postfix=postfix
1986                                       )
1987 
1988     #MET T1 uncertainties
1989     runMETCorrectionsAndUncertainties(process, metType=metType,
1990                                       correctionLevel=["T1"],
1991                                       computeUncertainties=True,
1992                                       produceIntermediateCorrections=False,
1993                                       addToPatDefaultSequence=False,
1994                                       jetCollectionUnskimmed=jetCollUnskimmed,
1995                                       photonCollection=photonColl,
1996                                       electronCollection=electronColl,
1997                                       muonCollection=muonColl,
1998                                       tauCollection=tauColl,
1999                                       pfCandCollection =pfCandColl,
2000                                       autoJetCleaning=jetCleaning,
2001                                       jecUncertaintyFile=jecUnFile,
2002                                       jetSelection=jetSelection,
2003                                       jetFlavor=jetFlavor,
2004                                       recoMetFromPFCs=recoMetFromPFCs,
2005                                       postfix=postfix
2006                                       )
2007 
2008     #MET T1 Smeared JER uncertainties
2009     runMETCorrectionsAndUncertainties(process, metType=metType,
2010                                       correctionLevel=["T1","Smear"],
2011                                       computeUncertainties=True,
2012                                       produceIntermediateCorrections=False,
2013                                       addToPatDefaultSequence=False,
2014                                       jetCollectionUnskimmed=jetCollUnskimmed,
2015                                       photonCollection=photonColl,
2016                                       electronCollection=electronColl,
2017                                       muonCollection=muonColl,
2018                                       tauCollection=tauColl,
2019                                       pfCandCollection =pfCandColl,
2020                                       autoJetCleaning=jetCleaning,
2021                                       jecUncertaintyFile=jecUnFile,
2022                                       jetSelection=jetSelection,
2023                                       jetFlavor=jetFlavor,
2024                                       recoMetFromPFCs=recoMetFromPFCs,
2025                                       postfix=postfix,
2026                                       )
2027 
2028 
2029 
2030 
2031 # miniAOD reproduction ===========================
2032 def runMetCorAndUncFromMiniAOD(process, metType="PF",
2033                                jetCollUnskimmed="slimmedJets",
2034                                photonColl="slimmedPhotons",
2035                                electronColl="slimmedElectrons",
2036                                muonColl="slimmedMuons",
2037                                tauColl="slimmedTaus",
2038                                pfCandColl = "packedPFCandidates",
2039                                jetFlavor="AK4PFchs",
2040                                jetCleaning="LepClean",
2041                                isData=False,
2042                                manualJetConfig=False,
2043                                reclusterJets=None,
2044                                jetSelection="pt>15 && abs(eta)<9.9",
2045                                recoMetFromPFCs=None,
2046                                jetCorLabelL3="ak4PFCHSL1FastL2L3Corrector",
2047                                jetCorLabelRes="ak4PFCHSL1FastL2L3ResidualCorrector",
2048 ##                               jecUncFile="CondFormats/JetMETObjects/data/Summer15_50nsV5_DATA_UncertaintySources_AK4PFchs.txt",
2049                                CHS=False,
2050                                reapplyJEC=True,
2051                                jecUncFile="",
2052                                computeMETSignificance=True,
2053                                fixEE2017=False,
2054                                fixEE2017Params=None,
2055                                extractDeepMETs=False,
2056                                postfix=""):
2057 
2058     runMETCorrectionsAndUncertainties = RunMETCorrectionsAndUncertainties()
2059 
2060     #MET T1 uncertainties
2061     runMETCorrectionsAndUncertainties(process, metType=metType,
2062                                       correctionLevel=["T1"],
2063                                       computeUncertainties=True,
2064                                       produceIntermediateCorrections=False,
2065                                       addToPatDefaultSequence=False,
2066                                       jetCollectionUnskimmed=jetCollUnskimmed,
2067                                       electronCollection=electronColl,
2068                                       muonCollection=muonColl,
2069                                       tauCollection=tauColl,
2070                                       photonCollection=photonColl,
2071                                       pfCandCollection =pfCandColl,
2072                                       runOnData=isData,
2073                                       onMiniAOD=True,
2074                                       reapplyJEC=reapplyJEC,
2075                                       reclusterJets=reclusterJets,
2076                                       jetSelection=jetSelection,
2077                                       recoMetFromPFCs=recoMetFromPFCs,
2078                                       autoJetCleaning=jetCleaning,
2079                                       manualJetConfig=manualJetConfig,
2080                                       jetFlavor=jetFlavor,
2081                                       jetCorLabelUpToL3=jetCorLabelL3,
2082                                       jetCorLabelL3Res=jetCorLabelRes,
2083                                       jecUncertaintyFile=jecUncFile,
2084                                       computeMETSignificance=computeMETSignificance,
2085                                       CHS=CHS,
2086                                       postfix=postfix,
2087                                       fixEE2017=fixEE2017,
2088                                       fixEE2017Params=fixEE2017Params,
2089                                       extractDeepMETs=extractDeepMETs,
2090                                       )
2091 
2092     #MET T1+Txy / Smear
2093     runMETCorrectionsAndUncertainties(process, metType=metType,
2094                                       correctionLevel=["T1","Txy"],
2095                                       computeUncertainties=False,
2096                                       produceIntermediateCorrections=True,
2097                                       addToPatDefaultSequence=False,
2098                                       jetCollectionUnskimmed=jetCollUnskimmed,
2099                                       electronCollection=electronColl,
2100                                       muonCollection=muonColl,
2101                                       tauCollection=tauColl,
2102                                       photonCollection=photonColl,
2103                                       pfCandCollection =pfCandColl,
2104                                       runOnData=isData,
2105                                       onMiniAOD=True,
2106                                       reapplyJEC=reapplyJEC,
2107                                       reclusterJets=reclusterJets,
2108                                       jetSelection=jetSelection,
2109                                       recoMetFromPFCs=recoMetFromPFCs,
2110                                       autoJetCleaning=jetCleaning,
2111                                       manualJetConfig=manualJetConfig,
2112                                       jetFlavor=jetFlavor,
2113                                       jetCorLabelUpToL3=jetCorLabelL3,
2114                                       jetCorLabelL3Res=jetCorLabelRes,
2115                                       jecUncertaintyFile=jecUncFile,
2116                                       computeMETSignificance=computeMETSignificance,
2117                                       CHS=CHS,
2118                                       postfix=postfix,
2119                                       fixEE2017=fixEE2017,
2120                                       fixEE2017Params=fixEE2017Params,
2121                                       extractDeepMETs=extractDeepMETs,
2122                                       )
2123     #MET T1+Smear + uncertainties
2124     runMETCorrectionsAndUncertainties(process, metType=metType,
2125                                       correctionLevel=["T1","Smear"],
2126                                       computeUncertainties=True,
2127                                       produceIntermediateCorrections=False,
2128                                       addToPatDefaultSequence=False,
2129                                       jetCollectionUnskimmed=jetCollUnskimmed,
2130                                       electronCollection=electronColl,
2131                                       muonCollection=muonColl,
2132                                       tauCollection=tauColl,
2133                                       photonCollection=photonColl,
2134                                       pfCandCollection =pfCandColl,
2135                                       runOnData=isData,
2136                                       onMiniAOD=True,
2137                                       reapplyJEC=reapplyJEC,
2138                                       reclusterJets=reclusterJets,
2139                                       jetSelection=jetSelection,
2140                                       recoMetFromPFCs=recoMetFromPFCs,
2141                                       autoJetCleaning=jetCleaning,
2142                                       manualJetConfig=manualJetConfig,
2143                                       jetFlavor=jetFlavor,
2144                                       jetCorLabelUpToL3=jetCorLabelL3,
2145                                       jetCorLabelL3Res=jetCorLabelRes,
2146                                       jecUncertaintyFile=jecUncFile,
2147                                       computeMETSignificance=computeMETSignificance,
2148                                       CHS=CHS,
2149                                       postfix=postfix,
2150                                       fixEE2017=fixEE2017,
2151                                       fixEE2017Params=fixEE2017Params,
2152                                       extractDeepMETs=extractDeepMETs,
2153                                       )