diff --git a/Phys/StrippingSelections/python/StrippingSelections/StrippingBandQ/StrippingXbToLambdaKmX.py b/Phys/StrippingSelections/python/StrippingSelections/StrippingBandQ/StrippingXbToLambdaKmX.py new file mode 100644 index 0000000000000000000000000000000000000000..d9c8341c06c276541914d4b220e3e57277777b1b --- /dev/null +++ b/Phys/StrippingSelections/python/StrippingSelections/StrippingBandQ/StrippingXbToLambdaKmX.py @@ -0,0 +1,228 @@ +############################################################################### +# (c) Copyright 2000-2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +""" +Lines for b-baryon -> Lambda0 K- X, where X = D0,D+,Ds+ +""" +__author__ = ["Marian Stahl"] + +__all__ = ("XbToLambdaKmXConf", "default_config", "get_mva_vars") + +moduleName = "XbToLambdaKmX" + +# Import Packages +from StrippingConf.StrippingLine import StrippingLine +from StrippingUtils.Utils import LineBuilder +from PhysSelPython.Wrappers import AutomaticData +from PhysConf.Selections import (FilterSelection, CombineSelection, Combine3BodySelection, MergedSelection) +from MVADictHelpers import addTMVAclassifierValue +from collections import OrderedDict + +# Default configuration dictionary +default_config = { + "NAME": "XbToLambdaKmX", + "BUILDERTYPE": "XbToLambdaKmXConf", + "CONFIG": { + "bach_pion" : { + "tes" : "Phys/StdAllNoPIDsPions/Particles", + "filter" : "(P>2*GeV) & (PT>150*MeV) & (MIPCHI2DV(PRIMARY)>4) & (PROBNNpi>0.03)" + }, + "bach_kaon" : { + "tes" : "Phys/StdAllNoPIDsKaons/Particles", + "filter" : "(P>4*GeV) & (PT>250*MeV) & (MIPCHI2DV(PRIMARY)>4) & (PROBNNk>0.03)" + }, + "lambda_ll" : { + "tes" : "Phys/StdVeryLooseLambdaLL/Particles", + "filter" : """(ADMASS('Lambda0')<20*MeV) & (P>12*GeV) & (PT>0.8*GeV) & (BPVVDZ>10*mm) & (BPVVDCHI2>32) & + (DOCA(1,2)<0.5*mm) & (DOCACHI2(1,2)<16) & (MAXTREE('p+'==ABSID,P)>7.5*GeV) & + (MAXTREE('p+'==ABSID,MIPCHI2DV(PRIMARY))>9) & (MAXTREE('pi+'==ABSID,MIPCHI2DV(PRIMARY))>9)""" + }, + "lambda_dd" : { + "tes" : "Phys/StdLooseLambdaDD/Particles", + "filter" : "(ADMASS('Lambda0')<20*MeV) & (P>12*GeV) & (PT>1*GeV) & (CHILDIP(1)<2*mm) & (MAXTREE('p+'==ABSID,P)>9*GeV)" + }, + "dz" : { + "descriptors" : ["[D0 -> K- pi+]cc"], + "comb_cut" : "(ASUM(PT)>1.4*GeV) & (ADAMASS('D0')<120*MeV) & (ADOCA(1,2)<0.3*mm)", + "mother_cut" : """(ADMASS('D0')<80*MeV) & (P>12*GeV) & (PT>1.2*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.4*mm) & + (CHILDIP(1)<0.3*mm) & (CHILDIP(2)<0.3*mm) & (VALUE('LoKi::Hybrid::DictValue/D0_BDT')>-0.8)""", + }, + "dp" : { + "descriptors" : ["[D+ -> K- pi+ pi+]cc"], + "comb12_cut" : "(ADOCA(1,2)<0.2*mm) & (AMASS(1,2)<1840*MeV)", + "comb_cut" : "(ASUM(PT)>1.4*GeV) & (ADAMASS('D+')<120*MeV) & (ADOCA(1,3)<0.3*mm) & (ADOCA(2,3)<0.3*mm)", + "mother_cut" : """(ADMASS('D+')<80*MeV) & (P>12*GeV) & (PT>1.2*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.4*mm) & (CHILDIP(1)<0.2*mm) & + (CHILDIP(2)<0.2*mm) & (CHILDIP(3)<0.3*mm) & (VALUE('LoKi::Hybrid::DictValue/D_BDT')>-0.9)""" + }, + "ds" : { + "descriptors" : ["[D_s+ -> K+ K- pi+]cc"], + "comb12_cut" : "(ADOCA(1,2)<0.2*mm) & (AMASS(1,2)<1940*MeV)", + "comb_cut" : "(ASUM(PT)>1.4*GeV) & (ADAMASS('D_s+')<120*MeV) & (ADOCA(1,3)<0.3*mm) & (ADOCA(2,3)<0.3*mm)", + "mother_cut" : """(ADMASS('D_s+')<80*MeV) & (P>12*GeV) & (PT>1.3*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.4*mm) & + (CHILDIP(1)<0.2*mm) & (CHILDIP(2)<0.2*mm) & (CHILDIP(3)<0.3*mm) & (VALUE('LoKi::Hybrid::DictValue/Ds_BDT')>-0.9)""", + }, + "dfb_kids" : { # daughter-names are the ones in the xml file + "D0" : OrderedDict({"K":1, "pi":2}), + "D" : OrderedDict({"K":1, "pi1":2, "pi2":3}), + "Ds" : OrderedDict({"Kp":1, "Km":2, "pi":3}), + }, + "dfb_weights_path" : "$TMVAWEIGHTSROOT/data/DfromB/{}Pi_2017_GBDT.weights.xml", + "b_decays" : { + "Xib2LKD0" : { + "LL" : { + "daughters" : ["dz","bach_kaon","lambda_ll"], + "descriptors" : ["[Xi_b- -> D0 K- Lambda0]cc"], + "comb12_cut" : "(ADOCA(1,2)<0.3*mm) & (AMASS(1,2)<5*GeV)", + "comb_cut" : "(ADOCA(1,3)<0.6*mm) & (ADOCA(2,3)<0.3*mm) & (ASUM(PT)>5.2*GeV) & (AMASS()>5.3*GeV) & (AMASS()<6.4*GeV)", + "mother_cut" : """(in_range(5.4*GeV,M,6.3*GeV)) & (P>36*GeV) & (PT>5*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.2*mm) & (BPVIPCHI2()<16) & (CHILDIP(1)<0.3*mm) & + (CHILDIP(2)<0.2*mm) & (CHILDIP(3)<0.4*mm) & ((CHILD(VFASPF(VZ),1) - VFASPF(VZ))>0.0*mm) & ((CHILD(VFASPF(VZ),3) - VFASPF(VZ))>10*mm)""" + }, + "DD" : { + "daughters" : ["dz","bach_kaon","lambda_dd"], + "descriptors" : ["[Xi_b- -> D0 K- Lambda0]cc"], + "comb12_cut" : "(ADOCA(1,2)<0.3*mm) & (AMASS(1,2)<5*GeV)", + "comb_cut" : "(ADOCA(1,3)<2*mm) & (ADOCA(2,3)<2*mm) & (ASUM(PT)>5.2*GeV) & (AMASS()>5.3*GeV) & (AMASS()<6.4*GeV)", + "mother_cut" : """(in_range(5.4*GeV,M,6.3*GeV)) & (P>36*GeV) & (PT>5*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.1*mm) & (BPVIPCHI2()<16) & + (CHILDIP(1)<0.3*mm) & (CHILDIP(2)<0.2*mm) & ((CHILD(VFASPF(VZ),1) - VFASPF(VZ))>0.0*mm)""" + }, + }, + "Xib02LKD" : { + "LL" : { + "daughters" : ["dp","bach_kaon","lambda_ll"], + "descriptors" : ["[Xi_b0 -> D+ K- Lambda0]cc"], + "comb12_cut" : "(ADOCA(1,2)<0.3*mm) & (AMASS(1,2)<5*GeV)", + "comb_cut" : "(ADOCA(1,3)<0.6*mm) & (ADOCA(2,3)<0.3*mm) & (ASUM(PT)>5.2*GeV) & (AMASS()>5.3*GeV) & (AMASS()<6.2*GeV)", + "mother_cut" : """(in_range(5.4*GeV,M,6.1*GeV)) & (P>36*GeV) & (PT>5*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.2*mm) & (BPVIPCHI2()<16) & (CHILDIP(1)<0.3*mm) & + (CHILDIP(2)<0.2*mm) & (CHILDIP(3)<0.4*mm) & ((CHILD(VFASPF(VZ),1) - VFASPF(VZ))>0.0*mm) & ((CHILD(VFASPF(VZ),3) - VFASPF(VZ))>10*mm)""" + }, + "DD" : { + "daughters" : ["dp","bach_kaon","lambda_dd"], + "descriptors" : ["[Xi_b0 -> D+ K- Lambda0]cc"], + "comb12_cut" : "(ADOCA(1,2)<0.3*mm) & (AMASS(1,2)<5*GeV)", + "comb_cut" : "(ADOCA(1,3)<2*mm) & (ADOCA(2,3)<2*mm) & (ASUM(PT)>5.2*GeV) & (AMASS()>5.3*GeV) & (AMASS()<6.2*GeV)", + "mother_cut" : """(in_range(5.4*GeV,M,6.1*GeV)) & (P>36*GeV) & (PT>5*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.1*mm) & (BPVIPCHI2()<16) & + (CHILDIP(1)<0.3*mm) & (CHILDIP(2)<0.2*mm) & ((CHILD(VFASPF(VZ),1) - VFASPF(VZ))>0.0*mm)""" + }, + }, + "Lb2LKDs" : { + "LL" : { + "daughters" : ["ds","bach_kaon","lambda_ll"], + "descriptors" : ["[Lambda_b0 -> D_s+ K- Lambda0]cc"], + "comb12_cut" : "(ADOCA(1,2)<0.3*mm) & (AMASS(1,2)<5*GeV)", + "comb_cut" : "(ADOCA(1,3)<0.6*mm) & (ADOCA(2,3)<0.3*mm) & (ASUM(PT)>4.8*GeV) & (AMASS()>5*GeV) & (AMASS()<6.1*GeV)", + "mother_cut" : """(in_range(5.1*GeV,M,6*GeV)) & (P>36*GeV) & (PT>4.5*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.2*mm) & (BPVIPCHI2()<16) & (CHILDIP(1)<0.3*mm) & + (CHILDIP(2)<0.2*mm) & (CHILDIP(3)<0.4*mm) & ((CHILD(VFASPF(VZ),1) - VFASPF(VZ))>0.0*mm) & ((CHILD(VFASPF(VZ),3) - VFASPF(VZ))>10*mm)""" + }, + "DD" : { + "daughters" : ["ds","bach_kaon","lambda_dd"], + "descriptors" : ["[Lambda_b0 -> D_s+ K- Lambda0]cc"], + "comb12_cut" : "(ADOCA(1,2)<0.3*mm) & (AMASS(1,2)<5*GeV)", + "comb_cut" : "(ADOCA(1,3)<2*mm) & (ADOCA(2,3)<2*mm) & (ASUM(PT)>4.8*GeV) & (AMASS()>5*GeV) & (AMASS()<6.1*GeV)", + "mother_cut" : """(in_range(5.1*GeV,M,6*GeV)) & (P>36*GeV) & (PT>4.5*GeV) & (CHI2VXNDF<12) & (BPVVDZ>0.1*mm) & (BPVIPCHI2()<16) & + (CHILDIP(1)<0.3*mm) & (CHILDIP(2)<0.2*mm) & ((CHILD(VFASPF(VZ),1) - VFASPF(VZ))>0.0*mm)""" + }, + }, + }, + }, + "STREAMS" : { + "Bhadron" : ["StrippingXbToLambdaKmX_Xib2LKD0Line", + "StrippingXbToLambdaKmX_Xib02LKDLine", + "StrippingXbToLambdaKmX_Lb2LKDsLine"] + }, + "WGs": ["BandQ"] +} + +class XbToLambdaKmXConf(LineBuilder): + + __configuration_keys__ = default_config["CONFIG"].keys() + + def __init__(self, moduleName, config): + LineBuilder.__init__(self, moduleName, config) + + daughters = {} + daughters["bach_pion"] = FilterSelection(moduleName+"_bach_pion", [AutomaticData(config["bach_pion"]["tes"])], Code=config["bach_pion"]["filter"]) + daughters["bach_kaon"] = FilterSelection(moduleName+"_bach_kaon", [AutomaticData(config["bach_kaon"]["tes"])], Code=config["bach_kaon"]["filter"]) + daughters["lambda_ll"] = FilterSelection(moduleName+"_lambda_ll", [AutomaticData(config["lambda_ll"]["tes"])], Code=config["lambda_ll"]["filter"]) + daughters["lambda_dd"] = FilterSelection(moduleName+"_lambda_dd", [AutomaticData(config["lambda_dd"]["tes"])], Code=config["lambda_dd"]["filter"]) + + daughters["dz"] = CombineSelection(moduleName+'_D02KPi', [daughters["bach_pion"], daughters["bach_kaon"]], DecayDescriptors=config["dz"]["descriptors"], + CombinationCut=config["dz"]["comb_cut"], MotherCut=config["dz"]["mother_cut"]) + daughters["dp"] = Combine3BodySelection(moduleName+'_D2KPiPi', [daughters["bach_pion"], daughters["bach_kaon"]], DecayDescriptors=config["dp"]["descriptors"], + Combination12Cut=config["dp"]["comb12_cut"], CombinationCut=config["dp"]["comb_cut"], MotherCut=config["dp"]["mother_cut"]) + daughters["ds"] = Combine3BodySelection(moduleName+'_Ds2KKPi', [daughters["bach_pion"], daughters["bach_kaon"]], DecayDescriptors=config["ds"]["descriptors"], + Combination12Cut=config["ds"]["comb12_cut"], CombinationCut=config["ds"]["comb_cut"], MotherCut=config["ds"]["mother_cut"]) + + add_bdt_val = lambda s, p : addTMVAclassifierValue(s.algorithm(), config["dfb_weights_path"].format(p), self.get_mva_vars(p, config["dfb_kids"][p]), p+"_BDT") + add_bdt_val(daughters["dz"],"D0") + add_bdt_val(daughters["dp"],"D") + add_bdt_val(daughters["ds"],"Ds") + + for line_name, v in config["b_decays"].iteritems() : + individual_selections = [] + for k, conf in v.iteritems(): + individual_selections.append(Combine3BodySelection(moduleName+"_"+line_name+k, [daughters[dau] for dau in conf["daughters"]], DecayDescriptors=conf["descriptors"], + Combination12Cut=conf["comb12_cut"], CombinationCut=conf["comb_cut"], MotherCut=conf["mother_cut"])) + merged_selection = MergedSelection(moduleName+"_"+line_name+"_combsel", RequiredSelections=individual_selections) + # Create the stripping lines + self.registerLine(StrippingLine(moduleName+"_"+line_name+"Line", algos=[merged_selection])) + + def get_mva_vars(self, parentname, daugthers): + """ + Return all variables required for the BDT + Variable names MUST correspond exactly to what is needed by classifier (xml) + """ + + bdt_vars = {} + # Variables for D and daughters; prefixes added later + vars_parent = { + 'log_P' : 'log10(P)', + 'log_PT' : 'log10(PT)', + 'log_ENDVERTEX_CHI2' : 'log10(VFASPF(VCHI2))', + 'log_IPCHI2_OWNPV' : 'log10(MIPCHI2DV(PRIMARY))', + 'log_FDCHI2_OWNPV' : 'log10(BPVVDCHI2)', + 'beta' : '(SUMTREE(P,ISBASIC,0.)-(2.*CHILD(P,1)))/SUMTREE(P,ISBASIC,0.)', + } + vars_daughters = { + 'log_PT' : 'log10(CHILD(PT,{0}))', + 'log_IPCHI2_OWNPV' : 'log10(CHILD(MIPCHI2DV(PRIMARY),{0}))', + 'log_TRACK_VeloCHI2NDOF' : 'log10(switch(CHILD(TINFO(LHCb.Track.FitVeloNDoF,-1),{0})>0,CHILD(TINFO(LHCb.Track.FitVeloChi2,-1),{0})/CHILD(TINFO(LHCb.Track.FitVeloNDoF,-1),{0}),-1))', + 'log_TRACK_TCHI2NDOF' : 'log10(switch(CHILD(TINFO(LHCb.Track.FitTNDoF,-1),{0})>0,CHILD(TINFO(LHCb.Track.FitTChi2,-1),{0})/CHILD(TINFO(LHCb.Track.FitTNDoF,-1),{0}),-1))', + 'log_TRACK_MatchCHI2' : 'log10(CHILD(TINFO(LHCb.Track.FitMatchChi2,-1.),{0}))', + 'log_TRACK_GhostProb' : 'log10(CHILD(TRGHOSTPROB,{0}))', + 'UsedRichAerogel' : 'switch(CHILDCUT(PPCUT(PP_USEDAEROGEL),{0}),1,0)', + 'UsedRich1Gas' : 'switch(CHILDCUT(PPCUT(PP_USEDRICH1GAS),{0}),1,0)', + 'UsedRich2Gas' : 'switch(CHILDCUT(PPCUT(PP_USEDRICH2GAS),{0}),1,0)', + 'RichAbovePiThres' : 'switch(CHILDCUT(PPCUT(PP_RICHTHRES_PI),{0}),1,0)', + 'RichAboveKaThres' : 'switch(CHILDCUT(PPCUT(PP_RICHTHRES_K),{0}),1,0)', + 'RichAbovePrThres' : 'switch(CHILDCUT(PPCUT(PP_RICHTHRES_P),{0}),1,0)', + 'atan_RichDLLe' : 'atan(CHILD(PPINFO(LHCb.ProtoParticle.RichDLLe,-1000),{0}))', + 'atan_RichDLLmu' : 'atan(CHILD(PPINFO(LHCb.ProtoParticle.RichDLLmu,-1000),{0}))', + 'atan_RichDLLk' : 'atan(CHILD(PPINFO(LHCb.ProtoParticle.RichDLLk,-1000),{0}))', + 'atan_RichDLLp' : 'atan(CHILD(PPINFO(LHCb.ProtoParticle.RichDLLp,-1000),{0}))', + 'atan_RichDLLbt' : 'atan(CHILD(PPINFO(LHCb.ProtoParticle.RichDLLbt,-1000),{0}))', + 'atan_MuonLLbg' : 'atan(switch(CHILD(PPINFO(LHCb.ProtoParticle.InAccMuon,0),{0})==1,CHILD(PPINFO(LHCb.ProtoParticle.MuonBkgLL,-10000),{0}),-1000))', + 'atan_MuonLLmu' : 'atan(switch(CHILD(PPINFO(LHCb.ProtoParticle.InAccMuon,0),{0})==1,CHILD(PPINFO(LHCb.ProtoParticle.MuonMuLL,-10000),{0}),-1000))', + 'isMuon' : 'switch(CHILDCUT(ISMUON,{0}),1,0)', + 'MuonNShared' : 'switch(CHILD(PPINFO(LHCb.ProtoParticle.InAccMuon,0),{0})==1,CHILD(PPINFO(LHCb.ProtoParticle.MuonNShared,0),{0}),-1)', + 'VeloCharge' : 'CHILD(PPINFO(LHCb.ProtoParticle.VeloCharge,-1000),{0})', + } + # Add all parent variables to output + for var, loki in vars_parent.iteritems(): + bdt_vars.update({'{}_{}'.format(parentname, var) : loki}) + # Add all daughter variables to output + for daugthername, lab in daugthers.iteritems(): + for var, loki in vars_daughters.iteritems(): + bdt_vars.update({'{}_{}_{}'.format(parentname,daugthername, var) : loki.format(lab)}) + # Print out variables for sanity + #for key in sorted(bdt_vars): + # print '{:<25} : {}'.format(key, bdt_vars[key].replace(',', ', ')) + #print 80 * '-' + return bdt_vars +