def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary = cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryRecoDB_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load("Configuration.StandardSequences.MagneticField_cff")
    process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
        inputCommands = cms.untracked.vstring("keep *", "drop *_MEtoEDMConverter_*_*"),
        fileNames = cms.untracked.vstring()
    )

    # Scraping filter
    process.scrapingFilter = cms.EDFilter("FilterOutScraping",
        applyfilter = cms.untracked.bool(True),
        debugOn = cms.untracked.bool(False),
        numtrack = cms.untracked.uint32(10),
        thresh = cms.untracked.double(0.25)
    )

    IN_ACCEPTANCE = '((abs(eta) <= 1.3 && pt > 3.3) || (1.3 < abs(eta) <= 2.2 && p > 2.9) || (2.2 < abs(eta) <= 2.4 && pt > 0.8))'

    # Merge muons, calomuons in a single collection for T&P
    process.mergedMuons = cms.EDProducer("CaloMuonMerger",
        muons     = cms.InputTag("muons"), 
        muonsCut = cms.string(""),
        mergeCaloMuons = cms.bool(True),  ### NEEDED TO RUN ON AOD
        caloMuons = cms.InputTag("calomuons"),
        caloMuonsCut = cms.string(IN_ACCEPTANCE),
        minCaloCompatibility = cms.double(0.6),
        mergeTracks = cms.bool(False),
        tracks = cms.InputTag("generalTracks"),
	tracksCut = cms.string(IN_ACCEPTANCE),
    )


    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer("GenParticlePruner",
        src = cms.InputTag("genParticles"),
        select = cms.vstring(
            "drop  *  ",                     # this is the default
            "++keep abs(pdgId) = 13",        # keep muons and their parents
            "drop pdgId == 21 && status = 2" # remove intermediate qcd spam carrying no flavour info
        )
    )

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(process) # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    #useL1MatchingWindowForSinglets(process)

    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0


    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.hltOniaHI *
        process.PAcollisionEventSelection *
        process.genMuons *
        process.patMuonsWithTriggerSequence
    )
    if not MC:
        process.patMuonSequence.remove(process.genMuons)
      
    # Make dimuon candidates
    process.onia2MuMuPatTrkTrk = cms.EDProducer('HiOnia2MuMuPAT',
        muons = cms.InputTag("patMuonsWithTrigger"),
     #   muons = cms.InputTag("patMuons"),
        beamSpotTag = cms.InputTag("offlineBeamSpot"),
        primaryVertexTag = cms.InputTag("offlinePrimaryVertices"),
        # At least one muon must pass this selection
        higherPuritySelection = cms.string("(isGlobalMuon || isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        # BOTH muons must pass this selection
        lowerPuritySelection  = cms.string("(isGlobalMuon || isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        dimuonSelection  = cms.string(""), ## The dimuon must pass this selection before vertexing
        addCommonVertex = cms.bool(True), ## Embed the full reco::Vertex out of the common vertex fit
        addMuonlessPrimaryVertex = cms.bool(True), ## Embed the primary vertex re-made from all the tracks except the two muons
        addMCTruth = cms.bool(MC),      ## Add the common MC mother of the two muons, if any
        resolvePileUpAmbiguity = cms.bool(True)   ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
    )

    # check if there is at least one (inclusive) tracker+tracker di-muon
    process.onia2MuMuPatTrkTrkFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('onia2MuMuPatTrkTrk'),
        minNumber = cms.uint32(1),
    )

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(
        process.patMuonSequence *
        process.onia2MuMuPatTrkTrk *
        process.onia2MuMuPatTrkTrkFilter
    )

    # Make Tag and Probe pairs for efficiency measurements
    TRACK_CUTS = "(track.hitPattern.trackerLayersWithMeasurement > 5 && track.normalizedChi2 < 1.8 && track.hitPattern.pixelLayersWithMeasurement > 1 && abs(dB) < 3 && abs(track.dz) < 15)"
    GLB_CUTS = "(isTrackerMuon && muonID('TrackerMuonArbitrated') && muonID('TMOneStationTight'))"
    QUALITY_CUTS =  "(" + GLB_CUTS + ' && ' + TRACK_CUTS + ")"

    process.tagMuonsSglTrg = cms.EDFilter("PATMuonSelector",
                                       src = cms.InputTag("patMuonsWithTrigger"),
                                       cut = cms.string(QUALITY_CUTS + ' && ' + IN_ACCEPTANCE + " && (!triggerObjectMatchesByPath('HLT_PAMu3_v*').empty() || !triggerObjectMatchesByPath('HLT_PAMu7_v*').empty() || !triggerObjectMatchesByPath('HLT_PAMu12_v*').empty())")
                                       )

    process.tagMuonsDblTrg = cms.EDFilter("PATMuonSelector",
                                       src = cms.InputTag("patMuonsWithTrigger"),
                                       cut = cms.string(QUALITY_CUTS + ' && ' + IN_ACCEPTANCE + " && !triggerObjectMatchesByPath('HLT_PAL1DoubleMuOpen_v*').empty()")
                                       )

    # produce patMuons that use the STA momentum information
    process.patMuonsWithTriggerSta = cms.EDProducer("RedefineMuonP4FromTrackPAT",
                                                    src   = cms.InputTag("patMuonsWithTrigger"),
                                                    track = cms.string("outer")
                                                    )

    # must be STA, so we can measure inner tracking efficiency
    process.probeMuonsSta = cms.EDFilter("PATMuonSelector",
                                         src = cms.InputTag("patMuonsWithTriggerSta"),
                                         cut = cms.string("outerTrack.isNonnull")
                                         )

    process.tpPairsSta = cms.EDProducer("CandViewShallowCloneCombiner",
                                        cut = cms.string('2.0 < mass < 5.0'),
                                        decay = cms.string('tagMuonsDblTrg@+ probeMuonsSta@-')
                                        )

    # must be a GLB to measure trigger efficiency
    process.probeMuons = cms.EDFilter("PATMuonSelector",
                                      src = cms.InputTag("patMuonsWithTrigger"),
                                      cut = cms.string(QUALITY_CUTS + ' && ' + IN_ACCEPTANCE)
                                      )

    process.tpPairsTrig = cms.EDProducer("CandViewShallowCloneCombiner",
                                     cut = cms.string('2.6 < mass < 4.0'),
                                     decay = cms.string('tagMuonsSglTrg@+ probeMuons@-')
                                     )

    # must be tracker muon, so we can measure the muon reco efficiency
    # since we're using tracker muons this year, we should use calo muons as probes here
    process.probeMuonsTrk = cms.EDFilter("PATMuonSelector",
                                         src = cms.InputTag("patMuonsWithTrigger"),
                                         #cut = cms.string("isCaloMuon && " + TRACK_CUTS)
                                         cut = cms.string("caloCompatibility>0.6 && innerTrack.isNonnull && " + TRACK_CUTS)
                                         )

    process.tpPairsTracks = cms.EDProducer("CandViewShallowCloneCombiner",
                                           cut = cms.string('2.6 < mass < 4.0'),
                                           decay = cms.string('tagMuonsDblTrg@+ probeMuonsTrk@-')
                                           )

    # check if there is at least one Tag and Probe pair
    process.tpPairsStaFilter = cms.EDFilter("CandViewCountFilter",
                                            src = cms.InputTag('tpPairsSta'),
                                            minNumber = cms.uint32(1),
                                            )

    process.tpPairsTrigFilter = cms.EDFilter("CandViewCountFilter",
                                             src = cms.InputTag('tpPairsTrig'),
                                             minNumber = cms.uint32(1),
                                             )

    process.tpPairsTracksFilter = cms.EDFilter("CandViewCountFilter",
                                               src = cms.InputTag('tpPairsTracks'),
                                               minNumber = cms.uint32(1),
                                               )
    
    # the Tag and Probe path
    process.tnpSta = cms.Sequence(
        process.probeMuonsSta *
        process.tpPairsSta *
        process.tpPairsStaFilter
        )

    process.tnpTrig = cms.Sequence(
        process.probeMuons *
        process.tpPairsTrig *
        process.tpPairsTrigFilter
        )

    process.tnpMuID = cms.Sequence(
        process.probeMuonsTrk *
        process.tpPairsTracks *
        process.tpPairsTracksFilter
        )

    # inner track reco efficiency
    process.TagAndProbeSta = cms.Path(
        process.patMuonSequence *
        process.tagMuonsDblTrg *
        process.patMuonsWithTriggerSta *
        process.tnpSta
    )

    # muon reco and ID efficiency
    process.TagAndProbeMuID = cms.Path(
        process.patMuonSequence *
        process.tagMuonsDblTrg *
        process.tnpMuID
    )

    # muon trigger efficiency
    process.TagAndProbeTrig = cms.Path(
        process.patMuonSequence *
        process.tagMuonsSglTrg *
        process.tnpTrig
    )
    
    if MC:
        process.tagMuonsDblTrgMCMatch = process.muonMatch.clone(src = "tagMuonsDblTrg")
        process.tagMuonsSglTrgMCMatch = process.muonMatch.clone(src = "tagMuonsSglTrg")
        process.probeMuonsStaMCMatch = process.tagMuonsDblTrgMCMatch.clone(src = "probeMuonsSta") # inner tracking eff
        process.probeMuonsTrkMCMatch = process.tagMuonsDblTrgMCMatch.clone(src = "probeMuonsTrk") # Muon reco and ID eff
        process.probeMuonsMCMatch = process.tagMuonsSglTrgMCMatch.clone(src = "probeMuons") # muon trigger eff
        process.TagAndProbeSta.replace(process.tpPairsSta, process.tagMuonsDblTrgMCMatch * process.probeMuonsStaMCMatch * process.tpPairsSta)
        process.TagAndProbeMuID.replace(process.tpPairsTracks, process.tagMuonsDblTrgMCMatch * process.probeMuonsTrkMCMatch * process.tpPairsTracks)
        process.TagAndProbeTrig.replace(process.tpPairsTrig, process.tagMuonsSglTrgMCMatch * process.probeMuonsMCMatch * process.tpPairsTrig)
    
    # output
    process.load('Configuration.EventContent.EventContent_cff')
    
    process.outOnia2MuMu = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands =  cms.untracked.vstring('drop *'),
                                                
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('Onia2MuMuPAT') ) if Filter else cms.untracked.PSet()
    )

    process.outOnia2MuMu.outputCommands.extend(cms.untracked.vstring(
        'keep *_mergedtruth_*_*',                              # tracking particles and tracking vertices for hit by hit matching
        'keep *_genParticles_*_*',                             # generated particles
        'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
        'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muons including matches to triggers
     #   'keep patMuons_*__Onia2MuMuPAT',    # All PAT muons including matches to triggers
        'keep patCompositeCandidates_*__Onia2MuMuPAT',         # PAT di-muons
        'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
        'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
        'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
        'keep l1extraL1MuonParticles_hltL1extraParticles_*_*', # L1 info (cheap)
        'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
        'keep *_offlinePrimaryVertices_*_*',
        'keep *_pACentrality_*_*',
        'keep *_generalTracks_*_*',
        'keep *_towerMaker_*_*',
        'keep *_standAloneMuons_*_*')
                            ),

    process.outTnP = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('tnp.root'),
        outputCommands = cms.untracked.vstring('drop *',
            'keep *_genParticles_*_*',                             # generated particles
            'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
            'keep *_tagMuonsDblTrgMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            'keep *_tagMuonsSglTrgMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            'keep *_probeMuonsMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep patMuons_patMuonsWithTriggerSta__Onia2MuMuPAT',    # All PAT muons including matches to triggers
            'keep patMuons_tagMuonsDblTrg__Onia2MuMuPAT',                # tagMuons for efficiency
            'keep patMuons_tagMuonsSglTrg__Onia2MuMuPAT',                # tagMuons for efficiency
            'keep patMuons_probeMuonsSta__Onia2MuMuPAT',           # probeMuons for efficiency
            'keep patMuons_probeMuonsTrk__Onia2MuMuPAT',                    # probeTracks for efficiency
            'keep patMuons_probeMuons__Onia2MuMuPAT',              # probeMuons for efficiency
            'keep *_probeMuonsStaMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep *_probeMuonsTrkMCMatch__Onia2MuMuPAT',              # probeTacks MC matches for efficiency
            'keep recoCompositeCandidates_tpPairsSta__Onia2MuMuPAT',        # RECO di-muons, tpPairs for tracking efficiency
            'keep recoCompositeCandidates_tpPairsTracks__Onia2MuMuPAT',        # RECO di-muons, tpPairs for muon ID and reco efficiency
            'keep recoCompositeCandidates_tpPairsTrig__Onia2MuMuPAT',        # RECO di-muons, tpPairs for trigger efficiency
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_hltL1extraParticles_*_*', # L1 info (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
            'keep *_pACentrality_*_*',
            'keep *_generalTracks_*_*',
            'keep *_standAloneMuons_*_*'                           # standAloneMuon track collection, to be on the safe side
        ),
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('TagAndProbeSta','TagAndProbeMuID','TagAndProbeTrig') ) if Filter else cms.untracked.PSet()
    )

    process.e = cms.EndPath(process.outOnia2MuMu + process.outTnP)
Example #2
0
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary=cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryRecoDB_cff')
    process.load('Configuration.StandardSequences.MagneticField_38T_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load(
        "Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
                                inputCommands=cms.untracked.vstring(
                                    "keep *", "drop *_MEtoEDMConverter_*_*"),
                                fileNames=cms.untracked.vstring())

    # Scraping filter
    process.scrapingFilter = cms.EDFilter("FilterOutScraping",
                                          applyfilter=cms.untracked.bool(True),
                                          debugOn=cms.untracked.bool(False),
                                          numtrack=cms.untracked.uint32(10),
                                          thresh=cms.untracked.double(0.25))

    # Merge muons
    process.mergedMuons = cms.EDProducer(
        "CaloMuonMerger",
        muons=cms.InputTag("muons"),
        muonsCut=cms.string(""),
        mergeCaloMuons=cms.bool(False),  ### NEEDED TO RUN ON AOD
        caloMuons=cms.InputTag("calomuons"),
        caloMuonsCut=cms.string(""),
        minCaloCompatibility=cms.double(0.6),
        mergeTracks=cms.bool(True),
        tracks=cms.InputTag("generalTracks"),
        # tracksCut = cms.string("pt > 0.5")
        tracksCut=cms.string(
            "(abs(eta) <= 0.9 && pt > 2.5) || (0.9 < abs(eta) <=2.4 && pt > 1.5)"
        ),
    )

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer(
        "GenParticlePruner",
        src=cms.InputTag("genParticles"),
        select=cms.vstring(
            "drop  *  ",  # this is the default
            "++keep abs(pdgId) = 13",  # keep muons and their parents
            "drop pdgId == 21 && status = 2"  # remove intermediate qcd spam carrying no flavour info
        ))

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeRecoMuonInput(process, "mergedMuons")
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(
        process
    )  # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    #useL1MatchingWindowForSinglets(process)
    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0

    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.scrapingFilter * process.mergedMuons * process.genMuons *
        process.patMuonsWithTriggerSequence)
    if not MC:
        process.patMuonSequence.remove(process.genMuons)

    # Make dimuon candidates
    process.onia2MuMuPatTrkTrk = cms.EDProducer(
        'Onia2MuMuPAT',
        muons=cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag=cms.InputTag("offlineBeamSpot"),
        primaryVertexTag=cms.InputTag("offlinePrimaryVertices"),
        # At least one muon must pass this selection
        higherPuritySelection=cms.string(
            "(isGlobalMuon || isTrackerMuon) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"
        ),
        # BOTH muons must pass this selection
        lowerPuritySelection=cms.string(
            "(isGlobalMuon || isTrackerMuon) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"
        ),
        # The dimuon must pass this selection before vertexing
        dimuonSelection=cms.string("4.5 < mass && mass < 6.3"),
        # Embed the full reco::Vertex out of the common vertex fit
        addCommonVertex=cms.bool(True),
        # Embed the primary vertex re-made from all the tracks except the two muons
        addMuonlessPrimaryVertex=cms.bool(True),
        # Add the common MC mother of the two muons, if any
        addMCTruth=cms.bool(MC),
        # Order PVs by their vicinity to the J/psi vertex, not by sumPt
        resolvePileUpAmbiguity=cms.bool(True),
        addThirdTrack=cms.bool(
            False
        ),  ## search a third track making a good vertex with the dimuon
        minTrackPt=cms.double(0.5),  ## minimum pt of the third track
        trackMass=cms.double(0.4936),  ## mass for the track
        diMuPlusTrackMassMax=cms.double(5.9),
        diMuPlusTrackMassMin=cms.double(4.9),
        diMuMassMax=cms.double(
            3.2),  ## dimuon mass range where to search for the third track
        diMuMassMin=cms.double(2.8),
        # track selection, taken from https://cmssdt.cern.ch/SDT/lxr/source/Validation/RecoVertex/test/redoPV_cfg.py#040
        TkFilterParameters=cms.PSet(
            algorithm=cms.string('filterWithThreshold'),
            maxNormalizedChi2=cms.double(5.0),
            minSiliconLayersWithHits=cms.int32(
                0),  ## >=0 (was 5 for generalTracks)
            minPixelLayersWithHits=cms.int32(
                2),  ## >=2 (was 2 for generalTracks)
            maxD0Significance=cms.double(
                3.0),  ## keep most primary tracks (was 5.0)
            minPt=cms.double(0.0),  ## better for softish events
            trackQuality=cms.string("any"),
            numTracksThreshold=cms.int32(2)
            #          minPt = cms.double(0.0),                   # direct pt cut
            #          maxD0Significance = cms.double(5.0),       # impact parameter significance
            #          maxNormalizedChi2 = cms.double(5.0),       # loose cut on track chi**2
            #          minPixelLayersWithHits = cms.int32(2),     # two or more pixel layers
            #          minSiliconLayersWithHits = cms.int32(5),   # five or more tracker layers (includes pixels)
            #          trackQuality = cms.string("any")           # track quality not used
        ),
        # track clustering, taken from https://cmssdt.cern.ch/SDT/lxr/source/Validation/RecoVertex/test/redoPV_cfg.py#076
        TkDAClusParameters=cms.PSet(
            coolingFactor=cms.double(0.8),  #  slow annealing
            Tmin=cms.double(4.0),  #  freezeout temperature
            vertexSize=cms.double(0.05)  #  ~ resolution / sqrt(Tmin)
        ),
        # Preselection cuts
        # userInt('Ntrk') < 21 &&
        preselection=cms.string(
            "userFloat('kinMass') > 4.5 && userFloat('kinMass') < 6.3 && pt > 5. && pt < 9999. && daughter('muon1').pt > 4. && daughter('muon1').pt < 999. && daughter('muon2').pt > 4. && daughter('muon2').pt < 999. && userFloat('l3d') < 2. && userFloat('l3dsig') > 0. && userFloat('l3dsig') < 200. && userFloat('vNChi2') < 20. && userFloat('delta3d') < 0.1 && userFloat('delta3d')/userFloat('delta3dErr') < 5. && userFloat('DCA') < 0.1 && acos(userFloat('cosAlpha3D')) < 1.0 && userFloat('minDca') < 2.50 && userFloat('Isolation20') > 0. && userFloat('lxysig') > 2. && abs(userFloat('pvlip')) < 1. && (abs(userFloat('pvlip'))/abs(userFloat('pvlipErr'))) < 5."
        ),
        # preselection = cms.string("mass > 4.5 && mass < 6.3 && pt > 5. && pt < 9999. && daughter('muon1').pt > 4. && daughter('muon1').pt < 999. && daughter('muon2').pt > 4. && daughter('muon2').pt < 999."),
    )

    # check if there is at least one (inclusive) tracker+tracker di-muon
    process.onia2MuMuPatTrkTrkFilter = cms.EDFilter(
        "CandViewCountFilter",
        src=cms.InputTag('onia2MuMuPatTrkTrk', 'DiMu'),
        minNumber=cms.uint32(1),
    )

    process.onia2MuMuPatMassFilter = cms.EDFilter(
        "CandViewSelector",
        src=cms.InputTag('onia2MuMuPatTrkTrk', 'DiMu'),
        cut=cms.string(
            "userFloat('kinMass') > 4.5 && userFloat('kinMass') < 6.3 && pt > 5. && pt < 9999. && daughter('muon1').pt > 4. && daughter('muon1').pt < 999. && daughter('muon2').pt > 4. && daughter('muon2').pt < 999. && userFloat('l3d') < 2. && userFloat('l3dsig') > 0. && userFloat('l3dsig') < 200. && userFloat('vNChi2') < 20. && userFloat('delta3d') < 0.1 && userFloat('delta3d')/userFloat('delta3dErr') < 5. && userFloat('DCA') < 0.1 && acos(userFloat('cosAlpha3D')) < 1.0 && userFloat('minDca') < 2.50 && userFloat('Isolation20') > 0. && userFloat('lxysig') > 2. && abs(userFloat('pvlip')) < 1. && (abs(userFloat('pvlip'))/abs(userFloat('pvlipErr'))) < 5."
        ),
        # cut = cms.string(""),
        filter=cms.bool(True))

    # add tracks
    process.load("PhysicsTools.RecoAlgos.allTracks_cfi")
    process.load("PhysicsTools.RecoAlgos.goodTracks_cfi")
    process.goodTracks.particleType = 'pi+'
    # process.goodTracks.cut = 'charge !=0 && found > 1 && pt > 0.5 && hitPattern.pixelLayersWithMeasurement > 0 && abs(d0) < 3.0 && abs(dz) < 25.0 && chi2/ndof < 4.0'
    process.goodTracks.cut = 'charge !=0 && pt > 0.5'

    process.nEventsTotal = cms.EDProducer("EventCountProducer")
    process.nEventsAfterFilter = cms.EDProducer("EventCountProducer")

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(
        process.nEventsTotal * process.patMuonSequence *
        process.onia2MuMuPatTrkTrk * process.allTracks * process.goodTracks *
        process.onia2MuMuPatTrkTrkFilter * process.onia2MuMuPatMassFilter *
        process.nEventsAfterFilter)

    # output
    process.out = cms.OutputModule(
        "PoolOutputModule",
        fileName=cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands=cms.untracked.vstring(
            'drop *',
            'keep *_genMuons_*_Onia2MuMuPAT',  # generated muons and parents
            # 'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muos including general tracks and matches to triggers
            'keep *_goodTracks_*_Onia2MuMuPAT',  # All good tracks (heavy!)  
            # 'keep patCompositeCandidates_*__Onia2MuMuPAT',       # PAT di-muons
            'keep patCompositeCandidates_*_*_Onia2MuMuPAT',  # PAT di-muons and dimuons+track
            # 'keep patMuons_tagMuons__Onia2MuMuPAT',                # tagMuons for efficiency
            # 'keep patMuons_probeMuons__Onia2MuMuPAT',              # probeMuons for efficiency
            # 'keep *_tagMuonsMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            # 'keep *_probeMuonsMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep recoCompositeCandidates_*__Onia2MuMuPAT',  # RECO di-muons, tpPairs for efficiency
            'keep *_offlinePrimaryVertices_*_*',  # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',  # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',  # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',  # L1 info (cheap)
            'keep L1GlobalTriggerReadoutRecord_gtDigis_*_*',  # Prescale info
            'keep *_l1GtRecord_*_*',  # Prescale info
            'keep edmMergeableCounter_*_*_*'  # Count the number of events before and after filters
            #'keep *_*_DiMu_*'
        ),
        # outputCommands = cms.untracked.vstring('keep *'),
        SelectEvents=cms.untracked.PSet(
            SelectEvents=cms.vstring('Onia2MuMuPAT'))
        if Filter else cms.untracked.PSet())
    process.e = cms.EndPath(process.out)
Example #3
0
# Prune generated particles to muons and their parents
process.genMuons = cms.EDProducer(
    "GenParticlePruner",
    src=cms.InputTag("genParticles"),
    select=cms.vstring(
        "drop  *  ",  # this is the default
        "++keep abs(pdgId) = 13",  # keep muons and their parents
        "drop pdgId == 21 && status = 2"  # remove intermediate qcd spam carrying no flavour info
    ))

process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, useExistingPATMuons, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution, addDiMuonTriggers
# with some customization
if MC:
    addMCinfo(process)
    # since we match inner tracks, keep the matching tight and make it one-to-one
    process.muonMatch.maxDeltaR = 0.05
    process.muonMatch.resolveByMatchQuality = True

addDiMuonTriggers(process)
useExistingPATMuons(process, 'cleanPatMuons', addL1Info=False)
changeTriggerProcessName(process, 'HLT')
switchOffAmbiguityResolution(
    process
)  # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
useL1MatchingWindowForSinglets(process)

process.muonL1Info.maxDeltaR = 0.3
process.muonL1Info.fallbackToME1 = True
process.muonMatchHLTL1.maxDeltaR = 0.3
process.genMuons = cms.EDProducer("GenParticlePruner",
                                  src = cms.InputTag("genParticles"),
                                  select = cms.vstring(
                                          "drop  *  ",                     # this is the default
                                          "++keep abs(pdgId) = 13",        # keep muons and their parents
                                          "drop pdgId == 21 && status = 2" # remove intermediate qcd spam carrying no flavour info
                                  )
 )



process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import  addMCinfo, useExistingPATMuons, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution, addDiMuonTriggers
    # with some customization
if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True

addDiMuonTriggers(process)
useExistingPATMuons(process,'cleanPatMuons',addL1Info=False)
changeTriggerProcessName(process, 'HLT')
switchOffAmbiguityResolution(process) # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
useL1MatchingWindowForSinglets(process)

process.muonL1Info.maxDeltaR     = 0.3
process.muonL1Info.fallbackToME1 = True
process.muonMatchHLTL1.maxDeltaR     = 0.3
process.muonMatchHLTL1.fallbackToME1 = True
process.muonMatchHLTL2.maxDeltaR = 0.3
Example #5
0
def finderMaker_75X(process,
                    AddCaloMuon=False,
                    runOnMC=True,
                    HIFormat=False,
                    UseGenPlusSim=False,
                    VtxLabel="hiSelectedVertex",
                    TrkLabel="hiGeneralTracks"):
    ### Set TransientTrackBuilder
    process.load("TrackingTools/TransientTrack/TransientTrackBuilder_cfi")

    ##Producing Gen list with SIM particles
    process.genParticlePlusGEANT = cms.EDProducer(
        "GenPlusSimParticleProducer",
        src=cms.InputTag("g4SimHits"),  # use "famosSimHits" for FAMOS
        setStatus=cms.int32(8),  # set status = 8 for GEANT GPs
        filter=cms.vstring("pt > 0.0"),  # just for testing (optional)
        genParticles=cms.InputTag("genParticles")  # original genParticle list
    )

    ### Setup Pat
    process.load("PhysicsTools.PatAlgos.patSequences_cff")
    ###### Needed in CMSSW7
    process.particleFlowPtrs.src = "particleFlowTmp"
    process.pfPileUpIsoPFBRECO.Vertices = cms.InputTag(VtxLabel)
    process.pfPileUpPFBRECO.Vertices = cms.InputTag(VtxLabel)
    ###### Needed in CMSSW7

    if HIFormat:
        process.muonMatch.matched = cms.InputTag("hiGenParticles")
        process.genParticlePlusGEANT.genParticles = cms.InputTag(
            "hiGenParticles")

    ##Using GEN plus SIM list for matching
    if UseGenPlusSim:
        process.muonMatch.matched = cms.InputTag("genParticlePlusGEANT")

    ## TrackCand
    from PhysicsTools.PatAlgos.tools.trackTools import makeTrackCandidates
    if runOnMC:
        makeTrackCandidates(
            process,  # patAODTrackCands
            label=
            'TrackCands',  # output collection will be 'allLayer0TrackCands', 'allLayer1TrackCands', 'selectedLayer1TrackCands'
            tracks=cms.InputTag(TrkLabel),  # input track collection
            particleType='pi+',  # particle type (for assigning a mass)
            preselection=
            'pt > 0.3',  # preselection cut on candidates. Only methods of 'reco::Candidate' are available
            selection=
            'pt > 0.3',  # Selection on PAT Layer 1 objects ('selectedLayer1TrackCands')
            isolation=
            {},  # Isolations to use ('source':deltaR; set to {} for None)
            isoDeposits=[],
            mcAs='muon'  # Replicate MC match as the one used for Muons
        )
        # you can specify more than one collection for this
        ### MC+mcAs+Match/pat_label options
        #process.patTrackCandsMCMatch.matched = cms.InputTag("hiGenParticles")
        process.patTrackCandsMCMatch.resolveByMatchQuality = cms.bool(True)
        process.patTrackCandsMCMatch.resolveAmbiguities = cms.bool(True)
        process.patTrackCandsMCMatch.checkCharge = cms.bool(True)
        process.patTrackCandsMCMatch.maxDPtRel = cms.double(0.5)
        process.patTrackCandsMCMatch.maxDeltaR = cms.double(0.7)
        process.patTrackCandsMCMatch.mcPdgId = cms.vint32(111, 211, 311, 321)
        process.patTrackCandsMCMatch.mcStatus = cms.vint32(1)
        l1cands = getattr(process, 'patTrackCands')
        l1cands.addGenMatch = True

    else:
        makeTrackCandidates(
            process,  # patAODTrackCands
            label=
            'TrackCands',  # output collection will be 'allLayer0TrackCands', 'allLayer1TrackCands', 'selectedLayer1TrackCands'
            tracks=cms.InputTag(TrkLabel),  # input track collection
            particleType='pi+',  # particle type (for assigning a mass)
            preselection=
            'pt > 0.3',  # preselection cut on candidates. Only methods of 'reco::Candidate' are available
            selection=
            'pt > 0.3',  # Selection on PAT Layer 1 objects ('selectedLayer1TrackCands')
            isolation=
            {},  # Isolations to use ('source':deltaR; set to {} for None)
            isoDeposits=[],
            mcAs=None  # Replicate MC match as the one used for Muons
        )
        # you can specify more than one collection for this
        l1cands = getattr(process, 'patTrackCands')
        l1cands.addGenMatch = False
    if runOnMC:
        process.TrackCandSequence = cms.Sequence(
            process.patAODTrackCandsUnfiltered * process.patAODTrackCands *
            process.patTrackCandsMCMatch * process.patTrackCands *
            process.selectedPatTrackCands)
    else:
        process.TrackCandSequence = cms.Sequence(
            process.patAODTrackCandsUnfiltered * process.patAODTrackCands *
            process.patTrackCands * process.selectedPatTrackCands)

    ## patMuonsWithTrigger
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution, addHLTL1Passthrough
    #process.patMuonsWithTriggerSequence = cms.Sequence(process.pfParticleSelectionForIsoSequence*process.muonPFIsolationPATSequence*process.patMuonsWithTriggerSequence)
    process.patMuonsWithTriggerSequence = cms.Sequence(
        process.patMuonsWithTriggerSequence)
    process.patMuonsWithoutTrigger.isoDeposits = cms.PSet()
    process.patMuonsWithoutTrigger.isolationValues = cms.PSet()
    process.patMuonsWithoutTrigger.pvSrc = cms.InputTag(VtxLabel)
    if runOnMC:
        addMCinfo(process)
        process.muonMatch.maxDeltaR = cms.double(0.05)
        process.muonMatch.resolveByMatchQuality = True

    changeTriggerProcessName(process, "HLT")
    switchOffAmbiguityResolution(
        process
    )  # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    addHLTL1Passthrough(process)

    process.patTrigger.collections.remove("hltL3MuonCandidates")
    process.patTrigger.collections.append("hltHIL3MuonCandidates")

    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0
    process.muonMatchHLTL3.matchedCuts = cms.string(
        'coll("hltHIL3MuonCandidates")')

    # Merge muons, calomuons in a single collection for T&P
    from RecoMuon.MuonIdentification.calomuons_cfi import calomuons
    process.mergedMuons = cms.EDProducer(
        "CaloMuonMerger",
        muons=cms.InputTag("muons"),
        mergeCaloMuons=cms.bool(True),  ### NEEDED TO RUN ON AOD
        caloMuons=cms.InputTag("calomuons"),
        minCaloCompatibility=cms.double(0.6),
        mergeTracks=cms.bool(False),
        tracks=cms.InputTag(TrkLabel),
    )
    if AddCaloMuon:
        #changeRecoMuonInput(process, "mergedMuons")#Add calo muon to the collection
        #process.patMuons.muonSource = cms.InputTag("mergedMuons")#Need to use the same collection as they are internally entengled
        #process.patMuons.embedCaloMETMuonCorrs = cms.bool(False)
        #process.patMuons.embedTcMETMuonCorrs   = cms.bool(False)

        #Or we change the muonMatch source of our patMuonsWithoutTrigger
        process.patMuonsWithoutTrigger.muonSource = cms.InputTag("mergedMuons")
        process.patMuonsWithoutTriggerMatch = PhysicsTools.PatAlgos.mcMatchLayer0.muonMatch_cfi.muonMatch.clone(
            src=cms.InputTag("mergedMuons"))
        if runOnMC:
            process.patMuonsWithTriggerSequence.replace(
                process.patMuonsWithoutTrigger,
                process.patMuonsWithoutTriggerMatch +
                process.patMuonsWithoutTrigger)
            process.patMuonsWithoutTrigger.genParticleMatch = 'patMuonsWithoutTriggerMatch'
        process.patMuonsWithTriggerSequence = cms.Sequence(
            process.mergedMuons * process.patMuonsWithTriggerSequence)

    ### Set Bfinder option
    process.Bfinder = cms.EDAnalyzer(
        'Bfinder',
        Bchannel=cms.vint32(
            1,  #RECONSTRUCTION: J/psi + K
            0,  #RECONSTRUCTION: J/psi + Pi
            0,  #RECONSTRUCTION: J/psi + Ks 
            0,  #RECONSTRUCTION: J/psi + K* (K+, Pi-)
            0,  #RECONSTRUCTION: J/psi + K* (K-, Pi+)
            0,  #RECONSTRUCTION: J/psi + phi
            1,  #RECONSTRUCTION: J/psi + pi pi <= psi', X(3872), Bs->J/psi f0
        ),
        detailMode=cms.bool(True),
        dropUnusedTracks=cms.bool(True),
        MuonTriggerMatchingPath=cms.vstring(""),
        MuonTriggerMatchingFilter=cms.vstring(""),
        HLTLabel=cms.InputTag('TriggerResults::HLT'),
        GenLabel=cms.InputTag('genParticles'),
        MuonLabel=cms.InputTag('patMuonsWithTrigger'),
        TrackLabel=cms.InputTag('patTrackCands'),
        RecoTrackLabel=cms.InputTag('generalTracks'),
        RecoDEdxLabel=cms.InputTag('dedxHarmonic'),
        MVAMapLabel=cms.string(TrkLabel),
        PUInfoLabel=cms.InputTag("addPileupInfo"),
        BSLabel=cms.InputTag("offlineBeamSpot"),
        PVLabel=cms.InputTag(VtxLabel),
        tkPtCut=cms.double(1.0),  #before fit
        tkEtaCut=cms.double(999.0),  #before fit
        jpsiPtCut=cms.double(0.0),  #before fit
        uj_VtxChiProbCut=cms.double(0.01),
        bPtCut=cms.vdouble(5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0),  #before fit
        bEtaCut=cms.vdouble(2.4, 2.4, 2.4, 2.4, 2.4, 2.4,
                            2.4),  #before fit, not used currently
        VtxChiProbCut=cms.vdouble(0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01),
        svpvDistanceCut=cms.vdouble(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
        MaxDocaCut=cms.vdouble(999., 999., 999., 999., 999., 999., 999.),
        alphaCut=cms.vdouble(999., 999., 999., 999., 999., 999., 999.),
        RunOnMC=cms.bool(False),
        doTkPreCut=cms.bool(True),
        doMuPreCut=cms.bool(True),
        makeBntuple=cms.bool(True),
        doBntupleSkim=cms.bool(False),
    )
    ### Set Dfinder option
    process.Dfinder = cms.EDAnalyzer(
        'Dfinder',
        Dchannel=cms.vint32(
            1,  #RECONSTRUCTION: K+pi- : D0bar
            1,  #RECONSTRUCTION: K-pi+ : D0
            0,  #RECONSTRUCTION: K-pi+pi+ : D+
            0,  #RECONSTRUCTION: K+pi-pi- : D-
            0,  #RECONSTRUCTION: K-pi-pi+pi+ : D0
            0,  #RECONSTRUCTION: K+pi+pi-pi- : D0bar
            0,  #RECONSTRUCTION: K+K-(Phi)pi+ : Ds+
            0,  #RECONSTRUCTION: K+K-(Phi)pi- : Ds-
            0,  #RECONSTRUCTION: D0(K-pi+)pi+ : D+*
            0,  #RECONSTRUCTION: D0bar(K+pi-)pi- : D-*
            0,  #RECONSTRUCTION: D0(K-pi-pi+pi+)pi+ : D+*
            0,  #RECONSTRUCTION: D0bar(K+pi+pi-pi-)pi- : D-*
        ),
        detailMode=cms.bool(False),
        dropUnusedTracks=cms.bool(True),
        HLTLabel=cms.InputTag('TriggerResults::HLT'),
        GenLabel=cms.InputTag('genParticles'),
        TrackLabel=cms.InputTag('patTrackCands'),
        MVAMapLabel=cms.string(TrkLabel),
        PUInfoLabel=cms.InputTag("addPileupInfo"),
        BSLabel=cms.InputTag("offlineBeamSpot"),
        PVLabel=cms.InputTag(VtxLabel),
        RecoTrackLabel=cms.InputTag('generalTracks'),
        RecoDEdxLabel=cms.InputTag('dedxHarmonic'),
        tkPtCut=cms.double(1.),  #before fit
        tkEtaCut=cms.double(2.0),  #before fit
        dPtCut=cms.vdouble(8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 8.,
                           8.),  #before fit
        dEtaCut=cms.vdouble(1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
                            1.5, 1.5),  #before fit, not used currently
        VtxChiProbCut=cms.vdouble(
            0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
        ),  #better not to cut for decay with resonance, cutting on both mother and daughter vertex fit now
        dCutSeparating_PtVal=cms.vdouble(5., 5., 5., 5., 5., 5., 5., 5., 5.,
                                         5., 5., 5.),
        tktkRes_svpvDistanceCut_lowptD=cms.vdouble(
            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0,
            2.0),  #if cut, only cut on last four channels, D*->D0
        tktkRes_svpvDistanceCut_highptD=cms.vdouble(
            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
            2.0, 2.0, 2.0,
            2.0),  #if cut, only cut on last four channels, D*->D0
        tktkRes_alphaCut=cms.vdouble(
            999., 999., 999., 999., 999., 999., 999., 999., 999., 999., 999.,
            999.),  #if cut, only cut on last four channels, D*->D0
        svpvDistanceCut_lowptD=cms.vdouble(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                                           0.0, 0.0, 0.0, 0.0, 0.0),
        svpvDistanceCut_highptD=cms.vdouble(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                                            0.0, 0.0, 0.0, 0.0, 0.0),
        MaxDocaCut=cms.vdouble(999., 999., 999., 999., 999., 999., 999., 999.,
                               999., 999., 999., 999.),
        alphaCut=cms.vdouble(999., 999., 999., 999., 999., 999., 999., 999.,
                             999., 999., 999., 999.),
        RunOnMC=cms.bool(False),
        doTkPreCut=cms.bool(True),
        makeDntuple=cms.bool(True),
        doDntupleSkim=cms.bool(False),
    )
    if runOnMC:
        process.Bfinder.RunOnMC = cms.bool(True)
        process.Dfinder.RunOnMC = cms.bool(True)
    if HIFormat:
        process.Bfinder.GenLabel = cms.InputTag('hiGenParticles')
        process.Dfinder.GenLabel = cms.InputTag('hiGenParticles')
    if UseGenPlusSim:
        process.Bfinder.GenLabel = cms.InputTag('genParticlePlusGEANT')
        process.Dfinder.GenLabel = cms.InputTag('genParticlePlusGEANT')

    if runOnMC and UseGenPlusSim:
        process.patMuonsWithTriggerSequence *= process.genParticlePlusGEANT

    process.BfinderSequence = cms.Sequence(
        process.patMuonsWithTriggerSequence * process.TrackCandSequence *
        process.Bfinder)
    process.DfinderSequence = cms.Sequence(process.TrackCandSequence *
                                           process.Dfinder)
    process.finderSequence = cms.Sequence(process.patMuonsWithTriggerSequence *
                                          process.TrackCandSequence *
                                          process.Bfinder * process.Dfinder)

    ### Temporal fix for the PAT Trigger prescale warnings.
    process.patTriggerFull.l1GtReadoutRecordInputTag = cms.InputTag(
        "gtDigis", "", "RECO")
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary=cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryRecoDB_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load("Configuration.StandardSequences.MagneticField_cff")
    process.load(
        "Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
                                inputCommands=cms.untracked.vstring(
                                    "keep *", "drop *_MEtoEDMConverter_*_*"),
                                fileNames=cms.untracked.vstring())

    # Scraping filter
    process.scrapingFilter = cms.EDFilter("FilterOutScraping",
                                          applyfilter=cms.untracked.bool(True),
                                          debugOn=cms.untracked.bool(False),
                                          numtrack=cms.untracked.uint32(10),
                                          thresh=cms.untracked.double(0.25))

    IN_ACCEPTANCE = '((abs(eta) <= 1.3 && pt > 3.3) || (1.3 < abs(eta) <= 2.2 && p > 2.9) || (2.2 < abs(eta) <= 2.4 && pt > 0.8))'

    # Merge muons, calomuons in a single collection for T&P
    process.mergedMuons = cms.EDProducer(
        "CaloMuonMerger",
        muons=cms.InputTag("muons"),
        muonsCut=cms.string(""),
        mergeCaloMuons=cms.bool(True),  ### NEEDED TO RUN ON AOD
        caloMuons=cms.InputTag("calomuons"),
        caloMuonsCut=cms.string(IN_ACCEPTANCE),
        minCaloCompatibility=cms.double(0.6),
        mergeTracks=cms.bool(False),
        tracks=cms.InputTag("generalTracks"),
        tracksCut=cms.string(IN_ACCEPTANCE),
    )

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer(
        "GenParticlePruner",
        src=cms.InputTag("genParticles"),  # KYO - pp
        #        src = cms.InputTag("hiGenParticles"), # KYO - embedded
        select=cms.vstring(
            "drop  *  ",  # this is the default
            "++keep abs(pdgId) = 13",  # keep muons and their parents
            "drop pdgId == 21 && status = 2"  # remove intermediate qcd spam carrying no flavour info
        ))

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(
        process
    )  # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    #useL1MatchingWindowForSinglets(process)

    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0

    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.hltOniaHI * process.PAcollisionEventSelection *
        process.genMuons * process.patMuonsWithTriggerSequence)
    if not MC:
        process.patMuonSequence.remove(process.genMuons)

    # Make dimuon candidates
    process.onia2MuMuPatTrkTrk = cms.EDProducer(
        'HiOnia2MuMuPAT',
        muons=cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag=cms.InputTag("offlineBeamSpot"),
        primaryVertexTag=cms.InputTag("offlinePrimaryVertices"),
        # At least one muon must pass this selection
        higherPuritySelection=cms.string(
            "(isGlobalMuon || isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"
        ),
        # BOTH muons must pass this selection
        lowerPuritySelection=cms.string(
            "(isGlobalMuon || isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"
        ),
        dimuonSelection=cms.string(
            ""),  ## The dimuon must pass this selection before vertexing
        addCommonVertex=cms.bool(
            True),  ## Embed the full reco::Vertex out of the common vertex fit
        addMuonlessPrimaryVertex=cms.bool(
            True
        ),  ## Embed the primary vertex re-made from all the tracks except the two muons
        addMCTruth=cms.bool(
            MC),  ## Add the common MC mother of the two muons, if any
        resolvePileUpAmbiguity=cms.bool(
            True
        )  ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
    )

    # check if there is at least one (inclusive) tracker+tracker di-muon
    process.onia2MuMuPatTrkTrkFilter = cms.EDFilter(
        "CandViewCountFilter",
        src=cms.InputTag('onia2MuMuPatTrkTrk'),
        minNumber=cms.uint32(1),
    )

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(process.patMuonSequence *
                                    process.onia2MuMuPatTrkTrk *
                                    process.onia2MuMuPatTrkTrkFilter)

    # Make Tag and Probe pairs for efficiency measurements
    TRACK_CUTS = "(track.hitPattern.trackerLayersWithMeasurement > 5 && track.normalizedChi2 < 1.8 && track.hitPattern.pixelLayersWithMeasurement > 1 && abs(dB) < 3 && abs(track.dz) < 15)"
    GLB_CUTS = "(isTrackerMuon && muonID('TrackerMuonArbitrated') && muonID('TMOneStationTight'))"
    QUALITY_CUTS = "(" + GLB_CUTS + ' && ' + TRACK_CUTS + ")"

    process.tagMuonsSglTrg = cms.EDFilter(
        "PATMuonSelector",
        src=cms.InputTag("patMuonsWithTrigger"),
        cut=cms.string(
            QUALITY_CUTS + ' && ' + IN_ACCEPTANCE +
            " && (!triggerObjectMatchesByPath('HLT_PAMu3_v*').empty() || !triggerObjectMatchesByPath('HLT_PAMu7_v*').empty() || !triggerObjectMatchesByPath('HLT_PAMu12_v*').empty())"
        ))

    process.tagMuonsDblTrg = cms.EDFilter(
        "PATMuonSelector",
        src=cms.InputTag("patMuonsWithTrigger"),
        cut=cms.string(
            QUALITY_CUTS + ' && ' + IN_ACCEPTANCE +
            " && !triggerObjectMatchesByPath('HLT_PAL1DoubleMuOpen_v*').empty()"
        ))

    # produce patMuons that use the STA momentum information
    process.patMuonsWithTriggerSta = cms.EDProducer(
        "RedefineMuonP4FromTrackPAT",
        src=cms.InputTag("patMuonsWithTrigger"),
        track=cms.string("outer"))

    # must be STA, so we can measure inner tracking efficiency
    process.probeMuonsSta = cms.EDFilter(
        "PATMuonSelector",
        src=cms.InputTag("patMuonsWithTriggerSta"),
        cut=cms.string("outerTrack.isNonnull"))

    process.tpPairsSta = cms.EDProducer(
        "CandViewShallowCloneCombiner",
        cut=cms.string('2.0 < mass < 5.0'),
        decay=cms.string('tagMuonsDblTrg@+ probeMuonsSta@-'))

    # must be a GLB to measure trigger efficiency
    process.probeMuons = cms.EDFilter("PATMuonSelector",
                                      src=cms.InputTag("patMuonsWithTrigger"),
                                      cut=cms.string(QUALITY_CUTS + ' && ' +
                                                     IN_ACCEPTANCE))

    process.tpPairsTrig = cms.EDProducer(
        "CandViewShallowCloneCombiner",
        cut=cms.string('2.6 < mass < 4.0'),
        decay=cms.string('tagMuonsSglTrg@+ probeMuons@-'))

    # must be tracker muon, so we can measure the muon reco efficiency
    # since we're using tracker muons this year, we should use calo muons as probes here
    process.probeMuonsTrk = cms.EDFilter(
        "PATMuonSelector",
        src=cms.InputTag("patMuonsWithTrigger"),
        #cut = cms.string("isCaloMuon && " + TRACK_CUTS)
        cut=cms.string("caloCompatibility>0.6 && innerTrack.isNonnull && " +
                       TRACK_CUTS))

    process.tpPairsTracks = cms.EDProducer(
        "CandViewShallowCloneCombiner",
        cut=cms.string('2.6 < mass < 4.0'),
        decay=cms.string('tagMuonsDblTrg@+ probeMuonsTrk@-'))

    # check if there is at least one Tag and Probe pair
    process.tpPairsStaFilter = cms.EDFilter(
        "CandViewCountFilter",
        src=cms.InputTag('tpPairsSta'),
        minNumber=cms.uint32(1),
    )

    process.tpPairsTrigFilter = cms.EDFilter(
        "CandViewCountFilter",
        src=cms.InputTag('tpPairsTrig'),
        minNumber=cms.uint32(1),
    )

    process.tpPairsTracksFilter = cms.EDFilter(
        "CandViewCountFilter",
        src=cms.InputTag('tpPairsTracks'),
        minNumber=cms.uint32(1),
    )

    # the Tag and Probe path
    process.tnpSta = cms.Sequence(process.probeMuonsSta * process.tpPairsSta *
                                  process.tpPairsStaFilter)

    process.tnpTrig = cms.Sequence(process.probeMuons * process.tpPairsTrig *
                                   process.tpPairsTrigFilter)

    process.tnpMuID = cms.Sequence(process.probeMuonsTrk *
                                   process.tpPairsTracks *
                                   process.tpPairsTracksFilter)

    # inner track reco efficiency
    process.TagAndProbeSta = cms.Path(
        process.patMuonSequence * process.tagMuonsDblTrg *
        process.patMuonsWithTriggerSta * process.tnpSta)

    # muon reco and ID efficiency
    process.TagAndProbeMuID = cms.Path(
        process.patMuonSequence * process.tagMuonsDblTrg * process.tnpMuID)

    # muon trigger efficiency
    process.TagAndProbeTrig = cms.Path(
        process.patMuonSequence * process.tagMuonsSglTrg * process.tnpTrig)

    if MC:
        process.tagMuonsDblTrgMCMatch = process.muonMatch.clone(
            src="tagMuonsDblTrg")
        process.tagMuonsSglTrgMCMatch = process.muonMatch.clone(
            src="tagMuonsSglTrg")
        process.probeMuonsStaMCMatch = process.tagMuonsDblTrgMCMatch.clone(
            src="probeMuonsSta")  # inner tracking eff
        process.probeMuonsTrkMCMatch = process.tagMuonsDblTrgMCMatch.clone(
            src="probeMuonsTrk")  # Muon reco and ID eff
        process.probeMuonsMCMatch = process.tagMuonsSglTrgMCMatch.clone(
            src="probeMuons")  # muon trigger eff
        process.TagAndProbeSta.replace(
            process.tpPairsSta, process.tagMuonsDblTrgMCMatch *
            process.probeMuonsStaMCMatch * process.tpPairsSta)
        process.TagAndProbeMuID.replace(
            process.tpPairsTracks, process.tagMuonsDblTrgMCMatch *
            process.probeMuonsTrkMCMatch * process.tpPairsTracks)
        process.TagAndProbeTrig.replace(
            process.tpPairsTrig, process.tagMuonsSglTrgMCMatch *
            process.probeMuonsMCMatch * process.tpPairsTrig)

    # output
    process.load('Configuration.EventContent.EventContent_cff')

    process.outOnia2MuMu = cms.OutputModule(
        "PoolOutputModule",
        fileName=cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands=cms.untracked.vstring('drop *'),
        SelectEvents=cms.untracked.PSet(
            SelectEvents=cms.vstring('Onia2MuMuPAT'))
        if Filter else cms.untracked.PSet())

    process.outOnia2MuMu.outputCommands.extend(
        cms.untracked.vstring(
            'keep *_mergedtruth_*_*',  # tracking particles and tracking vertices for hit by hit matching
            'keep *_genParticles_*_*',  # generated particles : KYO -pp
            #        'keep *_hiGenParticles_*_*',                             # generated particles : KYO - embedded
            'keep *_genMuons_*_Onia2MuMuPAT',  # generated muons and parents
            'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',  # All PAT muons including matches to triggers
            'keep patCompositeCandidates_*__Onia2MuMuPAT',  # PAT di-muons
            'keep *_offlinePrimaryVertices_*_*',  # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',  # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',  # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_hltL1extraParticles_*_*',  # L1 info (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',  # L1 info (cheap)
            'keep *_offlinePrimaryVertices_*_*',
            'keep *_pACentrality_*_*',
            'keep *_generalTracks_*_*',
            'keep *_standAloneMuons_*_*')),

    process.outTnP = cms.OutputModule(
        "PoolOutputModule",
        fileName=cms.untracked.string('tnp.root'),
        outputCommands=cms.untracked.vstring(
            'drop *',
            'keep *_genParticles_*_*',  # generated particles : KYO - pp
            #            'keep *_hiGenParticles_*_*',                             # generated particles : KYO - embedeed
            'keep *_genMuons_*_Onia2MuMuPAT',  # generated muons and parents
            'keep *_tagMuonsDblTrgMCMatch__Onia2MuMuPAT',  # tagMuons MC matches for efficiency
            'keep *_tagMuonsSglTrgMCMatch__Onia2MuMuPAT',  # tagMuons MC matches for efficiency
            'keep *_probeMuonsMCMatch__Onia2MuMuPAT',  # probeMuons MC matches for efficiency
            'keep patMuons_patMuonsWithTriggerSta__Onia2MuMuPAT',  # All PAT muons including matches to triggers
            'keep patMuons_tagMuonsDblTrg__Onia2MuMuPAT',  # tagMuons for efficiency
            'keep patMuons_tagMuonsSglTrg__Onia2MuMuPAT',  # tagMuons for efficiency
            'keep patMuons_probeMuonsSta__Onia2MuMuPAT',  # probeMuons for efficiency
            'keep patMuons_probeMuonsTrk__Onia2MuMuPAT',  # probeTracks for efficiency
            'keep patMuons_probeMuons__Onia2MuMuPAT',  # probeMuons for efficiency
            'keep *_probeMuonsStaMCMatch__Onia2MuMuPAT',  # probeMuons MC matches for efficiency
            'keep *_probeMuonsTrkMCMatch__Onia2MuMuPAT',  # probeTacks MC matches for efficiency
            'keep recoCompositeCandidates_tpPairsSta__Onia2MuMuPAT',  # RECO di-muons, tpPairs for tracking efficiency
            'keep recoCompositeCandidates_tpPairsTracks__Onia2MuMuPAT',  # RECO di-muons, tpPairs for muon ID and reco efficiency
            'keep recoCompositeCandidates_tpPairsTrig__Onia2MuMuPAT',  # RECO di-muons, tpPairs for trigger efficiency
            'keep *_offlinePrimaryVertices_*_*',  # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',  # Beam spot: you want this for the same reason   
            'keep edmTriggerResults_TriggerResults_*_*',  # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_hltL1extraParticles_*_*',  # L1 info (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',  # L1 info (cheap)
            'keep *_pACentrality_*_*',
            'keep *_generalTracks_*_*',
            'keep *_standAloneMuons_*_*'  # standAloneMuon track collection, to be on the safe side
        ),
        SelectEvents=cms.untracked.PSet(SelectEvents=cms.vstring(
            'TagAndProbeSta', 'TagAndProbeMuID', 'TagAndProbeTrig'))
        if Filter else cms.untracked.PSet())

    process.e = cms.EndPath(process.outOnia2MuMu + process.outTnP)
Example #7
0
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary=cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
                                inputCommands=cms.untracked.vstring(
                                    "keep *", "drop *_MEtoEDMConverter_*_*"),
                                fileNames=cms.untracked.vstring())

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer(
        "GenParticlePruner",
        src=cms.InputTag("hiGenParticles"),
        select=cms.vstring(
            "drop  *  ",  # this is the default
            "++keep abs(pdgId) = 13",  # keep muons and their parents
            "drop pdgId == 21 && status = 2"  # remove intermediate qcd spam carrying no flavour info
        ))

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution, addHLTL1Passthrough
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(
        process
    )  # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    addHLTL1Passthrough(process)
    #useL1MatchingWindowForSinglets(process)

    process.patTrigger.collections.remove("hltL3MuonCandidates")
    process.patTrigger.collections.append("hltHIL3MuonCandidates")

    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0
    process.muonMatchHLTL3.matchedCuts = cms.string(
        'coll("hltHIL3MuonCandidates")')

    # Make a sequence
    process.patMuonSequence = cms.Sequence(process.hltOniaHI *
                                           process.genMuons *
                                           process.patMuonsWithTriggerSequence)
    if not MC:
        process.patMuonSequence.remove(process.genMuons)

    # Make dimuon candidates
    process.onia2MuMuPatGlbGlb = cms.EDProducer(
        'HiOnia2MuMuPAT',
        muons=cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag=cms.InputTag("offlineBeamSpot"),
        primaryVertexTag=cms.InputTag("hiSelectedVertex"),
        srcTracks=cms.InputTag("hiGeneralTracks"),
        genParticles=cms.InputTag("genParticles"),
        # At least one muon must pass this selection
        higherPuritySelection=cms.string(
            "((isGlobalMuon && isTrackerMuon) || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"
        ),
        # BOTH muons must pass this selection
        lowerPuritySelection=cms.string(
            "((isGlobalMuon && isTrackerMuon) || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"
        ),
        dimuonSelection=cms.string(
            ""),  ## The dimuon must pass this selection before vertexing
        addCommonVertex=cms.bool(
            True),  ## Embed the full reco::Vertex out of the common vertex fit
        addMuonlessPrimaryVertex=cms.bool(
            False
        ),  ## Embed the primary vertex re-made from all the tracks except the two muons
        addMCTruth=cms.bool(
            MC),  ## Add the common MC mother of the two muons, if any
        resolvePileUpAmbiguity=cms.bool(
            True
        )  ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
    )

    # check if there is at least one (inclusive) global+tracker di-muon
    process.onia2MuMuPatGlbGlbFilter = cms.EDFilter(
        "CandViewCountFilter",
        src=cms.InputTag('onia2MuMuPatGlbGlb'),
        minNumber=cms.uint32(1),
    )

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(process.patMuonSequence *
                                    process.onia2MuMuPatGlbGlb *
                                    process.onia2MuMuPatGlbGlbFilter)

    # output
    process.load('Configuration.EventContent.EventContent_cff')
    process.load("Configuration.EventContent.EventContentHeavyIons_cff")

    process.outOnia2MuMu = cms.OutputModule(
        "PoolOutputModule",
        fileName=cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands=cms.untracked.vstring(
            'drop *',
            'keep *_mergedtruth_*_*',  # tracking particles and tracking vertices for hit by hit matching
            'keep *_genParticles_*_*',  # generated particles
            'keep *_genMuons_*_Onia2MuMuPAT',  # generated muons and parents
            'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',  # All PAT muons including matches to triggers
            'keep patCompositeCandidates_*__Onia2MuMuPAT',  # PAT di-muons
            'keep *_offlinePrimaryVertices_*_*',  # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',  # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',  # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_hltL1extraParticles_*_*',  # L1 info (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',  # L1 info (cheap)
            'keep L1GlobalTriggerReadoutRecord_*_*_*',  # For HLT and L1 prescales (cheap) 
            'keep L1GlobalTriggerRecord_*_*_*',  # For HLT and L1 prescales (cheap)        
            'keep L1GtTriggerMenu_*_*_*',  # L1 prescales 
            'keep *_hiEvtPlane_*_*',  # Event Plane collection
            'keep *_hiSelectedVertex_*_*',  # HI Primary vertices
            'keep *_centralityBin_*_*',  # Centrality bin collection
            'keep *_hiCentrality_*_*'  # HI Centrality collection
        ),
        SelectEvents=cms.untracked.PSet(
            SelectEvents=cms.vstring('Onia2MuMuPAT'))
        if Filter else cms.untracked.PSet())

    process.e = cms.EndPath(process.outOnia2MuMu)
Example #8
0
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary = cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
     
    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
        inputCommands = cms.untracked.vstring("keep *", 
                                              "drop *_MEtoEDMConverter_*_*"),
        fileNames = cms.untracked.vstring()
    )

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer("GenParticlePruner",
        src = cms.InputTag("hiGenParticles"),
        select = cms.vstring(
            "drop  *  ",                     # this is the default
            "++keep abs(pdgId) = 13",        # keep muons and their parents
            "drop pdgId == 21 && status = 2" # remove intermediate qcd spam carrying no flavour info
        )
    )

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution, addHLTL1Passthrough
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(process) # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    addHLTL1Passthrough(process)
    #useL1MatchingWindowForSinglets(process)

    process.patTrigger.collections.remove("hltL3MuonCandidates")
    process.patTrigger.collections.append("hltHIL3MuonCandidates")

    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0
    process.muonMatchHLTL3.matchedCuts = cms.string('coll("hltHIL3MuonCandidates")')
        
    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.hltOniaHI *
        process.genMuons *
        process.patMuonsWithTriggerSequence
    )
    if not MC:
        process.patMuonSequence.remove(process.genMuons)
      
    # Make dimuon candidates
    process.onia2MuMuPatGlbGlb = cms.EDProducer('HiOnia2MuMuPAT',
        muons                    = cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag              = cms.InputTag("offlineBeamSpot"),
        primaryVertexTag         = cms.InputTag("hiSelectedVertex"),
        srcTracks                = cms.InputTag("hiGeneralTracks"),
        genParticles             = cms.InputTag("genParticles"),
        # At least one muon must pass this selection
        higherPuritySelection    = cms.string("((isGlobalMuon && isTrackerMuon) || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        # BOTH muons must pass this selection
        lowerPuritySelection     = cms.string("((isGlobalMuon && isTrackerMuon) || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        dimuonSelection          = cms.string(""), ## The dimuon must pass this selection before vertexing
        addCommonVertex          = cms.bool(True), ## Embed the full reco::Vertex out of the common vertex fit
        addMuonlessPrimaryVertex = cms.bool(False), ## Embed the primary vertex re-made from all the tracks except the two muons
        addMCTruth               = cms.bool(MC),      ## Add the common MC mother of the two muons, if any
        resolvePileUpAmbiguity   = cms.bool(True)   ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
    )

    # check if there is at least one (inclusive) global+tracker di-muon
    process.onia2MuMuPatGlbGlbFilter = cms.EDFilter("CandViewCountFilter",
        src       = cms.InputTag('onia2MuMuPatGlbGlb'),
        minNumber = cms.uint32(1),
    )

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(
        process.patMuonSequence *
        process.onia2MuMuPatGlbGlb *
        process.onia2MuMuPatGlbGlbFilter
    )

    # output
    process.load('Configuration.EventContent.EventContent_cff')
    process.load("Configuration.EventContent.EventContentHeavyIons_cff")

    process.outOnia2MuMu = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands =  cms.untracked.vstring(
            'drop *',                       
            'keep *_mergedtruth_*_*',                              # tracking particles and tracking vertices for hit by hit matching
            'keep *_genParticles_*_*',                             # generated particles
            'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
            'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muons including matches to triggers
            'keep patCompositeCandidates_*__Onia2MuMuPAT',         # PAT di-muons
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_hltL1extraParticles_*_*', # L1 info (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
            'keep L1GlobalTriggerReadoutRecord_*_*_*',             # For HLT and L1 prescales (cheap) 
            'keep L1GlobalTriggerRecord_*_*_*',                    # For HLT and L1 prescales (cheap)        
            'keep L1GtTriggerMenu_*_*_*',                          # L1 prescales 
            'keep *_hiEvtPlane_*_*',                               # Event Plane collection
            'keep *_hiSelectedVertex_*_*',                         # HI Primary vertices
            'keep *_centralityBin_*_*',                            # Centrality bin collection
            'keep *_hiCentrality_*_*'                              # HI Centrality collection
            ),
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('Onia2MuMuPAT') ) if Filter else cms.untracked.PSet()
    )

    process.e = cms.EndPath(process.outOnia2MuMu)
Example #9
0
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary = cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryExtended_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load("Configuration.StandardSequences.MagneticField_cff")
    process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
        inputCommands = cms.untracked.vstring("keep *", "drop *_MEtoEDMConverter_*_*"),
        fileNames = cms.untracked.vstring()
    )

    # Scraping filter
    process.scrapingFilter = cms.EDFilter("FilterOutScraping",
        applyfilter = cms.untracked.bool(True),
        debugOn = cms.untracked.bool(False),
        numtrack = cms.untracked.uint32(10),
        thresh = cms.untracked.double(0.25)
    )

    # Merge muons, (calomuons) and tracks in a single collection for T&P
    process.mergedMuons = cms.EDProducer("CaloMuonMerger",
        muons     = cms.InputTag("muons"), 
        muonsCut = cms.string(""),
        mergeCaloMuons = cms.bool(False),  ### NEEDED TO RUN ON AOD
        caloMuons = cms.InputTag("calomuons"),
        caloMuonsCut = cms.string(""),
        minCaloCompatibility = cms.double(0.6),
        mergeTracks = cms.bool(True),
        tracks = cms.InputTag("generalTracks"),
        #tracksCut = cms.string("(abs(eta) <= 1.3 && pt > 3.3) || (1.3 < abs(eta) <= 2.2 && p > 2.9) || (2.2 < abs(eta) <= 2.4  && pt > 0.8)"),
	tracksCut = cms.string("(abs(eta) <= 0.9 && pt > 2.5) || (0.9 < abs(eta) <=2.4 && pt > 1.5)"),
    )

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer("GenParticlePruner",
        src = cms.InputTag("genParticles"),
        select = cms.vstring(
            "drop  *  ",                     # this is the default
            "++keep abs(pdgId) = 13",        # keep muons and their parents
            "drop pdgId == 21 && status = 2" # remove intermediate qcd spam carrying no flavour info
        )
    )

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeRecoMuonInput(process, "mergedMuons")
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(process) # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    #useL1MatchingWindowForSinglets(process)
    process.muonL1Info.maxDeltaR     = 0.3 
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR     = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0

    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.scrapingFilter *
        process.mergedMuons *
        process.genMuons *
        process.patMuonsWithTriggerSequence
    )
    if not MC:
        process.patMuonSequence.remove(process.genMuons)
      
    # Make dimuon candidates
    process.onia2MuMuPatTrkTrk = cms.EDProducer('Onia2MuMuPAT',
        muons = cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag = cms.InputTag("offlineBeamSpot"),
        primaryVertexTag = cms.InputTag("offlinePrimaryVertices"),
        # At least one muon must pass this selection
        higherPuritySelection = cms.string("(isGlobalMuon || isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35 && muonID('TrackerMuonArbitrated')"),
        # BOTH muons must pass this selection
        lowerPuritySelection  = cms.string("(isGlobalMuon || isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35 && muonID('TrackerMuonArbitrated')"),
        #dimuonSelection  = cms.string("2 < mass"), ## The dimuon must pass this selection before vertexing
        dimuonSelection  = cms.string(""), ## The dimuon must pass this selection before vertexing
        addCommonVertex = cms.bool(True), ## Embed the full reco::Vertex out of the common vertex fit
        addMuonlessPrimaryVertex = cms.bool(True), ## Embed the primary vertex re-made from all the tracks except the two muons
        addMCTruth = cms.bool(MC),      ## Add the common MC mother of the two muons, if any
        resolvePileUpAmbiguity = cms.bool(True)   ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
    )

    # check if there is at least one (inclusive) tracker+tracker di-muon
    process.onia2MuMuPatTrkTrkFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('onia2MuMuPatTrkTrk'),
        minNumber = cms.uint32(1),
    )

    # add tracks
    process.load("PhysicsTools.RecoAlgos.allTracks_cfi")
    process.load("PhysicsTools.RecoAlgos.goodTracks_cfi")
    process.goodTracks.particleType = 'pi+'
    process.goodTracks.cut = 'charge !=0 && found > 4 && pt > 0.4 && hitPattern.pixelLayersWithMeasurement > 0 && abs(d0) < 3.0 && abs(dz) < 25.0 && chi2/ndof < 4.0'
    
    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(
        process.patMuonSequence *
        process.onia2MuMuPatTrkTrk *
        process.allTracks *
        process.goodTracks * 
        process.onia2MuMuPatTrkTrkFilter 
    )

    # Make Tag and Probe pairs for efficiency measurements
    process.tagMuons = cms.EDFilter("PATMuonSelector",
        src = cms.InputTag("patMuonsWithTrigger"),
        cut = cms.string("isGlobalMuon && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"), # do not require trigger at this skim level
    )

    process.probeMuons = cms.EDFilter("PATMuonSelector",
        src = cms.InputTag("patMuonsWithTrigger"),
        cut = cms.string("track.isNonnull"),
    )

    process.tpPairs = cms.EDProducer("CandViewShallowCloneCombiner",
        cut = cms.string('2.6 < mass < 3.5'),
        decay = cms.string('tagMuons@+ probeMuons@-')
    )

    # check if there is at least one Tag and Probe pair
    process.tpPairsFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('tpPairs'),
        minNumber = cms.uint32(1),
    )
    
    # the Tag and Probe path
    process.TagAndProbe = cms.Path(
        process.patMuonSequence *
        process.tagMuons *
        process.probeMuons *
        process.tpPairs *
        process.tpPairsFilter
    )

    if MC:
        process.tagMuonsMCMatch = process.muonMatch.clone(src = "tagMuons")
        process.probeMuonsMCMatch = process.tagMuonsMCMatch.clone(src = "probeMuons")
        process.TagAndProbe.replace(process.tpPairs, process.tagMuonsMCMatch * process.probeMuonsMCMatch * process.tpPairs)

    # output
    process.out = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands = cms.untracked.vstring('drop *',
            'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
      #      'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muos including general tracks and matches to triggers
            'keep *_goodTracks_*_Onia2MuMuPAT',                    # All good tracks (heavy!)  
            'keep patCompositeCandidates_*__Onia2MuMuPAT',         # PAT di-muons
            'keep patMuons_tagMuons__Onia2MuMuPAT',                # tagMuons for efficiency
            'keep patMuons_probeMuons__Onia2MuMuPAT',              # probeMuons for efficiency
            'keep *_tagMuonsMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            'keep *_probeMuonsMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep recoCompositeCandidates_*__Onia2MuMuPAT',        # RECO di-muons, tpPairs for efficiency
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
            'keep L1GlobalTriggerReadoutRecord_gtDigis_*_*',       # Prescale info
            'keep *_l1GtRecord_*_*',                               # Prescale info    
                                               
        ),
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('Onia2MuMuPAT', 'TagAndProbe') ) if Filter else cms.untracked.PSet()
    )
    process.e = cms.EndPath(process.out)
Example #10
0
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary = cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryExtended_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load("Configuration.StandardSequences.MagneticField_cff")
    process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
        inputCommands = cms.untracked.vstring("keep *", "drop *_MEtoEDMConverter_*_*"),
        fileNames = cms.untracked.vstring()
    )

   
    # BSC or HF coincidence (masked unprescaled L1 bits)
    process.load('L1Trigger.Skimmer.l1Filter_cfi')
    process.bscOrHfCoinc = process.l1Filter.clone(
            algorithms = cms.vstring('L1_BscMinBiasThreshold1', 'L1_HcalHfCoincidencePm')
        )

    # Common offline event selection
    process.load("HeavyIonsAnalysis.Configuration.collisionEventSelection_cff")

    # HLT dimuon trigger
    import HLTrigger.HLTfilters.hltHighLevel_cfi
    process.hltOniaHI = HLTrigger.HLTfilters.hltHighLevel_cfi.hltHighLevel.clone()
    process.hltOniaHI.HLTPaths = ["HLT_HIL1DoubleMuOpen","HLT_HIL2DoubleMu0","HLT_HIL2DoubleMu3",
                                   "HLT_HIL1SingleMu3","HLT_HIL1SingleMu5","HLT_HIL1SingleMu7",
                                   "HLT_HIL2Mu20","HLT_HIL2Mu3","HLT_HIL2Mu5Tight"]
    process.hltOniaHI.throw = False
    process.hltOniaHI.andOr = True



    # Merge CaloMuons and General Tracks into the collection of reco::Muons
    process.load("RecoMuon.MuonIdentification.mergedMuons_cfi")
    process.mergedMuons.mergeTracks = True
    process.mergedMuons.tracksCut = '(abs(eta) <= 1.3 && pt > 3.3) || (1.3 < abs(eta) <= 2.2 && p > 2.9) || (2.2 < abs(eta) <= 2.4  && pt > 0.8)'
    process.mergedMuons.caloMuonsCut = process.mergedMuons.tracksCut
    process.mergedMuons.tracks = 'hiSelectedTracks'
 

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer("GenParticlePruner",
        src = cms.InputTag("genParticles"),
        select = cms.vstring(
            "drop  *  ",                     # this is the default
            "++keep abs(pdgId) = 13",        # keep muons and their parents
            "drop pdgId == 21 && status = 2" # remove intermediate qcd spam carrying no flavour info
        )
    )

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
        changeTriggerProcessName(process, HLT)
        switchOffAmbiguityResolution(process) # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon


    #useL1MatchingWindowForSinglets(process)
    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0

    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.bscOrHfCoinc *
        process.hltOniaHI *
        process.collisionEventSelection *
        process.genMuons *
        process.patMuonsWithTriggerSequence
        )
    if not MC:
        process.patMuonSequence.remove(process.genMuons)
      
        # Make dimuon candidates
        process.onia2MuMuPatGlbGlb = cms.EDProducer('Onia2MuMuPAT',
                                                    muons = cms.InputTag("patMuonsWithTrigger"),
                                                    beamSpotTag = cms.InputTag("offlineBeamSpot"),
                                                    primaryVertexTag = cms.InputTag("hiSelectedVertex"),
                                                    # At least one muon must pass this selection
                                                    higherPuritySelection = cms.string("(isGlobalMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
                                                    # BOTH muons must pass this selection
                                                    lowerPuritySelection  = cms.string("(isGlobalMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
                                                    dimuonSelection  = cms.string("2 < mass"), ## The dimuon must pass this selection before vertexing
                                                    addCommonVertex = cms.bool(True), ## Embed the full reco::Vertex out of the common vertex fit
                                                    addMuonlessPrimaryVertex = cms.bool(True), ## Embed the primary vertex re-made from all the tracks except the two muons
                                                    addMCTruth = cms.bool(MC),      ## Add the common MC mother of the two muons, if any
                                                    resolvePileUpAmbiguity = cms.bool(False)   ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
                                                    )

    process.onia2MuMuPatGlbGlbFilter = cms.EDFilter("CandViewCountFilter",
                                                    src = cms.InputTag('onia2MuMuPatGlbGlb'),
                                                    minNumber = cms.uint32(1),
                                                    )

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(
        process.patMuonSequence*
        process.onia2MuMuPatGlbGlb*
        process.onia2MuMuPatGlbGlbFilter
        
    )

    # Make Tag and Probe pairs for efficiency measurements
    process.tagMuons = cms.EDFilter("PATMuonSelector",
        src = cms.InputTag("patMuonsWithTrigger"),
        cut = cms.string("isGlobalMuon && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"), # do not require trigger at this skim level
    )

    process.probeMuons = cms.EDFilter("PATMuonSelector",
        src = cms.InputTag("patMuonsWithTrigger"),
        cut = cms.string("track.isNonnull"),
    )

    process.tpPairs = cms.EDProducer("CandViewShallowCloneCombiner",
        cut = cms.string('2.6 < mass < 3.5'),
        decay = cms.string('tagMuons@+ probeMuons@-')
    )

    # check if there is at least one Tag and Probe pair
    process.tpPairsFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('tpPairs'),
        minNumber = cms.uint32(1),
    )
    
    # the Tag and Probe path
    process.TagAndProbe = cms.Path(
        process.patMuonSequence *
        process.tagMuons *
        process.probeMuons *
        process.tpPairs *
        process.tpPairsFilter
    )

    if MC:
        process.tagMuonsMCMatch = process.muonMatch.clone(src = "tagMuons")
        process.probeMuonsMCMatch = process.tagMuonsMCMatch.clone(src = "probeMuons")
        process.TagAndProbe.replace(process.tpPairs, process.tagMuonsMCMatch * process.probeMuonsMCMatch * process.tpPairs)

    # output
    process.out = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands = cms.untracked.vstring('drop *',
            'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
            'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muos including general tracks and matches to triggers
            'keep patCompositeCandidates_*__Onia2MuMuPAT',         # PAT di-muons
            'keep patMuons_tagMuons__Onia2MuMuPAT',                # tagMuons for efficiency
            'keep patMuons_probeMuons__Onia2MuMuPAT',              # probeMuons for efficiency
            'keep *_tagMuonsMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            'keep *_probeMuonsMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep recoCompositeCandidates_*__Onia2MuMuPAT',        # RECO di-muons, tpPairs for efficiency
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
        ),
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('Onia2MuMuPAT', 'TagAndProbe') ) if Filter else cms.untracked.PSet()
    )
    process.e = cms.EndPath(process.out)
Example #11
0
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary = cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryExtended_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load("Configuration.StandardSequences.MagneticField_cff")
    process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
        inputCommands = cms.untracked.vstring("keep *", "drop *_MEtoEDMConverter_*_*", "drop *_hiEvtPlane_*_*"),
        fileNames = cms.untracked.vstring()
    )
    # Scraping filter
    process.scrapingFilter = cms.EDFilter("FilterOutScraping",
                                          applyfilter = cms.untracked.bool(True),
                                          debugOn = cms.untracked.bool(False),
                                          numtrack = cms.untracked.uint32(10),
                                          thresh = cms.untracked.double(0.25)
                                          )
    # Merge CaloMuons and General Tracks into the collection of reco::Muons
    # nf : this is only used in tnp
    IN_ACCEPTANCE = '( (abs(eta)<1.0 && pt>=3.4) || (1.0<=abs(eta)<1.5 && pt>=5.8-2.4*abs(eta)) || (1.5<=abs(eta)<2.4 && pt>=3.3667-7.0/9.0*abs(eta)) )'
    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer("GenParticlePruner",
        src = cms.InputTag("GenParticles"),
        select = cms.vstring(
            "drop  *  ",                     # this is the default
            "++keep abs(pdgId) = 13",        # keep muons and their parents
            "drop pdgId == 21 && status = 2" # remove intermediate qcd spam carrying no flavour info
        )
    )

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(process) # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    #useL1MatchingWindowForSinglets(process)

    #process.patMuonsWithoutTrigger.pvSrc = "hiSelectedVertex"

    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0


    #process.muonMatchHLTL3.matchedCuts = cms.string('coll("hltHIL3MuonCandidates")')

    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        #process.bscOrHfCoinc *
        process.hltOniaHI *
        process.collisionEventSelection *
        process.scrapingFilter *
        process.genMuons *
        process.patMuonsWithTriggerSequence
    )
    if not MC:
        process.patMuonSequence.remove(process.genMuons)
      
    # Make dimuon candidates
    process.onia2MuMuPatTrkTrk = cms.EDProducer('HiOnia2MuMuPAT',
        muons = cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag = cms.InputTag("offlineBeamSpot"),
        primaryVertexTag = cms.InputTag("offlinePrimaryVertices"),
        # At least one muon must pass this selection
        higherPuritySelection = cms.string("(isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        # BOTH muons must pass this selection
        lowerPuritySelection  = cms.string("(isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        dimuonSelection  = cms.string("2 < mass"), ## The dimuon must pass this selection before vertexing
        addCommonVertex = cms.bool(True), ## Embed the full reco::Vertex out of the common vertex fit
        addMuonlessPrimaryVertex = cms.bool(True), ## Embed the primary vertex re-made from all the tracks except the two muons
        addMCTruth = cms.bool(MC),      ## Add the common MC mother of the two muons, if any
        resolvePileUpAmbiguity = cms.bool(False)   ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
    )

    # check if there is at least one (inclusive) tracker+tracker di-muon
    process.onia2MuMuPatTrkTrkFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('onia2MuMuPatTrkTrk'),
        minNumber = cms.uint32(1),
    )

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(
        process.patMuonSequence *
        process.onia2MuMuPatTrkTrk *
        process.onia2MuMuPatTrkTrkFilter
    )

    
    # output
    process.load('Configuration.EventContent.EventContent_cff')
    process.load("Configuration.EventContent.EventContentHeavyIons_cff")
    
    process.outOnia2MuMu = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands =  cms.untracked.vstring('drop *'),
                                                
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('Onia2MuMuPAT') ) if Filter else cms.untracked.PSet()
    )

    process.outOnia2MuMu.outputCommands.extend(cms.untracked.vstring(
        'keep *_mergedtruth_*_*',                              # tracking particles and tracking vertices for hit by hit matching
        'keep *_GenParticles_*_*',                           # generated particles
        'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
        'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muons including matches to triggers
        'keep patCompositeCandidates_*__Onia2MuMuPAT',         # PAT di-muons
        'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
        'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
        'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
        'keep l1extraL1MuonParticles_hltL1extraParticles_*_*', # L1 info (cheap)
        'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
       )
                            ),




    
    #   process.e = cms.EndPath(process.outOnia2MuMu + process.outTnP)
    process.e = cms.EndPath(process.outOnia2MuMu)
Example #12
0
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary = cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryExtended_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load("Configuration.StandardSequences.MagneticField_cff")
    process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
        inputCommands = cms.untracked.vstring("keep *", "drop *_MEtoEDMConverter_*_*"),
        fileNames = cms.untracked.vstring()
    )
    
    # Merge CaloMuons and General Tracks into the collection of reco::Muons
    IN_ACCEPTANCE = '((abs(eta) < 1.3 && pt >= 3.3) || (1.3 <= abs(eta) < 2.2 && p >= 2.9) || (2.2 <= abs(eta) < 2.4  && pt >= 0.8))'
    process.load("RecoMuon.MuonIdentification.mergedMuons_cfi")
    process.mergedMuons.mergeTracks = True
    process.mergedMuons.tracksCut = IN_ACCEPTANCE
    process.mergedMuons.caloMuonsCut = process.mergedMuons.tracksCut
    process.mergedMuons.tracks = 'hiGlobalPrimTracks'

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer("GenParticlePruner",
        src = cms.InputTag("genParticles"),
        select = cms.vstring(
            "drop  *  ",                     # this is the default
            "++keep abs(pdgId) = 13",        # keep muons and their parents
            "drop pdgId == 21 && status = 2" # remove intermediate qcd spam carrying no flavour info
        )
    )

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    # changeRecoMuonInput(process, "mergedMuons")
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(process) # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    #useL1MatchingWindowForSinglets(process)
    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0

    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.bscOrHfCoinc *
        process.hltOniaHI *
        process.collisionEventSelection *
        # process.mergedMuons *
        process.genMuons *
        process.patMuonsWithTriggerSequence
    )
    if not MC:
        process.patMuonSequence.remove(process.genMuons)
      
    # Make dimuon candidates
    process.onia2MuMuPatGlbGlb = cms.EDProducer('Onia2MuMuPAT',
        muons = cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag = cms.InputTag("offlineBeamSpot"),
        primaryVertexTag = cms.InputTag("hiSelectedVertex"),
        # At least one muon must pass this selection
        higherPuritySelection = cms.string("(isGlobalMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        # BOTH muons must pass this selection
        lowerPuritySelection  = cms.string("(isGlobalMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        dimuonSelection  = cms.string("2 < mass"), ## The dimuon must pass this selection before vertexing
        addCommonVertex = cms.bool(True), ## Embed the full reco::Vertex out of the common vertex fit
        addMuonlessPrimaryVertex = cms.bool(True), ## Embed the primary vertex re-made from all the tracks except the two muons
        addMCTruth = cms.bool(MC),      ## Add the common MC mother of the two muons, if any
        resolvePileUpAmbiguity = cms.bool(False)   ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
    )

    # check if there is at least one (inclusive) tracker+tracker di-muon
    process.onia2MuMuPatGlbGlbFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('onia2MuMuPatGlbGlb'),
        minNumber = cms.uint32(1),
    )

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(
        process.patMuonSequence *
        process.DoubleMuOpenCounter *
        process.onia2MuMuPatGlbGlb *
        process.onia2MuMuPatGlbGlbFilter
    )

    # Make Tag and Probe pairs for efficiency measurements
    TRACK_CUTS = "track.numberOfValidHits > 11 && track.normalizedChi2 < 4"
    GLB_CUTS = "isGlobalMuon && isTrackerMuon && globalTrack.normalizedChi2 < 10  && globalTrack.hitPattern.numberOfValidMuonHits > 0 && abs(dB) < 3 && abs(track.dz) < 30"
#    QUALITY_CUTS = TRACK_CUTS + ' && ' + GLB_CUTS
    QUALITY_CUTS =  GLB_CUTS + ' && ' + TRACK_CUTS

    process.tagMuons = cms.EDFilter("PATMuonSelector",
                                    src = cms.InputTag("patMuonsWithTrigger"),
#                                    cut = cms.string("isGlobalMuon && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35")
                                    cut = cms.string(QUALITY_CUTS + ' && ' + IN_ACCEPTANCE + " && (!triggerObjectMatchesByPath('HLT_HIL2Mu3').empty() || !triggerObjectMatchesByPath('HLT_HIL1SingleMu3').empty())")
                                    )

#    process.oneTag = cms.EDFilter("CandViewCountFilter",
#                                  src = cms.InputTag("tagMuons"),
#                                  minNumber = cms.uint32(1)
#                                  )
#
    # produce patMuons that use the STA momentum information
    process.patMuonsWithTriggerSta = cms.EDProducer("RedefineMuonP4FromTrackPAT",
                                                    src   = cms.InputTag("patMuonsWithTrigger"),
                                                    track = cms.string("outer")
                                                    )

    # must be STA, so we can measure inner tracking efficiency
    process.probeMuonsSta = cms.EDFilter("PATMuonSelector",
                                         src = cms.InputTag("patMuonsWithTriggerSta"),
                                         cut = cms.string("outerTrack.isNonnull && outerTrack.numberOfValidHits>0")
                                         )

    process.tpPairsSta = cms.EDProducer("CandViewShallowCloneCombiner",
                                        cut = cms.string('2.0 < mass < 5.0'),
                                        decay = cms.string('tagMuons@+ probeMuonsSta@-')
                                        )

    # must be a GLB to measure trigger efficiency
    process.probeMuons = cms.EDFilter("PATMuonSelector",
                                      src = cms.InputTag("patMuonsWithTrigger"),
                                      cut = cms.string(QUALITY_CUTS + ' && ' + IN_ACCEPTANCE)
                                      )

    process.tpPairsTrig = cms.EDProducer("CandViewShallowCloneCombiner",
                                     cut = cms.string('2.6 < mass < 3.5'),
                                     decay = cms.string('tagMuons@+ probeMuons@-')
                                     )

    # need the tracks to measure the muon reco efficiency
    process.goodTracks = cms.EDFilter("TrackSelector",
                                      src  = cms.InputTag("hiGlobalPrimTracks"),
                                      cut = cms.string(IN_ACCEPTANCE)
                                      )

    process.tkTracks  = cms.EDProducer("ConcreteChargedCandidateProducer", 
                                       src  = cms.InputTag("goodTracks"),
                                       particleType = cms.string("mu+"),
                                       ) 

    process.probeTracks = cms.EDFilter("CandViewRefSelector",
                                       src = cms.InputTag("tkTracks"),
                                       cut = cms.string(IN_ACCEPTANCE),
                                       )


    process.tpPairsTracks = cms.EDProducer("CandViewShallowCloneCombiner",
                                           cut = cms.string('2.6 < mass < 3.5'),
                                           decay = cms.string('tagMuons@+ probeTracks@-')
                                           )

    # check if there is at least one Tag and Probe pair
    process.tpPairsStaFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('tpPairsSta'),
        minNumber = cms.uint32(1),
    )

    process.tpPairsTrigFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('tpPairsTrig'),
        minNumber = cms.uint32(1),
    )

    process.tpPairsTracksFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('tpPairsTracks'),
        minNumber = cms.uint32(1),
    )
    
#    process.patMuonSequenceSta = cms.Sequence(
#        process.patMuonsWithTriggerSequenceSta
#    )
#
    # the Tag and Probe path
    process.tnpSta = cms.Sequence(
        process.probeMuonsSta *
        process.tpPairsSta *
        process.tpPairsStaFilter
        )

    process.tnpTrig = cms.Sequence(
        process.probeMuons *
        process.tpPairsTrig *
        process.tpPairsTrigFilter
        )

    process.tnpMuID = cms.Sequence(
        process.goodTracks *
        process.tkTracks *
        process.probeTracks *
        process.tpPairsTracks *
        process.tpPairsTracksFilter
        )

    # inner track reco efficiency
    process.TagAndProbeSta = cms.Path(
        process.patMuonSequence *
        process.tagMuons *
        process.patMuonsWithTriggerSta *
        process.tnpSta
    )

    # muon reco and ID efficiency
    process.TagAndProbeMuID = cms.Path(
        process.patMuonSequence *
        process.tagMuons *
        process.tnpMuID
    )

    # muon trigger efficiency
    process.TagAndProbeTrig = cms.Path(
        process.patMuonSequence *
        process.tagMuons *
        process.tnpTrig
    )
    
    if MC:
        process.tagMuonsMCMatch = process.muonMatch.clone(src = "tagMuons")
        process.probeMuonsStaMCMatch = process.tagMuonsMCMatch.clone(src = "probeMuonsSta") # inner tracking eff
        process.probeMuonsTrkMCMatch = process.tagMuonsMCMatch.clone(src = "probeTracks") # Muon reco and ID eff
        process.probeMuonsMCMatch = process.tagMuonsMCMatch.clone(src = "probeMuons") # muon trigger eff
        process.TagAndProbeSta.replace(process.tpPairsSta, process.tagMuonsMCMatch * process.probeMuonsStaMCMatch * process.tpPairsSta)
        process.TagAndProbeMuID.replace(process.tpPairsTracks, process.tagMuonsMCMatch * process.probeMuonsTrkMCMatch * process.tpPairsTracks)
        process.TagAndProbeTrig.replace(process.tpPairsTrig, process.tagMuonsMCMatch * process.probeMuonsMCMatch * process.tpPairsTrig)
    
    # output




    process.outOnia2MuMu = cms.OutputModule("PoolOutputModule",
                                            outputCommands = cms.untracked.vstring('drop *',
                                            #'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
                                            #'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muos including general tracks and matches to triggers
                                            #'keep patCompositeCandidates_*__Onia2MuMuPAT',         # PAT di-muons
                                                                                   
            'keep *_genMuons_*_*',                     
            'keep patMuons_patMuonsWithTrigger_*_*', 
            'keep patCompositeCandidates_*_*_*',
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
            'keep *_generator_*_*',
            'keep *_hiCentrality_*_*',
            'keep *_hiSelectedVertex_*_*',
            'keep *_hiGlobalPrimTracks_*_*',
            'keep *_standAloneMuons_*_*'

        ),

       SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('Onia2MuMuPAT') ) if Filter else cms.untracked.PSet()
    )




    process.outSta = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('tnpSta.root'),
        outputCommands = cms.untracked.vstring('drop *',
            'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
            'keep patMuons_tagMuons__Onia2MuMuPAT',                # tagMuons for efficiency
            'keep patMuons_probeMuonsSta__Onia2MuMuPAT',              # probeMuons for efficiency
            'keep *_tagMuonsMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            'keep *_probeMuonsMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep recoCompositeCandidates_tpPairsSta__Onia2MuMuPAT',        # RECO di-muons, tpPairs for efficiency
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
            'keep *_hiCentrality_*_*',
            'keep *_hiSelectedVertex_*_*',
            'keep *_hiGlobalPrimTracks_*_*'
        ),
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('TagAndProbeSta') ) if Filter else cms.untracked.PSet()
    )

    process.outMuID = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('tnpMuID.root'),
        outputCommands = cms.untracked.vstring('drop *',
            'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
            'keep patMuons_tagMuons__Onia2MuMuPAT',                # tagMuons for efficiency
            'keep patMuons_probeMuons__Onia2MuMuPAT',              # probeMuons for efficiency
            'keep *_tagMuonsMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            'keep *_probeMuonsMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep recoCompositeCandidates_tpPairsTracks__Onia2MuMuPAT',        # RECO di-muons, tpPairs for efficiency
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
            'keep *_hiCentrality_*_*',
            'keep *_hiSelectedVertex_*_*',
        ),
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('TagAndProbeMuID') ) if Filter else cms.untracked.PSet()
    )

    process.outTrig = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('tnpTrig.root'),
        outputCommands = cms.untracked.vstring('drop *',
            'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
            'keep patMuons_tagMuons__Onia2MuMuPAT',                # tagMuons for efficiency
            'keep patMuons_probeMuons__Onia2MuMuPAT',              # probeMuons for efficiency
            'keep *_tagMuonsMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            'keep *_probeMuonsMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep recoCompositeCandidates_tpPairsTrig__Onia2MuMuPAT',        # RECO di-muons, tpPairs for efficiency
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
            'keep *_hiCentrality_*_*',
            'keep *_hiSelectedVertex_*_*',
        ),
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('TagAndProbeTrig') ) if Filter else cms.untracked.PSet()
    )

    process.e = cms.EndPath(process.outOnia2MuMu + process.outSta + process.outMuID + process.outTrig)
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary=cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryExtended_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load("Configuration.StandardSequences.MagneticField_cff")
    process.load(
        "Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
                                inputCommands=cms.untracked.vstring(
                                    "keep *", "drop *_MEtoEDMConverter_*_*"),
                                fileNames=cms.untracked.vstring())

    # Scraping filter
    process.scrapingFilter = cms.EDFilter("FilterOutScraping",
                                          applyfilter=cms.untracked.bool(True),
                                          debugOn=cms.untracked.bool(False),
                                          numtrack=cms.untracked.uint32(10),
                                          thresh=cms.untracked.double(0.25))

    # Merge muons, (calomuons) and tracks in a single collection for T&P
    process.mergedMuons = cms.EDProducer(
        "CaloMuonMerger",
        muons=cms.InputTag("muons"),
        muonsCut=cms.string(""),
        mergeCaloMuons=cms.bool(False),  ### NEEDED TO RUN ON AOD
        caloMuons=cms.InputTag("calomuons"),
        caloMuonsCut=cms.string(""),
        minCaloCompatibility=cms.double(0.6),
        mergeTracks=cms.bool(True),
        tracks=cms.InputTag("generalTracks"),
        #tracksCut = cms.string("(abs(eta) <= 1.3 && pt > 3.3) || (1.3 < abs(eta) <= 2.2 && p > 2.9) || (2.2 < abs(eta) <= 2.4  && pt > 0.8)"),
        tracksCut=cms.string(
            "(abs(eta) <= 0.9 && pt > 2.5) || (0.9 < abs(eta) <=2.4 && pt > 1.5)"
        ),
    )

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer(
        "GenParticlePruner",
        src=cms.InputTag("genParticles"),
        select=cms.vstring(
            "drop  *  ",  # this is the default
            "++keep abs(pdgId) = 13",  # keep muons and their parents
            "drop pdgId == 21 && status = 2"  # remove intermediate qcd spam carrying no flavour info
        ))

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeRecoMuonInput(process, "mergedMuons")
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(
        process
    )  # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    #useL1MatchingWindowForSinglets(process)
    process.muonL1Info.maxDeltaR = 0.3
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0

    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.scrapingFilter * process.mergedMuons * process.genMuons *
        process.patMuonsWithTriggerSequence)
    if not MC:
        process.patMuonSequence.remove(process.genMuons)

    # Make dimuon candidates
    process.onia2MuMuPatTrkTrk = cms.EDProducer(
        'Onia2MuMuPAT',
        muons=cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag=cms.InputTag("offlineBeamSpot"),
        primaryVertexTag=cms.InputTag("offlinePrimaryVertices"),
        # At least one muon must pass this selection
        higherPuritySelection=cms.string(
            "(isGlobalMuon || isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35 && muonID('TrackerMuonArbitrated')"
        ),
        # BOTH muons must pass this selection
        lowerPuritySelection=cms.string(
            "(isGlobalMuon || isTrackerMuon || (innerTrack.isNonnull && genParticleRef(0).isNonnull)) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35 && muonID('TrackerMuonArbitrated')"
        ),
        #dimuonSelection  = cms.string("2 < mass"), ## The dimuon must pass this selection before vertexing
        dimuonSelection=cms.string(
            ""),  ## The dimuon must pass this selection before vertexing
        addCommonVertex=cms.bool(
            True),  ## Embed the full reco::Vertex out of the common vertex fit
        addMuonlessPrimaryVertex=cms.bool(
            True
        ),  ## Embed the primary vertex re-made from all the tracks except the two muons
        addMCTruth=cms.bool(
            MC),  ## Add the common MC mother of the two muons, if any
        resolvePileUpAmbiguity=cms.bool(
            True
        )  ## Order PVs by their vicinity to the J/psi vertex, not by sumPt                            
    )

    # check if there is at least one (inclusive) tracker+tracker di-muon
    process.onia2MuMuPatTrkTrkFilter = cms.EDFilter(
        "CandViewCountFilter",
        src=cms.InputTag('onia2MuMuPatTrkTrk'),
        minNumber=cms.uint32(1),
    )

    # add tracks
    process.load("PhysicsTools.RecoAlgos.allTracks_cfi")
    process.load("PhysicsTools.RecoAlgos.goodTracks_cfi")
    process.goodTracks.particleType = 'pi+'
    process.goodTracks.cut = 'charge !=0 && found > 4 && pt > 0.4 && hitPattern.pixelLayersWithMeasurement > 0 && abs(d0) < 3.0 && abs(dz) < 25.0 && chi2/ndof < 4.0'

    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(process.patMuonSequence *
                                    process.onia2MuMuPatTrkTrk *
                                    process.allTracks * process.goodTracks *
                                    process.onia2MuMuPatTrkTrkFilter)

    # Make Tag and Probe pairs for efficiency measurements
    process.tagMuons = cms.EDFilter(
        "PATMuonSelector",
        src=cms.InputTag("patMuonsWithTrigger"),
        cut=cms.string(
            "isGlobalMuon && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"
        ),  # do not require trigger at this skim level
    )

    process.probeMuons = cms.EDFilter(
        "PATMuonSelector",
        src=cms.InputTag("patMuonsWithTrigger"),
        cut=cms.string("track.isNonnull"),
    )

    process.tpPairs = cms.EDProducer(
        "CandViewShallowCloneCombiner",
        cut=cms.string('2.6 < mass < 3.5'),
        decay=cms.string('tagMuons@+ probeMuons@-'))

    # check if there is at least one Tag and Probe pair
    process.tpPairsFilter = cms.EDFilter(
        "CandViewCountFilter",
        src=cms.InputTag('tpPairs'),
        minNumber=cms.uint32(1),
    )

    # the Tag and Probe path
    process.TagAndProbe = cms.Path(process.patMuonSequence * process.tagMuons *
                                   process.probeMuons * process.tpPairs *
                                   process.tpPairsFilter)

    if MC:
        process.tagMuonsMCMatch = process.muonMatch.clone(src="tagMuons")
        process.probeMuonsMCMatch = process.tagMuonsMCMatch.clone(
            src="probeMuons")
        process.TagAndProbe.replace(
            process.tpPairs, process.tagMuonsMCMatch *
            process.probeMuonsMCMatch * process.tpPairs)

    # output
    process.out = cms.OutputModule(
        "PoolOutputModule",
        fileName=cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands=cms.untracked.vstring(
            'drop *',
            'keep *_genMuons_*_Onia2MuMuPAT',  # generated muons and parents
            #      'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muos including general tracks and matches to triggers
            'keep *_goodTracks_*_Onia2MuMuPAT',  # All good tracks (heavy!)  
            'keep patCompositeCandidates_*__Onia2MuMuPAT',  # PAT di-muons
            'keep patMuons_tagMuons__Onia2MuMuPAT',  # tagMuons for efficiency
            'keep patMuons_probeMuons__Onia2MuMuPAT',  # probeMuons for efficiency
            'keep *_tagMuonsMCMatch__Onia2MuMuPAT',  # tagMuons MC matches for efficiency
            'keep *_probeMuonsMCMatch__Onia2MuMuPAT',  # probeMuons MC matches for efficiency
            'keep recoCompositeCandidates_*__Onia2MuMuPAT',  # RECO di-muons, tpPairs for efficiency
            'keep *_offlinePrimaryVertices_*_*',  # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',  # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',  # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',  # L1 info (cheap)
            'keep L1GlobalTriggerReadoutRecord_gtDigis_*_*',  # Prescale info
            'keep *_l1GtRecord_*_*',  # Prescale info    
        ),
        SelectEvents=cms.untracked.PSet(
            SelectEvents=cms.vstring('Onia2MuMuPAT', 'TagAndProbe'))
        if Filter else cms.untracked.PSet())
    process.e = cms.EndPath(process.out)
Example #14
0
def onia2MuMuPAT(process, GlobalTag, MC=False, HLT='HLT', Filter=True):
    # Setup the process
    process.options = cms.untracked.PSet(
        wantSummary = cms.untracked.bool(True),
        # fileMode = cms.untracked.string('MERGE'),
    )
    process.load("FWCore.MessageService.MessageLogger_cfi")
    process.MessageLogger.cerr.FwkReport.reportEvery = 100
    process.load('Configuration.StandardSequences.GeometryRecoDB_cff')
    process.load('Configuration.StandardSequences.MagneticField_38T_cff')
    process.load("Configuration.StandardSequences.Reconstruction_cff")
    process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
    process.GlobalTag.globaltag = GlobalTag

    # Drop the DQM stuff on input
    process.source = cms.Source("PoolSource",
        inputCommands = cms.untracked.vstring("keep *", "drop *_MEtoEDMConverter_*_*"),
        fileNames = cms.untracked.vstring()
    )

    # Scraping filter
    process.scrapingFilter = cms.EDFilter("FilterOutScraping",
        applyfilter = cms.untracked.bool(True),
        debugOn = cms.untracked.bool(False),
        numtrack = cms.untracked.uint32(10),
        thresh = cms.untracked.double(0.25)
    )

    # Merge muons
    process.mergedMuons = cms.EDProducer("CaloMuonMerger",
        muons     = cms.InputTag("muons"), 
        muonsCut = cms.string(""),
        mergeCaloMuons = cms.bool(False),  ### NEEDED TO RUN ON AOD
        caloMuons = cms.InputTag("calomuons"),
        caloMuonsCut = cms.string(""),
        minCaloCompatibility = cms.double(0.6),
        mergeTracks = cms.bool(True),
        tracks = cms.InputTag("generalTracks"),
        # tracksCut = cms.string("pt > 0.5")
        tracksCut = cms.string("(abs(eta) <= 0.9 && pt > 2.5) || (0.9 < abs(eta) <=2.4 && pt > 1.5)"),
    )

    # Prune generated particles to muons and their parents
    process.genMuons = cms.EDProducer("GenParticlePruner",
        src = cms.InputTag("genParticles"),
        select = cms.vstring(
            "drop  *  ",                     # this is the default
            "++keep abs(pdgId) = 13",        # keep muons and their parents
            "drop pdgId == 21 && status = 2" # remove intermediate qcd spam carrying no flavour info
        )
    )

    # Make PAT Muons
    process.load("MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff")
    from MuonAnalysis.MuonAssociators.patMuonsWithTrigger_cff import addMCinfo, changeRecoMuonInput, useL1MatchingWindowForSinglets, changeTriggerProcessName, switchOffAmbiguityResolution
    # with some customization
    if MC:
        addMCinfo(process)
        # since we match inner tracks, keep the matching tight and make it one-to-one
        process.muonMatch.maxDeltaR = 0.05
        process.muonMatch.resolveByMatchQuality = True
        process.muonMatch.matched = "genMuons"
    changeRecoMuonInput(process, "mergedMuons")
    changeTriggerProcessName(process, HLT)
    switchOffAmbiguityResolution(process) # Switch off ambiguity resolution: allow multiple reco muons to match to the same trigger muon
    #useL1MatchingWindowForSinglets(process)
    process.muonL1Info.maxDeltaR     = 0.3 
    process.muonL1Info.fallbackToME1 = True
    process.muonMatchHLTL1.maxDeltaR = 0.3
    process.muonMatchHLTL1.fallbackToME1 = True
    process.muonMatchHLTL2.maxDeltaR = 0.3
    process.muonMatchHLTL2.maxDPtRel = 10.0
    process.muonMatchHLTL3.maxDeltaR = 0.1
    process.muonMatchHLTL3.maxDPtRel = 10.0
    process.muonMatchHLTCtfTrack.maxDeltaR = 0.1
    process.muonMatchHLTCtfTrack.maxDPtRel = 10.0
    process.muonMatchHLTTrackMu.maxDeltaR = 0.1
    process.muonMatchHLTTrackMu.maxDPtRel = 10.0

    # Make a sequence
    process.patMuonSequence = cms.Sequence(
        process.scrapingFilter *
        process.mergedMuons *
        process.genMuons *
        process.patMuonsWithTriggerSequence
    )
    if not MC:
        process.patMuonSequence.remove(process.genMuons)

    # Make dimuon candidates
    process.onia2MuMuPatTrkTrk = cms.EDProducer('Onia2MuMuPAT',
        muons = cms.InputTag("patMuonsWithTrigger"),
        beamSpotTag = cms.InputTag("offlineBeamSpot"),
        primaryVertexTag = cms.InputTag("offlinePrimaryVertices"),
        # At least one muon must pass this selection
        higherPuritySelection  = cms.string("(isGlobalMuon || isTrackerMuon) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        # BOTH muons must pass this selection
        lowerPuritySelection  = cms.string("(isGlobalMuon || isTrackerMuon) && abs(innerTrack.dxy)<4 && abs(innerTrack.dz)<35"),
        # The dimuon must pass this selection before vertexing
        dimuonSelection  = cms.string("4.5 < mass && mass < 6.3"),
        # Embed the full reco::Vertex out of the common vertex fit
        addCommonVertex = cms.bool(True),
        # Embed the primary vertex re-made from all the tracks except the two muons
        addMuonlessPrimaryVertex = cms.bool(True),
        # Add the common MC mother of the two muons, if any
        addMCTruth = cms.bool(MC),
        # Order PVs by their vicinity to the J/psi vertex, not by sumPt
        resolvePileUpAmbiguity = cms.bool(True),
        addThirdTrack = cms.bool(False),  ## search a third track making a good vertex with the dimuon
        minTrackPt =cms.double(0.5), ## minimum pt of the third track
        trackMass = cms.double(0.4936), ## mass for the track
        diMuPlusTrackMassMax = cms.double(5.9),
        diMuPlusTrackMassMin = cms.double(4.9),
        diMuMassMax = cms.double(3.2),## dimuon mass range where to search for the third track
        diMuMassMin = cms.double(2.8),
        # track selection, taken from https://cmssdt.cern.ch/SDT/lxr/source/Validation/RecoVertex/test/redoPV_cfg.py#040
        TkFilterParameters = cms.PSet(
          algorithm = cms.string('filterWithThreshold'),
          maxNormalizedChi2 = cms.double(5.0),
          minSiliconLayersWithHits = cms.int32(0), ## >=0 (was 5 for generalTracks)
          minPixelLayersWithHits = cms.int32(2),   ## >=2 (was 2 for generalTracks)
          maxD0Significance = cms.double(3.0),     ## keep most primary tracks (was 5.0)
          minPt = cms.double(0.0),                 ## better for softish events
          trackQuality = cms.string("any"),
          numTracksThreshold = cms.int32(2)
#          minPt = cms.double(0.0),                   # direct pt cut
#          maxD0Significance = cms.double(5.0),       # impact parameter significance
#          maxNormalizedChi2 = cms.double(5.0),       # loose cut on track chi**2
#          minPixelLayersWithHits = cms.int32(2),     # two or more pixel layers
#          minSiliconLayersWithHits = cms.int32(5),   # five or more tracker layers (includes pixels)
#          trackQuality = cms.string("any")           # track quality not used
        ),
        # track clustering, taken from https://cmssdt.cern.ch/SDT/lxr/source/Validation/RecoVertex/test/redoPV_cfg.py#076
        TkDAClusParameters = cms.PSet(
          coolingFactor = cms.double(0.8),  #  slow annealing
          Tmin = cms.double(4.0),           #  freezeout temperature
          vertexSize = cms.double(0.05)     #  ~ resolution / sqrt(Tmin)
        ),
        # Preselection cuts
        # userInt('Ntrk') < 21 &&
        preselection = cms.string("userFloat('kinMass') > 4.5 && userFloat('kinMass') < 6.3 && pt > 5. && pt < 9999. && daughter('muon1').pt > 4. && daughter('muon1').pt < 999. && daughter('muon2').pt > 4. && daughter('muon2').pt < 999. && userFloat('l3d') < 2. && userFloat('l3dsig') > 0. && userFloat('l3dsig') < 200. && userFloat('vNChi2') < 20. && userFloat('delta3d') < 0.1 && userFloat('delta3d')/userFloat('delta3dErr') < 5. && userFloat('DCA') < 0.1 && acos(userFloat('cosAlpha3D')) < 1.0 && userFloat('minDca') < 2.50 && userFloat('Isolation20') > 0. && userFloat('lxysig') > 2. && abs(userFloat('pvlip')) < 1. && (abs(userFloat('pvlip'))/abs(userFloat('pvlipErr'))) < 5."),
        # preselection = cms.string("mass > 4.5 && mass < 6.3 && pt > 5. && pt < 9999. && daughter('muon1').pt > 4. && daughter('muon1').pt < 999. && daughter('muon2').pt > 4. && daughter('muon2').pt < 999."),
    )

    # check if there is at least one (inclusive) tracker+tracker di-muon
    process.onia2MuMuPatTrkTrkFilter = cms.EDFilter("CandViewCountFilter",
        src = cms.InputTag('onia2MuMuPatTrkTrk', 'DiMu'),
        minNumber = cms.uint32(1),
    )

    process.onia2MuMuPatMassFilter = cms.EDFilter("CandViewSelector",
        src = cms.InputTag('onia2MuMuPatTrkTrk', 'DiMu'),
        cut = cms.string("userFloat('kinMass') > 4.5 && userFloat('kinMass') < 6.3 && pt > 5. && pt < 9999. && daughter('muon1').pt > 4. && daughter('muon1').pt < 999. && daughter('muon2').pt > 4. && daughter('muon2').pt < 999. && userFloat('l3d') < 2. && userFloat('l3dsig') > 0. && userFloat('l3dsig') < 200. && userFloat('vNChi2') < 20. && userFloat('delta3d') < 0.1 && userFloat('delta3d')/userFloat('delta3dErr') < 5. && userFloat('DCA') < 0.1 && acos(userFloat('cosAlpha3D')) < 1.0 && userFloat('minDca') < 2.50 && userFloat('Isolation20') > 0. && userFloat('lxysig') > 2. && abs(userFloat('pvlip')) < 1. && (abs(userFloat('pvlip'))/abs(userFloat('pvlipErr'))) < 5."),
        # cut = cms.string(""),
        filter = cms.bool(True)
    )

    # add tracks
    process.load("PhysicsTools.RecoAlgos.allTracks_cfi")
    process.load("PhysicsTools.RecoAlgos.goodTracks_cfi")
    process.goodTracks.particleType = 'pi+'
    # process.goodTracks.cut = 'charge !=0 && found > 1 && pt > 0.5 && hitPattern.pixelLayersWithMeasurement > 0 && abs(d0) < 3.0 && abs(dz) < 25.0 && chi2/ndof < 4.0'
    process.goodTracks.cut = 'charge !=0 && pt > 0.5'

    process.nEventsTotal = cms.EDProducer("EventCountProducer")
    process.nEventsAfterFilter = cms.EDProducer("EventCountProducer")
    
    # the onia2MuMu path
    process.Onia2MuMuPAT = cms.Path(
        process.nEventsTotal *
        process.patMuonSequence *
        process.onia2MuMuPatTrkTrk *
        process.allTracks *
        process.goodTracks *
        process.onia2MuMuPatTrkTrkFilter *
        process.onia2MuMuPatMassFilter *
        process.nEventsAfterFilter
    )


    # output
    process.out = cms.OutputModule("PoolOutputModule",
        fileName = cms.untracked.string('onia2MuMuPAT.root'),
        outputCommands = cms.untracked.vstring('drop *',
            'keep *_genMuons_*_Onia2MuMuPAT',                      # generated muons and parents
             # 'keep patMuons_patMuonsWithTrigger_*_Onia2MuMuPAT',    # All PAT muos including general tracks and matches to triggers
            'keep *_goodTracks_*_Onia2MuMuPAT',                    # All good tracks (heavy!)  
             # 'keep patCompositeCandidates_*__Onia2MuMuPAT',       # PAT di-muons
            'keep patCompositeCandidates_*_*_Onia2MuMuPAT',        # PAT di-muons and dimuons+track
            # 'keep patMuons_tagMuons__Onia2MuMuPAT',                # tagMuons for efficiency
            # 'keep patMuons_probeMuons__Onia2MuMuPAT',              # probeMuons for efficiency
            # 'keep *_tagMuonsMCMatch__Onia2MuMuPAT',                # tagMuons MC matches for efficiency
            # 'keep *_probeMuonsMCMatch__Onia2MuMuPAT',              # probeMuons MC matches for efficiency
            'keep recoCompositeCandidates_*__Onia2MuMuPAT',        # RECO di-muons, tpPairs for efficiency
            'keep *_offlinePrimaryVertices_*_*',                   # Primary vertices: you want these to compute impact parameters
            'keep *_offlineBeamSpot_*_*',                          # Beam spot: you want this for the same reason                                   
            'keep edmTriggerResults_TriggerResults_*_*',           # HLT info, per path (cheap)
            'keep l1extraL1MuonParticles_l1extraParticles_*_*',    # L1 info (cheap)
            'keep L1GlobalTriggerReadoutRecord_gtDigis_*_*',       # Prescale info
            'keep *_l1GtRecord_*_*',                               # Prescale info
            'keep edmMergeableCounter_*_*_*'                       # Count the number of events before and after filters
            #'keep *_*_DiMu_*'
        ),
        # outputCommands = cms.untracked.vstring('keep *'),
        SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('Onia2MuMuPAT') ) if Filter else cms.untracked.PSet()
    )
    process.e = cms.EndPath(process.out)