def makePromptJPsi(name): """ Prompt variant of the detached JPsi selection for B--> JPsi X calibration and normalization channels. Selection is aligned to the Bs2MuMu selection. heavily prescaled Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter PromptJPsi = CombineParticles("Combine" + name) PromptJPsi.DecayDescriptor = "J/psi(1S) -> mu+ mu-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: PromptJPsi.addTool(OfflineVertexFitter()) PromptJPsi.VertexFitters.update({"": "OfflineVertexFitter"}) PromptJPsi.OfflineVertexFitter.useResonanceVertex = False PromptJPsi.ReFitPVs = True PromptJPsi.DaughtersCuts = {"mu+": "(TRCHI2DOF < 4 ) "} PromptJPsi.CombinationCut = "(ADAMASS('J/psi(1S)')<100*MeV) "\ "& (AMAXDOCA('')<0.3*mm)" PromptJPsi.MotherCut = "(VFASPF(VCHI2)<15) "\ "& (ADMASS('J/psi(1S)') < 100*MeV )" _stdLooseMuons = DataOnDemand(Location="Phys/StdLooseMuons/Particles") return Selection(name, Algorithm=PromptJPsi, RequiredSelections=[_stdLooseMuons])
def makeDetachedJPsiLoose(name): """ loose detached JPsi selection to monitor selection, systematics from cuts, etc. prescaled Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter DetachedJPsiLoose = CombineParticles("Combine" + name) DetachedJPsiLoose.DecayDescriptor = "J/psi(1S) -> mu+ mu-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: DetachedJPsiLoose.addTool(OfflineVertexFitter()) DetachedJPsiLoose.VertexFitters.update({"": "OfflineVertexFitter"}) DetachedJPsiLoose.OfflineVertexFitter.useResonanceVertex = False DetachedJPsiLoose.ReFitPVs = True DetachedJPsiLoose.DaughtersCuts = { "mu+" : "(TRCHI2DOF < 10 ) "\ "& (MIPCHI2DV(PRIMARY)> 9.)"} DetachedJPsiLoose.CombinationCut = "(ADAMASS('J/psi(1S)')<120*MeV) "\ "& (AMAXDOCA('')<0.5*mm)" DetachedJPsiLoose.MotherCut = "(VFASPF(VCHI2)<25) "\ "& (ADMASS('J/psi(1S)') < 120*MeV )"\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2>100)" _stdLooseMuons = DataOnDemand(Location="Phys/StdLooseMuons/Particles") return Selection(name, Algorithm=DetachedJPsiLoose, RequiredSelections=[_stdLooseMuons])
def makeD2MuMuMuMu(name): """ D --> 4 mu selection should become inclusive bb-->4 mu selection ?? """ from Configurables import OfflineVertexFitter D2MuMuMuMu = CombineParticles("Combine" + name) D2MuMuMuMu.DecayDescriptor = "D0 -> mu+ mu- mu+ mu-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: D2MuMuMuMu.addTool(OfflineVertexFitter()) D2MuMuMuMu.VertexFitters.update({"": "OfflineVertexFitter"}) D2MuMuMuMu.OfflineVertexFitter.useResonanceVertex = False D2MuMuMuMu.ReFitPVs = True D2MuMuMuMu.DaughtersCuts = { "mu+" : "(TRCHI2DOF < 5 ) "\ " & (MIPCHI2DV(PRIMARY)> 9.)"} D2MuMuMuMu.CombinationCut = "(ADAMASS('D0')<1000*MeV) "\ "& (AMAXDOCA('')<0.3*mm) " D2MuMuMuMu.MotherCut = "(VFASPF(VCHI2/VDOF)<10) "\ "& (BPVDIRA > 0.9998) "\ "& (BPVVDCHI2>48.)"\ " & (M>864.83) & (M<2868.47)"\ "& (BPVIPCHI2()< 30) " _stdLooseMuons = DataOnDemand(Location="Phys/StdLooseMuons/Particles") return Selection(name, Algorithm=D2MuMuMuMu, RequiredSelections=[_stdLooseMuons])
def makeBs2Kst_0Kst_0(name, Kst_0sel, BMassWin, BVCHI2, BDOCA, BIPCHI2, BFDistanceCHI2, SumPT, BDIRA): """ Create and return a Bs -> Kstar_0(1430)(Kpi) anti-Kstar_0(1430)(Kpi) Selection object. Arguments: name : name of the Selection. Kst_0sel : Kst_0(1430) -> K+pi- Selection object. BMassWin : Bs invariant mass window around PDG mass value (MeV). BVCHI2 : Maximum Bs vertex chi2 per degree of freedom. BDOCA : Maximum Bs DOCA. BFDistanceCHI2 : Minimum Bs Flight Distance chi2. SumPT : Sum|pT| of the daughters. """ _motherCuts = " (VFASPF(VCHI2/VDOF) < %(BVCHI2)s) & (MIPCHI2DV(PRIMARY)< %(BIPCHI2)s) & (BPVVDCHI2 > %(BFDistanceCHI2)s) & (BPVDIRA > %(BDIRA)s)" % locals( ) _combinationCut = "(ADAMASS('B_s0') < %(BMassWin)s *MeV) & (AMAXDOCA('')< %(BDOCA)s *mm) "\ "& ( (AMINCHILD(PT,ID=='K+') + AMINCHILD(PT,ID=='K-') + AMINCHILD(PT,ID=='pi-') + AMINCHILD(PT,ID=='pi+'))> %(SumPT)s *MeV)" % locals() _Bs = CombineParticles('_' + name) _Bs.DecayDescriptor = "B_s0 -> K*_0(1430)0 K*_0(1430)~0" _Bs.CombinationCut = _combinationCut _Bs.MotherCut = _motherCuts _Bs.ReFitPVs = True _Bs.addTool(OfflineVertexFitter) # _Bs.VertexFitters.update( { "" : "OfflineVertexFitter"} ) _Bs.ParticleCombiners.update({"": "OfflineVertexFitter" }) # Fix for DaVinci v32r0 by A.Poluektov _Bs.OfflineVertexFitter.useResonanceVertex = False return Selection(name, Algorithm=_Bs, RequiredSelections=[Kst_0sel])
def makeBd2InflatonRho(name, SelInflatonLong, SelRho) : """ detached Bd -> Inflaton rho selection. Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter Bd2InflatonRho = CombineParticles("Combine"+name) Bd2InflatonRho.DecayDescriptor = "B0 -> KS0 rho(770)0" Bd2InflatonRho.addTool( OfflineVertexFitter ) #Bd2InflatonRho.VertexFitters.update( { "" : "OfflineVertexFitter"} ) Bd2InflatonRho.ParticleCombiners.update( { "" : "OfflineVertexFitter"} ) Bd2InflatonRho.OfflineVertexFitter.useResonanceVertex = False Bd2InflatonRho.ReFitPVs = True Bd2InflatonRho.DaughtersCuts = { "rho(770)0" : "MIPCHI2DV(PRIMARY)> 25."} Bd2InflatonRho.CombinationCut = "(ADAMASS('B0') < 500*MeV)" Bd2InflatonRho.MotherCut = "(BPVIPCHI2()< 50) & (VFASPF(VCHI2)<100)& (D2DVVDDOT(1) > 0.3*mm)" return Selection( "Sel"+name, Algorithm = Bd2InflatonRho, RequiredSelections=[SelInflatonLong, SelRho] )
def makeDefault(name) : """ default Bs2mumu selection object (tighter selection a la roadmap) starts from Phys/StdNoPIDsMuons Please contact Johannes Albrecht if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter Bs2MuMuNoMuID = CombineParticles("Comine"+name) Bs2MuMuNoMuID.DecayDescriptor = "B_s0 -> mu+ mu-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: Bs2MuMuNoMuID.addTool( OfflineVertexFitter() ) Bs2MuMuNoMuID.VertexFitters.update( { "" : "OfflineVertexFitter"} ) Bs2MuMuNoMuID.OfflineVertexFitter.useResonanceVertex = False Bs2MuMuNoMuID.ReFitPVs = True Bs2MuMuNoMuID.DaughtersCuts = { "mu+" : "(MIPCHI2DV(PRIMARY)> 25.)&(TRCHI2DOF < 4 )" } Bs2MuMuNoMuID.CombinationCut = "(ADAMASS('B_s0')<600*MeV)"\ "& (AMAXDOCA('')<0.3*mm)" Bs2MuMuNoMuID.MotherCut = "(VFASPF(VCHI2/VDOF)<9) "\ "& (ADMASS('B_s0') < 600*MeV )"\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2> 225)"\ "& (BPVIPCHI2()< 25) " _stdNoPIDsMuons = DataOnDemand(Location = "Phys/StdNoPIDsMuons/Particles") return Selection (name, Algorithm = Bs2MuMuNoMuID, RequiredSelections = [ _stdNoPIDsMuons])
def makeK0s2mm(name) : """ K0s2mumu selection object with muon Id and wide mass window starts from Phys/StdLooseMuons Please contact Diego Martinez Santos if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter K0s2MuMu = CombineParticles("Combine"+name) K0s2MuMu.DecayDescriptor = "KS0 -> mu+ mu-" K0s2MuMu.addTool( OfflineVertexFitter ) K0s2MuMu.ParticleCombiners.update( { "" : "OfflineVertexFitter"} ) K0s2MuMu.OfflineVertexFitter.useResonanceVertex = False K0s2MuMu.ReFitPVs = True K0s2MuMu.DaughtersCuts = { "mu+" : "(MIPCHI2DV(PRIMARY)> 100.)&(TRCHI2DOF < 5 )" } K0s2MuMu.CombinationCut ="(ADAMASS('KS0')<1000*MeV)"\ "& (AMAXDOCA('')<0.3*mm)" K0s2MuMu.MotherCut = "((BPVDIRA>0) & ((BPVVDSIGN*M/P) > 0.1*89.53*2.9979e-01) & (MIPDV(PRIMARY)<0.4*mm) & (M>450))" _stdLooseMuons = DataOnDemand(Location = "Phys/StdLooseMuons/Particles") return Selection (name, Algorithm = K0s2MuMu, RequiredSelections = [ _stdLooseMuons])
def makeBs2PhiKst(name, Phisel, Kstsel, BMassWin, BVCHI2, BDOCA): """ Create and return a Bs -> Phi (KK) Kstar (Kpi) Selection object. Arguments: name : name of the Selection. Phisel : Phi -> K+K- Selection object. Kstsel : Kst -> K+pi- Selection object. BMassWin : Bs invariant mass window around PDG mass value (MeV). BVCHI2 : Maximum Bs vertex chi2 per degree of freedom. BDOCA : Maximum Bs DOCA. """ _motherCuts = "(VFASPF(VCHI2/VDOF) < %(BVCHI2)s)" % locals() _combinationCut = "(ADAMASS('B_s0') < %(BMassWin)s *MeV) & (AMAXDOCA('')< %(BDOCA)s *mm)" % locals( ) _Bs = CombineParticles('_' + name) _Bs.DecayDescriptor = "[B_s0 -> phi(1020) K*(892)~0]cc" _Bs.CombinationCut = _combinationCut _Bs.MotherCut = _motherCuts _Bs.ReFitPVs = True _Bs.addTool(OfflineVertexFitter()) _Bs.VertexFitters.update({"": "OfflineVertexFitter"}) _Bs.OfflineVertexFitter.useResonanceVertex = False return Selection(name, Algorithm=_Bs, RequiredSelections=[Phisel, Kstsel])
def makeDetachedJPsi(name): """ detached JPsi selection for B--> JPsi X calibration and normalization channels. Please contact Flavio Archilli if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter DetachedJPsi = CombineParticles("Combine" + name) DetachedJPsi.DecayDescriptor = "J/psi(1S) -> e+ e-" DetachedJPsi.addTool(OfflineVertexFitter) DetachedJPsi.ParticleCombiners.update({"": "OfflineVertexFitter"}) DetachedJPsi.OfflineVertexFitter.useResonanceVertex = False DetachedJPsi.ReFitPVs = True DetachedJPsi.DaughtersCuts = { "e+" : "(TRCHI2DOF < 4 ) "\ "& (MIPCHI2DV(PRIMARY)> 25.) "\ "& (PIDe > 2) "} DetachedJPsi.CombinationCut = "(ADAMASS('J/psi(1S)')<1000*MeV) "\ "& (AMAXDOCA('')<0.3*mm)" DetachedJPsi.MotherCut = "(VFASPF(VCHI2)<9) "\ "& (ADMASS('J/psi(1S)') < 1000*MeV )"\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2>169)" _stdLooseElectrons = DataOnDemand( Location="Phys/StdLooseElectrons/Particles") return Selection(name, Algorithm=DetachedJPsi, RequiredSelections=[_stdLooseElectrons])
def makeNoMuID(name, mupt=0, kspt=0): """ default K0s2mumu selection object starts from Phys/StdNoPIDsMuons Please contact Diego Martinez Santos if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter K0s2MuMuNoMuID = CombineParticles("Comine" + name) K0s2MuMuNoMuID.DecayDescriptor = "KS0 -> pi+ pi-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: K0s2MuMuNoMuID.addTool(OfflineVertexFitter) K0s2MuMuNoMuID.ParticleCombiners.update({"": "OfflineVertexFitter"}) K0s2MuMuNoMuID.OfflineVertexFitter.useResonanceVertex = False K0s2MuMuNoMuID.ReFitPVs = True K0s2MuMuNoMuID.DaughtersCuts = { "pi+": "(MIPCHI2DV(PRIMARY)> 100.)&(TRCHI2DOF < 5 ) & (PT >" + str(mupt) + " * MeV )" } K0s2MuMuNoMuID.CombinationCut = "(ADAMASS('KS0')<100*MeV)"\ "& (AMAXDOCA('')<0.3*mm)" K0s2MuMuNoMuID.MotherCut = "((BPVDIRA>0) & ((BPVVDSIGN*M/P) > 0.1*89.53*2.9979e-01) & (MIPDV(PRIMARY)<0.4*mm) & (M>400) & (M<600) & (PT > " + str( kspt) + " * MeV))" _stdNoPIDsPions = DataOnDemand(Location="Phys/StdNoPIDsPions/Particles") return Selection(name, Algorithm=K0s2MuMuNoMuID, RequiredSelections=[_stdNoPIDsPions])
def makeBd2InflatonKst(name, SelInflatonLong): """ detached Bd -> Inflaton K* selection. Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter _kstar = DataOnDemand(Location='Phys/StdLooseDetachedKst2Kpi/Particles') Bd2InflatonKst = CombineParticles("Combine" + name) Bd2InflatonKst.DecayDescriptor = "[B0 -> KS0 K*(892)0]cc" Bd2InflatonKst.addTool(OfflineVertexFitter) #Bd2InflatonKst.VertexFitters.update( { "" : "OfflineVertexFitter"} ) Bd2InflatonKst.ParticleCombiners.update({"": "OfflineVertexFitter"}) Bd2InflatonKst.OfflineVertexFitter.useResonanceVertex = False Bd2InflatonKst.ReFitPVs = True Bd2InflatonKst.DaughtersCuts = {"K*(892)0": "MIPCHI2DV(PRIMARY)> 25."} Bd2InflatonKst.CombinationCut = "(ADAMASS('B0') < 500*MeV)" Bd2InflatonKst.MotherCut = "(BPVIPCHI2()< 50) & (VFASPF(VCHI2)<100)& (D2DVVDDOT(1) > 0.3*mm)" return Selection("Sel" + name, Algorithm=Bd2InflatonKst, RequiredSelections=[SelInflatonLong, _kstar])
def makeBs2InflatonPhi(name, SelInflatonLong): """ detached Bs -> Inflaton Phi selection. Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter _phi = DataOnDemand(Location='Phys/StdLooseDetachedPhi2KK/Particles') Bs2InflatonPhi = CombineParticles("Combine" + name) Bs2InflatonPhi.DecayDescriptor = "B_s0 -> KS0 phi(1020)" Bs2InflatonPhi.addTool(OfflineVertexFitter) #Bs2InflatonPhi.VertexFitters.update( { "" : "OfflineVertexFitter"} ) Bs2InflatonPhi.ParticleCombiners.update({"": "OfflineVertexFitter"}) Bs2InflatonPhi.OfflineVertexFitter.useResonanceVertex = False Bs2InflatonPhi.ReFitPVs = True Bs2InflatonPhi.DaughtersCuts = {"phi(1020)": "MIPCHI2DV(PRIMARY)> 25."} Bs2InflatonPhi.CombinationCut = "(ADAMASS('B_s0') < 500*MeV)" Bs2InflatonPhi.MotherCut = "(BPVIPCHI2()< 50)& (VFASPF(VCHI2)<100)& (D2DVVDDOT(1) > 0.3*mm)" return Selection("Sel" + name, Algorithm=Bs2InflatonPhi, RequiredSelections=[SelInflatonLong, _phi])
def makeBu2InflatonK(name, SelInflatonLong): """ detached Bu -> Inflaton K selection. Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter Bu2InflatonK = CombineParticles("Combine" + name) Bu2InflatonK.DecayDescriptor = " [B+ -> KS0 K+]cc " Bu2InflatonK.addTool(OfflineVertexFitter) #Bu2InflatonK.VertexFitters.update( { "" : "OfflineVertexFitter"} ) Bu2InflatonK.ParticleCombiners.update({"": "OfflineVertexFitter"}) Bu2InflatonK.OfflineVertexFitter.useResonanceVertex = False Bu2InflatonK.ReFitPVs = True Bu2InflatonK.DaughtersCuts = { "K+": "(ISLONG) & (TRCHI2DOF < 3 ) &(MIPCHI2DV(PRIMARY)>25)& (PT>250*MeV) " } Bu2InflatonK.CombinationCut = "(ADAMASS('B+') < 500*MeV)" Bu2InflatonK.MotherCut = "(BPVIPCHI2()< 50)& (VFASPF(VCHI2)<100)& (D2DVVDDOT(1) > 0.3*mm)" _kaons = DataOnDemand(Location='Phys/StdLooseKaons/Particles') return Selection("Sel" + name, Algorithm=Bu2InflatonK, RequiredSelections=[SelInflatonLong, _kaons])
def makeSidebandRegion(self, name): """ K0s2pi0mumu selection object in sideband region. Arguments: name : name of the Selection """ from Configurables import OfflineVertexFitter K0s2Pi0MuMu2 = CombineParticles("Combine" + name) K0s2Pi0MuMu2.DecayDescriptor = "KS0 -> pi0 J/psi(1S)" K0s2Pi0MuMu2.addTool(OfflineVertexFitter) K0s2Pi0MuMu2.ParticleCombiners.update({"": "OfflineVertexFitter"}) K0s2Pi0MuMu2.OfflineVertexFitter.useResonanceVertex = False K0s2Pi0MuMu2.ReFitPVs = True K0s2Pi0MuMu2.CombinationCut = " (AM > %(KSsidebminMass)s * MeV)"\ "& (AM < %(KSsidebmaxMass)s * MeV)" %self.config K0s2Pi0MuMu2.MotherCut = "((BPVDIRA> %(KSdira)s ) "\ "& ((BPVVDSIGN*M/P) > %(KSlife)s*2.9979e-01) "\ "& (MIPDV(PRIMARY)<%(KSip)s*mm) "\ "& (M> %(KSsidebminMass)s * MeV) "\ "& ( (M< %(KSsidebmaxMass)s * MeV) ))" %self.config return Selection( name, Algorithm=K0s2Pi0MuMu2, RequiredSelections=[self.PseudoJPsiSel, self._stdLoosePi0s])
def makeBs2mmWide(name): """ Bs2mumu selection object (tighter selection a la roadmap) with muon Id and wide mass window (1.2GeV) starts from Phys/StdLooseMuons Please contact Johannes Albrecht if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter Bs2MuMuWideMass = CombineParticles("Combine" + name) Bs2MuMuWideMass.DecayDescriptor = "B_s0 -> mu+ mu-" Bs2MuMuWideMass.addTool(OfflineVertexFitter()) Bs2MuMuWideMass.VertexFitters.update({"": "OfflineVertexFitter"}) Bs2MuMuWideMass.OfflineVertexFitter.useResonanceVertex = False Bs2MuMuWideMass.ReFitPVs = True Bs2MuMuWideMass.DaughtersCuts = { "mu+": "(MIPCHI2DV(PRIMARY)> 25.)&(TRCHI2DOF < 4 )" } Bs2MuMuWideMass.CombinationCut = "(ADAMASS('B_s0')<1200*MeV)"\ "& (AMAXDOCA('')<0.3*mm)" Bs2MuMuWideMass.MotherCut = "(VFASPF(VCHI2/VDOF)<9) "\ "& (ADMASS('B_s0') < 1200*MeV )"\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2> 225)"\ "& (BPVIPCHI2()< 25) " _stdLooseMuons = DataOnDemand(Location="Phys/StdLooseMuons/Particles") return Selection(name, Algorithm=Bs2MuMuWideMass, RequiredSelections=[_stdLooseMuons])
def makeDefault(name): """ very detached JPSi selection """ from Configurables import OfflineVertexFitter Detached2mu = CombineParticles("Combine" + name) Detached2mu.DecayDescriptor = "J/psi(1S) -> mu+ mu-" Detached2mu.addTool(OfflineVertexFitter) Detached2mu.VertexFitters.update({"": "OfflineVertexFitter"}) Detached2mu.OfflineVertexFitter.useResonanceVertex = False Detached2mu.ReFitPVs = True Detached2mu.DaughtersCuts = { "mu+" : "(TRCHI2DOF < 4 ) "\ " & (MIPCHI2DV(PRIMARY)> 100)"\ "& (PT > 0.7) "} Detached2mu.CombinationCut = " (AMAXDOCA('')<0.1*mm)" #"(ADAMASS('B_s0')<1000*MeV) "\ Detached2mu.MotherCut = "(VFASPF(VCHI2/VDOF)<15) "\ "& (M>1500)"\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2>625)"\ "& (BPVVD>50)" _stdLooseMuons = DataOnDemand(Location="Phys/StdLooseMuons/Particles") return Selection(name, Algorithm=Detached2mu, RequiredSelections=[_stdLooseMuons])
def makeBd2JPsiKst(name, JPsisel, Kstsel, BMassWin, BVCHI2, BDOCA, BIPCHI2): """ Create and return a Bd -> JPsi(mumu) Kstar (Kpi) Selection object. Arguments: name : name of the Selection. JPsisel : JPsi -> mu+ mu- Selection object. Kstsel : Kst -> K+pi- Selection object. BMassWin : Bd invariant mass window around PDG mass value (MeV). BVCHI2 : Maximum Bd vertex chi2 per degree of freedom. BDOCA : Maximum Bd DOCA. """ _motherCuts = " (VFASPF(VCHI2/VDOF) < %(BVCHI2)s) & (MIPCHI2DV(PRIMARY)< %(BIPCHI2)s)" % locals( ) _combinationCut = "(ADAMASS('B_s0') < %(BMassWin)s *MeV) & (AMAXDOCA('')< %(BDOCA)s *mm)" % locals( ) _Bd = CombineParticles('_' + name) _Bd.DecayDescriptor = "[B0 -> J/psi(1S) K*(892)0]cc" _Bd.CombinationCut = _combinationCut _Bd.MotherCut = _motherCuts _Bd.ReFitPVs = True _Bd.addTool(OfflineVertexFitter) # _Bd.VertexFitters.update( { "" : "OfflineVertexFitter"} ) _Bd.ParticleCombiners.update({"": "OfflineVertexFitter" }) # Fix for DaVinci v32r0 by A.Poluektov _Bd.OfflineVertexFitter.useResonanceVertex = False return Selection(name, Algorithm=_Bd, RequiredSelections=[JPsisel, Kstsel])
def makeDetachedJPsi(name): """ detached JPsi selection for B--> JPsi X calibration and normalization channels. Selection is aligned to the Bs2MuMu selection. Please contact Johannes Albrecht if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter DetachedJPsi = CombineParticles("Combine" + name) DetachedJPsi.DecayDescriptor = "J/psi(1S) -> mu+ mu-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: DetachedJPsi.addTool(OfflineVertexFitter()) DetachedJPsi.VertexFitters.update({"": "OfflineVertexFitter"}) DetachedJPsi.OfflineVertexFitter.useResonanceVertex = False DetachedJPsi.ReFitPVs = True DetachedJPsi.DaughtersCuts = { "mu+" : "(TRCHI2DOF < 4 ) "\ "& (MIPCHI2DV(PRIMARY)> 25.)"} DetachedJPsi.CombinationCut = "(ADAMASS('J/psi(1S)')<100*MeV) "\ "& (AMAXDOCA('')<0.3*mm)" DetachedJPsi.MotherCut = "(VFASPF(VCHI2)<9) "\ "& (ADMASS('J/psi(1S)') < 100*MeV )"\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2>169)" _stdLooseMuons = DataOnDemand(Location="Phys/StdLooseMuons/Particles") return Selection(name, Algorithm=DetachedJPsi, RequiredSelections=[_stdLooseMuons])
def makeBs2KstKst(name, Kstsel, BMassWin, BVCHI2, BDOCA, BIPCHI2): """ Create and return a Bs -> Kstar (Kpi) anti-Kstar (Kpi) Selection object. Arguments: name : name of the Selection. Kstsel : Kst -> K+pi- Selection object. BMassWin : Bs invariant mass window around PDG mass value (MeV). BVCHI2 : Maximum Bs vertex chi2 per degree of freedom. BDOCA : Maximum Bs DOCA. """ _motherCuts = " (VFASPF(VCHI2/VDOF) < %(BVCHI2)s) & (MIPCHI2DV(PRIMARY)< %(BIPCHI2)s)" % locals( ) _combinationCut = "(ADAMASS('B_s0') < %(BMassWin)s *MeV) & (AMAXDOCA('')< %(BDOCA)s *mm)" % locals( ) _Bs = CombineParticles('_' + name) _Bs.DecayDescriptor = "B_s0 -> K*(892)0 K*(892)~0" _Bs.CombinationCut = _combinationCut _Bs.MotherCut = _motherCuts _Bs.ReFitPVs = True _Bs.addTool(OfflineVertexFitter) # _Bs.VertexFitters.update( { "" : "OfflineVertexFitter"} ) _Bs.ParticleCombiners.update({"": "OfflineVertexFitter" }) # Fix for DaVinci v32r0 by A.Poluektov _Bs.OfflineVertexFitter.useResonanceVertex = False return Selection(name, Algorithm=_Bs, RequiredSelections=[Kstsel])
def makeBu(name): """ detached Bu-->JPsiK selection. Selection is aligned to the Bs2MuMu selection. Please contact Johannes Albrecht if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter SelDJPsi = makeDetachedJPsi(name) PreselBu2JPsiKCommon = CombineParticles("PreselBu2JPsiKCommon") PreselBu2JPsiKCommon.DecayDescriptor = " [B+ -> J/psi(1S) K+]cc " PreselBu2JPsiKCommon.addTool(OfflineVertexFitter()) PreselBu2JPsiKCommon.VertexFitters.update({"": "OfflineVertexFitter"}) PreselBu2JPsiKCommon.OfflineVertexFitter.useResonanceVertex = False PreselBu2JPsiKCommon.ReFitPVs = True PreselBu2JPsiKCommon.DaughtersCuts = { "K+": "(ISLONG) & (TRCHI2DOF < 5 ) &(MIPCHI2DV(PRIMARY)>25)& (PT>250*MeV) " } PreselBu2JPsiKCommon.CombinationCut = "(ADAMASS('B+') < 500*MeV)" PreselBu2JPsiKCommon.MotherCut = "(BPVIPCHI2()< 25)& (VFASPF(VCHI2)<45) " _kaons = DataOnDemand(Location='Phys/StdNoPIDsKaons/Particles') return Selection("SelBu2JPsiK", Algorithm=PreselBu2JPsiKCommon, RequiredSelections=[SelDJPsi, _kaons])
def makeDownstream(name): """ very very detached dimuon selection with downstream tracks """ from Configurables import OfflineVertexFitter Detached2mu = CombineParticles("Combine" + name) Detached2mu.DecayDescriptor = "KS0 -> mu+ mu-" Detached2mu.addTool(OfflineVertexFitter) #Detached2mu.VertexFitters.update( { "" : "OfflineVertexFitter"} ) Detached2mu.ParticleCombiners.update({"": "OfflineVertexFitter"}) Detached2mu.OfflineVertexFitter.useResonanceVertex = False Detached2mu.ReFitPVs = True Detached2mu.DaughtersCuts = { "mu+" : "(TRCHI2DOF < 4 ) "\ " & (MIPCHI2DV(PRIMARY)> 150)"\ "& (PT > 125*MeV) "\ "& (PIDmu > -4)"} Detached2mu.CombinationCut = " (AMAXDOCA('')<0.2*mm)" #"(ADAMASS('B_s0')<1000*MeV) "\ Detached2mu.MotherCut = "(VFASPF(VCHI2/VDOF)<12) "\ "& (M>250)"\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2>1000)"\ "& (BPVVD>200)" _stdLooseDownMuons = DataOnDemand( Location="Phys/StdLooseDownMuons/Particles") return Selection(name, Algorithm=Detached2mu, RequiredSelections=[_stdLooseDownMuons])
def makeDefault(name, inputSel): """ B --> 4 mu selection should become inclusive bb-->4 mu selection ?? """ from Configurables import OfflineVertexFitter Detached4mu = CombineParticles("Combine" + name) Detached4mu.DecayDescriptor = "B_s0 -> mu+ mu- mu+ mu-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: Detached4mu.addTool(OfflineVertexFitter) Detached4mu.VertexFitters.update({"": "OfflineVertexFitter"}) Detached4mu.OfflineVertexFitter.useResonanceVertex = False Detached4mu.ReFitPVs = True Detached4mu.DaughtersCuts = { "mu+" : "(TRCHI2DOF < 2.5 ) "\ " & (MIPCHI2DV(PRIMARY)> 9.)"} Detached4mu.CombinationCut = "(ADAMASS('B_s0')<1000*MeV) "\ "& (AMAXDOCA('')<0.3*mm)" Detached4mu.MotherCut = "(VFASPF(VCHI2/VDOF)<9) "\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2>100)"\ " & (M>4366.3) & (M<6366.3)"\ "& (BPVIPCHI2()< 25) " return Selection(name, Algorithm=Detached4mu, RequiredSelections=inputSel)
def build_mc_unbiased_selection(decayDesc, arrow = '==>', refitpvs = True) : '''Make a selection for the given decay descriptor that has no cuts besides truth matching.''' preamble = [ "from LoKiPhysMC.decorators import *" , "from LoKiPhysMC.functions import mcMatch" ] decayDesc = decayDesc.copy() decayDesc.clear_aliases() decayDesc.set_carets(False) decayDescCC = decayDesc.copy() decayDescCC.cc = True algname = decayDesc.get_full_alias() + '_MCSel' algnameconj = decayDesc.conjugate().get_full_alias() + '_MCSel' if algname in selections : return selections[algname] elif algnameconj in selections : return selections[algnameconj] if not decayDesc.daughters : alg = FilterDesktop(algname + '_Filter') basicname = decayDesc.particle.name if not basicname in mcbasicinputs : basicname = decayDesc.conjugate().particle.name if basicname in mcbasicinputs : inputsels = [RebuildSelection(getattr(StandardParticles, basicinput)) for basicinput in mcbasicinputs[basicname]] else : raise ValueError("Can't find MC basic input for particle " + repr(decayDesc.particle.name)) alg.Code = 'mcMatch({0!r})'.format(decayDescCC.to_string(arrow)) alg.Preambulo = preamble sel = Selection(algname, Algorithm = alg, RequiredSelections = inputsels) selections[algname] = sel return sel inputs = set() daughtercuts = {} for daughter in decayDescCC.daughters : originaldaughtercc = daughter.cc daughter.cc = True sel = build_mc_unbiased_selection(daughter, arrow, refitpvs) daughter.cc = originaldaughtercc inputs.add(sel) #daughter.caret = True #daughtercuts[daughter.particle.name] = 'mcMatch({0!r})'.format(decayDescCC.to_string(arrow)) #daughter.caret = False #comb = nCombiners[len(decayDesc.daughters)](algname + '_Comb') comb = CombineParticles(algname + '_Comb') # CombineParticles uses small cc, so set ishead = False comb.DecayDescriptors = [decayDesc.to_string(depth = 1).replace('CC', 'cc')] comb.MotherCut = 'mcMatch({0!r})'.format(decayDescCC.to_string(arrow)) comb.Preambulo = preamble comb.DaughtersCuts = daughtercuts comb.ReFitPVs = refitpvs if refitpvs: comb.MotherCut += ' & BPVVALID()' sel = Selection(algname, Algorithm = comb, RequiredSelections = list(inputs)) selections[algname] = sel return sel
def makeBd(name) : """ detached Bd-->JPsiK* selection. Selection is aligned to the Bs2MuMu selection. Please contact Johannes Albrecht if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter SelDJPsi = makeDetachedJPsi(name) ## make Kstar makeKstar = CombineParticles("makeKstar") makeKstar.DecayDescriptor = "[K*(892)0 -> K+ pi-]cc" makeKstar.DaughtersCuts = {"K+": "(ISLONG) & (TRCHI2DOF < 3 ) "\ " & ( TRGHOSTPROB < 0.3 )"\ " & (MIPCHI2DV(PRIMARY)> 4.)& (PT>250*MeV)", "pi-":"(ISLONG) & (TRCHI2DOF < 3 ) "\ " & ( TRGHOSTPROB < 0.3 )"\ "& (MIPCHI2DV(PRIMARY)> 4.)& (PT>250*MeV)"} makeKstar.CombinationCut = "(ADAMASS('K*(892)0')<2000*MeV)"#huge, to allow to study JPsi K1 etc makeKstar.MotherCut = " (MIPCHI2DV(PRIMARY)> 25.)" _pions = DataOnDemand(Location='Phys/StdNoPIDsPions/Particles') _kaons = DataOnDemand(Location='Phys/StdNoPIDsKaons/Particles') SelKst = Selection( "SelKst", Algorithm= makeKstar, RequiredSelections=[_pions,_kaons] ) ## make BtoJPsiKstar PreselBd2JPsiKstCommon = CombineParticles("PreselBd2JPsiKstCommon") PreselBd2JPsiKstCommon.DecayDescriptor = "[B0 -> J/psi(1S) K*(892)0]cc" PreselBd2JPsiKstCommon.addTool( OfflineVertexFitter ) PreselBd2JPsiKstCommon.ParticleCombiners.update( { "" : "OfflineVertexFitter"} ) PreselBd2JPsiKstCommon.OfflineVertexFitter.useResonanceVertex = False PreselBd2JPsiKstCommon.ReFitPVs = True PreselBd2JPsiKstCommon.DaughtersCuts = {} PreselBd2JPsiKstCommon.CombinationCut = "(ADAMASS('B0') < 500*MeV)" PreselBd2JPsiKstCommon.MotherCut = "(BPVIPCHI2()< 25) & (VFASPF(VCHI2)<75)" return Selection( "SelBd2JPsiKstar", Algorithm = PreselBd2JPsiKstCommon, RequiredSelections=[SelDJPsi,SelKst] )
def makeB2KShh(self, name, ks_type, year, sign, config): """ Create and return either a B -> KS h+ h- Selection object, or a B -> KS h+(-) h+(-) Same Sign Selection Object Arguments: name : name of the Selection. ks_type : type of the KS, e.g. DD year : the year for which we are making the selection sign : whether we use opposite-sign or same-sign h's config : config dictionary """ _trkChi2Cut = "(TRCHI2DOF<%s)" % config['Trk_Chi2'] _trkGhostProbCut = "(TRGHOSTPROB<%s)" % config['Trk_GhostProb'] _daughtersCuts = _trkChi2Cut + '&' + _trkGhostProbCut _massCutLow = "(AM>(5279-%s)*MeV)" % config['B_Mlow'] _massCutHigh = "(AM<(5279+%s)*MeV)" % config['B_Mhigh'] _aptCut = "(APT>%s*MeV)" % config['B_APTmin'] _daugMedPtCut = "(ANUM(PT>%s*MeV)>=2)" % config['BDaug_MedPT_PT'] _daugMaxPtIPCut = "(AVAL_MAX(MIPDV(PRIMARY),PT)>%s)" % config[ 'BDaug_MaxPT_IP'] _maxDocaChi2Cut = "(ACUTDOCACHI2(%s,''))" % config[ 'BDaug_%s_maxDocaChi2' % ks_type] _daugPtSumCut = "((APT1+APT2+APT3)>%s*MeV)" % config['BDaug_%s_PTsum' % ks_type] _combCuts = _daugPtSumCut + '&' + _massCutLow + '&' + _massCutHigh + '&' + _maxDocaChi2Cut + '&' + _aptCut + '&' + _daugMedPtCut + '&' + _daugMaxPtIPCut _diraCut = "(BPVDIRA>%s)" % config['B_%s_Dira' % ks_type] _KSdiffZ = "((CHILD(VFASPF(VZ),3) - VFASPF(VZ)) > %s*mm)" % config[ 'KS_FD_Z'] _motherCuts = _diraCut + '&' + _KSdiffZ _combName = name + '_' + ks_type + '_' + year + '_' + sign + '_Comb3Body' _B = CombineParticles(_combName) _B.DaughtersCuts = {"pi+": _daughtersCuts} _B.CombinationCut = _combCuts _B.MotherCut = _motherCuts _B.ReFitPVs = True if sign == 'OS': _B.DecayDescriptors = ["B0 -> pi+ pi- KS0"] else: _B.DecayDescriptors = ["B0 -> pi+ pi+ KS0", "B0 -> pi- pi- KS0"] _selname = name + '_' + ks_type + '_' + year + '_' + sign + '_Presel' return Selection(_selname, Algorithm=_B, RequiredSelections=[self.selKS[ks_type], self.pions])
def makeBs(name): """ detached Bs-->JPsiPhi selection. Selection is aligned to the Bs2MuMu selection. Please contact Johannes Albrecht if you think of prescaling this line! Arguments: name : name of the Selection. """ from Configurables import OfflineVertexFitter SelDJPsi = makeDetachedJPsi(name) makePhi = CombineParticles("makePhi") makePhi.DecayDescriptor = "phi(1020) -> K+ K-" makePhi.DaughtersCuts = { "K+": "(ISLONG) & (TRCHI2DOF < 5 ) & (MIPCHI2DV(PRIMARY)> 4.) & (PT>250*MeV)" } _kaons = DataOnDemand(Location='Phys/StdNoPIDsKaons/Particles') makePhi.CombinationCut = "(ADAMASS('phi(1020)')<10*MeV)" makePhi.MotherCut = " (MIPCHI2DV(PRIMARY)> 25.)" SelPhi = Selection("SelPhi", Algorithm=makePhi, RequiredSelections=[_kaons]) PreselBs2JPsiPhiCommon = CombineParticles("PreselBs2JPsiPhiCommon") PreselBs2JPsiPhiCommon.DecayDescriptor = "B_s0 -> J/psi(1S) phi(1020)" PreselBs2JPsiPhiCommon.addTool(OfflineVertexFitter()) PreselBs2JPsiPhiCommon.VertexFitters.update({"": "OfflineVertexFitter"}) PreselBs2JPsiPhiCommon.OfflineVertexFitter.useResonanceVertex = False PreselBs2JPsiPhiCommon.ReFitPVs = True PreselBs2JPsiPhiCommon.DaughtersCuts = {} PreselBs2JPsiPhiCommon.CombinationCut = "(ADAMASS('B_s0') < 500*MeV)" PreselBs2JPsiPhiCommon.MotherCut = "(BPVIPCHI2()< 25)& (VFASPF(VCHI2)<75)" return Selection("SelBs2JPsiPhi", Algorithm=PreselBs2JPsiPhiCommon, RequiredSelections=[SelDJPsi, SelPhi])
def makeDefault(self, name, inputSel): """ B --> 4 mu selection should become inclusive bb-->4 mu selection ?? """ from Configurables import OfflineVertexFitter Detached4mu = CombineParticles("Combine" + name) Detached4mu.DecayDescriptor = "B_s0 -> mu+ mu- mu+ mu-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: Detached4mu.addTool(OfflineVertexFitter) Detached4mu.ParticleCombiners.update({"": "OfflineVertexFitter"}) Detached4mu.OfflineVertexFitter.useResonanceVertex = False Detached4mu.ReFitPVs = True Detached4mu.DaughtersCuts = {"mu+": self.BDaughtersCuts} Detached4mu.CombinationCut = "(ADAMASS('B_s0')<1000*MeV) "\ "& (AMAXDOCA('')<0.3*mm)" Detached4mu.MotherCut = self.BMotherCuts + " & (ADMASS('B_s0')<1000*MeV) " return Selection(name, Algorithm=Detached4mu, RequiredSelections=inputSel)
def makeLoose(name, MuIPChi2, MuTrChi2, BIPChi2, BFDChi2): """ loose Bs2mumu selection object to monitor selection, systematics from cuts, etc. starts from Phys/StdNoPIDsMuons prescaled Arguments: name : name of the Selection. MuIPChi2 : muon MIPCHI2DV(PRIMARY) MuTrChi2 : muon TRCHI2 BIPChi2 : Bs MIPCHI2DV(PRIMARY) BFDChi2 : Bs BPVVDCHI2> %(BFDChi2) """ from Configurables import OfflineVertexFitter Bs2MuMuNoMuIDLoose = CombineParticles("Combine" + name) Bs2MuMuNoMuIDLoose.DecayDescriptor = "B_s0 -> mu+ mu-" # Set the OfflineVertexFitter to keep the 4 tracks and not the J/Psi Kstar: Bs2MuMuNoMuIDLoose.addTool(OfflineVertexFitter()) Bs2MuMuNoMuIDLoose.VertexFitters.update({"": "OfflineVertexFitter"}) Bs2MuMuNoMuIDLoose.OfflineVertexFitter.useResonanceVertex = False Bs2MuMuNoMuIDLoose.ReFitPVs = True Bs2MuMuNoMuIDLoose.DaughtersCuts = { "mu+" : "(TRCHI2DOF < %(MuTrChi2)s ) "\ "& (MIPCHI2DV(PRIMARY)> %(MuIPChi2)s ) "% locals() } Bs2MuMuNoMuIDLoose.CombinationCut = "(ADAMASS('B_s0')<600*MeV)"\ "& (AMAXDOCA('')<0.5*mm)" Bs2MuMuNoMuIDLoose.MotherCut = "(VFASPF(VCHI2/VDOF)<25) "\ "& (ADMASS('B_s0') < 600*MeV )"\ "& (BPVDIRA > 0) "\ "& (BPVVDCHI2> %(BFDChi2)s)"\ "& (BPVIPCHI2()< %(BIPChi2)s) "% locals() _stdNoPIDsMuons = DataOnDemand(Location="Phys/StdNoPIDsMuons/Particles") return Selection(name, Algorithm=Bs2MuMuNoMuIDLoose, RequiredSelections=[_stdNoPIDsMuons])
def selection_tau_h3(Config, preambulo, inputs): config = Config['tau_h3'] ## Pickout tau_h3 config from big one. # dcut = parse_cuts_auto(config['dcuts']) algo = CombineParticles('CombTauNoiso_h3') algo.DecayDescriptor = '[ tau- -> pi- pi- pi+ ]cc' algo.Preambulo = preambulo0 + preambulo.split('\n') algo.DaughtersCuts = {'pi-': dcut, 'pi+': dcut} algo.CombinationCut = parse_cuts_auto(config['ccuts']) algo.MotherCut = parse_cuts_auto(config['mcuts']) # config_refit = Config['PVRefitter'] if config_refit: tool = LoKi__PVReFitter('PVRefitter_tauh3', **config_refit) algo.ReFitPVs = True algo.IgnoreP2PVFromInputLocations = True algo.addTool(tool) algo.PVReFitters.update({'': 'LoKi::PVReFitter/PVRefitter_tauh3'}) # return Selection('SelTauNoiso_h3', Algorithm=algo, RequiredSelections=inputs)
def DstarMaker(_name, _KstDecays, _D0Decays, _DstDecays, _ChargedTracks, _Pi0s, _Slowpions, _Filter, config, prescale): KstSel = Selection( "SelKst" + _name, Algorithm=CombineParticles( name="CombKst" + _name, DecayDescriptors=_KstDecays, CombinationCut= "(((ACHILD(PT,1) > 1.7*GeV) & (ACHILD(BPVIPCHI2(),1) > 36)) | ((ACHILD(PT,2) > 1.7*GeV) & (ACHILD(BPVIPCHI2(),2) > 36))) & (AM < 1850*MeV) & (ADOCACHI2CUT(15,''))", MotherCut="(VFASPF(VCHI2/VDOF) < 3) & (BPVVDCHI2 > 100)"), RequiredSelections=_ChargedTracks) D0Comb = CombineParticles( name="CombD0" + _name, DecayDescriptors=_D0Decays, CombinationCut= "(ADAMASS('D0') < %(D0_M_WINDOW)s + 10 *MeV) & (APT > %(D0_APT)s *MeV)" % config, MotherCut= "(VFASPF(VCHI2/VDOF) < 20.0) & (DMASS('D0') < %(D0_M_WINDOW)s *MeV)" % config) D0Sel = Selection("SelD0" + _name, Algorithm=D0Comb, RequiredSelections=[KstSel, _Pi0s]) DstComb = CombineParticles( name="CombDst" + _name, DecayDescriptors=_DstDecays, CombinationCut= "(AM - ACHILD(M,1) < %(DELTA_MASS_MAX)s+5 *MeV) & (ADOCACHI2CUT(20,''))" % config, MotherCut= "(M - CHILD(M,1) < %(DELTA_MASS_MAX)s *MeV) & (VFASPF(VCHI2/VDOF) < 9.0)" % config) if config["Pi0_MassConstraint"] == True: DstComb.addTool(OfflineVertexFitter) DstComb.ParticleCombiners.update({"": "OfflineVertexFitter"}) DstComb.OfflineVertexFitter.useResonanceVertex = False DstComb.OfflineVertexFitter.applyDauMassConstraint = True DstComb.ReFitPVs = True DstSel = Selection("SelDst" + _name, Algorithm=DstComb, RequiredSelections=[D0Sel, _Slowpions]) DstSelTOS = TOSFilter("SelDstKPiPi0_Hlt2TOS" + _name, DstSel, {'Hlt2CharmHadD02HHXDst_hhXDecision%TOS': 0}) hlt = "" if config["useHLT"] == True: hlt = "HLT_PASS_RE('Hlt2.*CharmHadD02HHXDst_hhX.*Decision')" if config["useTOS"] == True: Line = StrippingLine(_name + 'Line', prescale=prescale, FILTER=_Filter, HLT=hlt, selection=DstSelTOS) else: Line = StrippingLine(_name + 'Line', prescale=prescale, FILTER=_Filter, HLT=hlt, selection=DstSel) return Line