From 4da3b099b689cd63cb419d42c47bf274ce4712b0 Mon Sep 17 00:00:00 2001 From: jbex <Josh Bex joshua.james.bex@cern.ch> Date: Fri, 27 Sep 2024 16:45:50 +0100 Subject: [PATCH 1/4] reversepid data lines, additional filtered simulation --- ..._BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...si_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py | 672 ++++++++++++++++++ ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py | 672 ++++++++++++++++++ ...LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py | 672 ++++++++++++++++++ ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py | 672 ++++++++++++++++++ ..._BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...si_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py | 672 ++++++++++++++++++ ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py | 672 ++++++++++++++++++ ...LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py | 672 ++++++++++++++++++ ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py | 672 ++++++++++++++++++ ..._BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...si_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...taunu_Kmunu_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...nu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...u_DtoK0munu_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...unu_Kpimunu_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...unu_Kpimunu_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...unu_phitoKK_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...unu_phitoKK_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py | 672 ++++++++++++++++++ ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py | 672 ++++++++++++++++++ ...LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py | 672 ++++++++++++++++++ ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py | 672 ++++++++++++++++++ ...topKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...munu_pKmunu_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ ...aunu_pKmunu_mc_background-filt_Lb2pK_Mu.py | 672 ++++++++++++++++++ lbtopktautau/info.yaml | 355 +++++++++ 30 files changed, 19843 insertions(+) create mode 100644 lbtopktautau/2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py create mode 100644 lbtopktautau/2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py create mode 100644 lbtopktautau/2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py create mode 100644 lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py create mode 100644 lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py create mode 100644 lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py create mode 100644 lbtopktautau/2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py create mode 100644 lbtopktautau/2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py create mode 100644 lbtopktautau/2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py create mode 100644 lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py create mode 100644 lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py create mode 100644 lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py create mode 100644 lbtopktautau/2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py create mode 100644 lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py create mode 100644 lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py create mode 100644 lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py create mode 100644 lbtopktautau/info.yaml diff --git a/lbtopktautau/2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py b/lbtopktautau/2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py new file mode 100644 index 0000000000..d972dd36bb --- /dev/null +++ b/lbtopktautau/2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2016' +mcdecay = '[B_s0 ==> ^K+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py b/lbtopktautau/2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py new file mode 100644 index 0000000000..d9b79f0b6f --- /dev/null +++ b/lbtopktautau/2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2016' +mcdecay = '[B0 ==> ^K+ ^pi- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py b/lbtopktautau/2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py new file mode 100644 index 0000000000..285ce848f0 --- /dev/null +++ b/lbtopktautau/2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2016' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py new file mode 100644 index 0000000000..6ac86280a7 --- /dev/null +++ b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDK_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2016' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py new file mode 100644 index 0000000000..271375d1c2 --- /dev/null +++ b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDMu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2016' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py new file mode 100644 index 0000000000..f3c8dc57e9 --- /dev/null +++ b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDp_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2016' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py b/lbtopktautau/2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py new file mode 100644 index 0000000000..dc03edda29 --- /dev/null +++ b/lbtopktautau/2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2017' +mcdecay = '[B_s0 ==> ^K+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py b/lbtopktautau/2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py new file mode 100644 index 0000000000..a6f4d8fd79 --- /dev/null +++ b/lbtopktautau/2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2017' +mcdecay = '[B0 ==> ^K+ ^pi- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py b/lbtopktautau/2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py new file mode 100644 index 0000000000..551376f179 --- /dev/null +++ b/lbtopktautau/2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2017' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py new file mode 100644 index 0000000000..4d86d15531 --- /dev/null +++ b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDK_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2017' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py new file mode 100644 index 0000000000..a6a8516374 --- /dev/null +++ b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDMu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2017' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py new file mode 100644 index 0000000000..4b448bf760 --- /dev/null +++ b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDp_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2017' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py b/lbtopktautau/2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py new file mode 100644 index 0000000000..f79cffa168 --- /dev/null +++ b/lbtopktautau/2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[B_s0 ==> ^K+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py b/lbtopktautau/2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py new file mode 100644 index 0000000000..36ebee1445 --- /dev/null +++ b/lbtopktautau/2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[B0 ==> ^K+ ^pi- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..4dedb0b235 --- /dev/null +++ b/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..4dedb0b235 --- /dev/null +++ b/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..0b35650c70 --- /dev/null +++ b/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu- ^pi0]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..4dedb0b235 --- /dev/null +++ b/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..e00a058d9b --- /dev/null +++ b/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^pi- ^K- ^pi+ ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..e00a058d9b --- /dev/null +++ b/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^pi- ^K- ^pi+ ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..555558c541 --- /dev/null +++ b/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^K+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..555558c541 --- /dev/null +++ b/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^K+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py b/lbtopktautau/2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py new file mode 100644 index 0000000000..d48c2ba045 --- /dev/null +++ b/lbtopktautau/2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py new file mode 100644 index 0000000000..70ee7fb80c --- /dev/null +++ b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDK_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py new file mode 100644 index 0000000000..5cea9b6643 --- /dev/null +++ b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDMu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py new file mode 100644 index 0000000000..cd74cd96a0 --- /dev/null +++ b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = False +noPID = False +no_restrip = False +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDp_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = 'N/A' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..4dedb0b235 --- /dev/null +++ b/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..5ddc4658b9 --- /dev/null +++ b/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Xi_b0 -> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py new file mode 100644 index 0000000000..5ddc4658b9 --- /dev/null +++ b/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py @@ -0,0 +1,672 @@ + +########################################################## +# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +simulation = True +noPID = True +no_restrip = True +stripping_stream = 'Semileptonic' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' +decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' +branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} +year = '2018' +mcdecay = '[Xi_b0 -> ^p+ ^K- ^mu+ ^mu-]CC' +# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py +# From here on, the file dv_options_generic.py will be used +# (Stripping will be added first for the lb2pkemu line) +########################################################### + +try: + simulation = simulation + noPID = noPID + no_restrip = no_restrip + stripping_stream = stripping_stream + stripping_line = stripping_line + decay = decay + branches = branches + year = year + mcdecay = mcdecay + +except NameError as error: + raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. + The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to + be specified first. Correct usage is to run 'ganga_options_generic.py'""") + +# don't use f-strings as not supported pre python 3.6! +print("Simulation = {0}".format(simulation)) +print("noPID = {0}".format(noPID)) +print("no_restrip = {0}".format(no_restrip)) +print("year = {0}".format(year)) +print("mcdecay descriptor = {0}".format(mcdecay)) +print("stripping stream = {0}".format(stripping_stream)) +print("stripping line = {0}".format(stripping_line)) +print("decay = {0}".format(decay)) +print("branches = {0}".format(branches)) + + +from Gaudi.Configuration import * +from LHCbKernel.Configuration import * +from DaVinci.Configuration import * +from DecayTreeTuple.Configuration import * + +from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple +from Configurables import TupleToolTISTOS +from Configurables import EventNodeKiller, ProcStatusCheck +from Configurables import LoKi__HDRFilter + +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration +from StrippingArchive.Utils import buildStreams +from StrippingArchive import strippingArchive + +############################################## + +print("\n## Determined stripping line to be: \n ===>", stripping_line) + +print("\n## config determined") +print("\n===> stream = ", stripping_stream) +print("\n===> line = ", stripping_line) +print("\n===> decay = ", decay) +print("\n===> branches = ", branches) +################################# +# ## Stream and stripping line ### +stream = stripping_stream +line = stripping_line + +########################### +# ## Restripping process ### + +# In the case that we are dealing with simulation, we may need to restrip due to the fact +# that the stripping version for the simulation is different (older) than that of the +# stripping line + +# In the case that we remove the PID requirements, this changes the restripping process +# since we edit the config file to remove these requirements + +if simulation == True: + if no_restrip == False: + event_node_killer = EventNodeKiller('StripKiller') + event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] + #################### + if noPID == False: # conventional restrip + if year == '2016': + strip = 'stripping28r2p2' + elif year == '2017': + strip = 'stripping29r2p3' + elif year == '2018': + strip = 'stripping34r0p3' + + streams = buildStreams(stripping=strippingConfiguration(strip), + archive=strippingArchive(strip)) + + custom_stream = StrippingStream('AllStreams') + custom_line = 'Stripping'+line + + for stream in streams: + for sline in stream.lines: + if sline.name() == custom_line: + custom_stream.appendLines([sline]) + ##################### + else: # remove PID requirements and restrip + # in this case we need to edit the config to remove PID requirements + # different stripping versions for different years + if year == '2016': + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2017': + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + elif year == '2018': + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder + from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config + + # print the unedited config file + print("OLD CONFIG below") + print(config['CONFIG']) + print("OLD CONFIG above") + + # edit the config + config1 = config['CONFIG'] + config1['MuonPID'] = -1001 + config1['ElectronPID'] = -1001 + config1['UseNoPIDsHadrons'] = True + + # then print the edited config file + print("NEW CONFIG below") + print(config1) + print("NEW CONFIG above") + + lb = builder('B2XTauTauLeptonic', config1) + custom_stream = StrippingStream('MyStream') + # Now we have the stream and the line and can add the lines to the stream + target_line = 'Stripping' + line + for sline in lb.lines(): + if sline.name() == target_line: + custom_stream.appendLines([sline]) + ####################### + filterBadEvents = ProcStatusCheck() + sc = StrippingConf(Streams=[custom_stream], + MaxCandidates=10000, + AcceptBadEvents=False, + BadEventSelection=filterBadEvents) + + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] + else: # no restrip + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] + +else: # data rather than simulation + ### Fill tuple with DecayTreeTuple ### + dtt = DecayTreeTuple('DecayTreeTuple') + dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] +######################################## +# ## Define decay and create branches ### +dtt.Decay = decay +dtt.addBranches(branches) + +###################### +# ## Add tupletools ### +# # Generic tupletools ## +dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic + +SubMassTool = dtt.addTupleTool('TupleToolSubMass') + +# +# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] +# Particle daughters are sorted by PID at each branch of the tree (cc-independant) +# +#**** Substitution property +# +# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] +# produce alternative mass with substituted PID pi<->K (cc is assumed) +# +#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) +# +#**** DoubleSubstitution property +# +# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] +# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) +# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) +# +# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) + + +GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple +GeometryTool.Verbose=True +# head_MINIP : minimum impact parameter on any PV +# head_MINIPCHI2 : minimum chi2 IP on all PVs +# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles +# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles +# head_ENDVERTEX_CHI2 : decay vertex chi2 +# head_ENDVERTEX_NDOF : decay vertex nDoF +# head_OWNPV_[X|Y|Z] : related primary vertex position +# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles +# head_OWNPV_CHI2 : related primary vertex chi2 +# head_OWNPV_NDOF : related primary vertex nDoF +# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle +# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle +# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle +# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle +# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle + +# Verbose being true gives: +# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position +# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate +# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 +# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF +# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain +# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain +# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain +# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain +# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain +# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) +# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) +# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) +# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) +# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) +# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) +# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) +# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) +# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) + +KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple +KinematicTool.Verbose=True +# head_P : momentum's amplitude +# head_PT : transverse momentum +# head_P[E|X|Y|Z] : four vector momentum +# head_MM : measured mass (or assigned mass in case of 'basic' particle +# head_M : mass calculated from momentum four-vector +# head_MMERR : error on the measured mass (only for non-basic parts) + +# Verbose being true gives: +# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through +# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). +# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut +# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position + +TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple +TrackInfoTool.Verbose=True +# X_TRACK_CHI2NDOF : track chi2/ndof +# X_TRACK_TYPE : track type +# X_TRACK_PCHI2 : track Chi2 probability +# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) +# X_TRACK_CloneDist : Only available for 2009 data + +# Verbose being true gives: +# X_TRACK_CHI2 : track chi2 +# X_TRACK_NDOF : track ndof +# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF +# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF +# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs +# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs +# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs +# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs +# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs +# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs +# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs +# X_TRACK_nVeloHits : Number of Velo hits on the track +# X_TRACK_nVeloRHits : Number of Velo R hits on the track +# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track +# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track +# X_TRACK_nTTHits : Number of TT hits on the track +# X_TRACK_nITHits : Number of IT hits on the track +# X_TRACK_nOTHits : Number of OT hits on the track +# X_TRACK_nVPHits : Number of VP hits on the track +# X_TRACK_nUTHits : Number of UT hits on the track +# X_TRACK_nFTHits : Number of FT hits on the track +# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' +# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' +# X_TRACK_History: Algorithm which the track was made with +# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' +# X_TRACK_Tx : x slope of state at 'FirstMeasurement' +# X_TRACK_Ty : y slope of state at 'FirstMeasurement' + +EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple +EventInfoTool.Verbose=True +# runNumber: well, the run number +# eventNumber: +# BCID and BC type +# Odin and Hlt TCKs +# GPS time +# If the property Mu is given it will fill the Mu of the run. A working dictionary can be +# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp + +# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are +# numbered [0-11]. That's a convention. Sorry. + +PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple +# PropertimeTool.Verbose=True +# head_TAU +# head_TAUERR +# head_TAUCHI2 + +RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. +# RecoStatsTool.Verbose=True + +PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple +# PidTool.Verbose=True +# head_ID : particleID().pid(); +# For the long lived particles (isBasicParticle()). +# head_PIDe : LHCb::ProtoParticle::CombDLLe +# head_PIDmu : LHCb::ProtoParticle::CombDLLmu +# head_PIDK : LHCb::ProtoParticle::CombDLLk +# head_PIDp : LHCb::ProtoParticle::CombDLLp + +ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" +# ANNPIDTool.Verbose=True + +AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame +# AnglesTool.Verbose=True +# head_CosTheta : angle in mother's frame +# if WRTMother is false, will calculate angle in frame of top of tree + +PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple +# PrimariesTool.Verbose=True +# coordinates PVX, PVY, PVZ +# errors PVXERR, PVYERR, PVZERR +# vertex chi2 PVCHI +# vertex ndf PVNDOF +# Nb of tracks used to do the vertex PVNTRACKS + +## Isolation variables ## + +# cone isolation # +ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolmother.MinConeSize = 0.5 +ConeIsoToolmother.MaxConeSize = 0.9 +ConeIsoToolmother.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolmother.FillAsymmetry = True +ConeIsoToolmother.FillDeltas = True +ConeIsoToolmother.FillComponents = True +# also fill intermediate hadron branch +ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +ConeIsoToolinter.MinConeSize = 0.5 +ConeIsoToolinter.MaxConeSize = 0.9 +ConeIsoToolinter.SizeStep = 0.2 +# Fill asymmetry, delta, and component variables +ConeIsoToolinter.FillAsymmetry = True +ConeIsoToolinter.FillDeltas = True +ConeIsoToolinter.FillComponents = True + +# head_cc: charged cone +# head_nc: neutral cone + +# head_XX_mult : number of objects inside the cone +# head_XX_sPT : scalar-summed pT of the objects inside the cone +# head_XX_vPT : vector-summed pT of the objects inside the cone +# head_XX_P : x, y and z components of the cone momentum +# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) +# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry +# head_XX_deltaEta : difference in eta between the head and the cone +# head_XX_deltaPhi : difference in phi between the head and the cone +# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T +# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T +# head_cc_maxPt_Q : charge of the max-pT object in the charged cone +# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone +# head_MasshPi0: invariant mass of the seed-Pi0 combinations +# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions +# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 +# head_Pi0_M: invariant mass of the pi0 +# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters + +# track isolation # +TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolmother.MinConeAngle = 0.5 +TrackIsoToolmother.MaxConeAngle = 0.9 +TrackIsoToolmother.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolmother.FillAsymmetry = True +TrackIsoToolmother.FillDeltaAngles = True +# also fill intermediate hadron branch +TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians +TrackIsoToolinter.MinConeAngle = 0.5 +TrackIsoToolinter.MaxConeAngle = 0.9 +TrackIsoToolinter.StepSize = 0.2 +# fill asymmetry and DeltaAngles variables +TrackIsoToolinter.FillAsymmetry = True +TrackIsoToolinter.FillDeltaAngles = True + +# Open up a cone around head, exclude all tracks that are in the decay descriptor +# (i.e. that belong to the decay you are looking for), build the variables with +# the remaining tracks. + +# head_cmult : Number of tracks inside cone. +# head_cp : Summed p inside cone +# head_cpt : Summed pt inside cone +# head_cpx : Summed px inside cone +# head_cpy : Summed py inside cone +# head_cpz : Summed pz inside cone + +# If Verbose, or other flags are set: + +# Asymmetry variables + +# head_pasy : (head_P - head_cp)/(head_P + head_cp) +# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) +# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) +# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) +# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables +# head_DeltaEta : Difference in eta between summed tracks and head +# head_DeltaPhi : Difference in phi between summed tracks and head + + +# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians +# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians +# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians +# TrackType: Set the type of tracks which are considered inside the cone (default = 3) +# FillAsymmetry: Flag to fill the asymmetry variables (default = false) +# FillDeltaAngles: Flag to fill the delta angle variables (default = false) + +# vertex isolation # +# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both +VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') +VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') + +# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window +# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window +# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles +# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles +#### updates: +# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window +# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 +# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination +# that has the smallest delta chi2 when adding one track +# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding +# one track to the combination that has the smallest delta chi2 when adding one track + +## Hybrid tupletool ## +all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') +all_hybrid.Variables = { + 'ETA' : "ETA", #pseudorapidity + 'PHI' : "PHI", #asimuthal angle + 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", + #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary + #vertices from desktop. + 'MINIP' : "MIPDV(PRIMARY)", + #The special version of LoKi::Particles::MinImpPar functor which gets all the primary + #vertices from desktop. + 'IPCHI2_OWNPV' : "BPVIPCHI2()", + #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets + #the related primary vertex from IPhysDesktop tool + 'IP_OWNPV' : "BPVIP()", + #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the + #related primary vertex from IPhysDesktop tool. + 'DIRA_OWNPV' : "BPVDIRA", + 'ghost' : "TRGHP", #simple evaluator of "ghost probability" + 'TrackCHI2DOF' : 'TRCHI2DOF', + 'FD_CHI2' : "BPVVDCHI2", + #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance + #between the particle "endVertex" and "the vertex". + 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', + # #Decay tree fitter functions: + # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", + # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. + # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", + # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees + # #of freedom for the vertex + # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , + # 'DTF_MASS' : "DTF_FUN ( M , True )" , + # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", + # #Evaluate $c\tau$ for the dauthter particle in the decay tree. + # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" + # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle + # #in the decay tree. +} + +lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') +lb_hybrid.Variables = { + 'DOCAjpsiinter' : "DOCA(1,2)", + 'DOCAmotherjpsi' : "DOCA(0,1)", + 'DOCAmotherinter' : "DOCA(0,2)", + 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", + 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", + 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" +} +jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') +jpsi_hybrid.Variables = { + 'DOCAd1d2' : "DOCA(1,2)", + 'DOCAjpsid1' : "DOCA(0,1)", + 'DOCAjpsid2' : "DOCA(0,2)", + 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", + 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", + 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" +} +inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') +inter_hybrid.Variables = { + #note that the end vertex of the intermediate hadron is also the end vertex of the lb + 'DOCAh1h2' : "DOCA(1,2)", + 'DOCAmotherh1' : "DOCA(0,1)", + 'DOCAmotherh2' : "DOCA(0,2)", + 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", + 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", + 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" +} + +################ +### Triggers ### +# Add trigger list # + +L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] +Hlt1Triggers = [# muon lines + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + # dimuon lines + 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', + # MVA lines + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' + ] +Hlt2Triggers = [# topo lines + 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', + 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', + 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', + # muon lines + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', + 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', + # dimuon lines + 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', + 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', + 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' + ] +# Electrons in Sel +if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: + L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] + Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] + Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", + "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", + "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" + ] + +AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers + +MuonTriggers = [# L0 + 'L0MuonDecision', + # Hlt1 + 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', + # Hlt2 + 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', + 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' + ] +HadronTriggers = [# L0 + 'L0HadronDecision', + # Hlt1 + 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' + ] +ElectronTriggers = [# L0 + "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", + # Hlt1 + "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] + +# TupleToolTISTOS # +# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection +dtt.mother.ToolList += [ "TupleToolTISTOS" ] +dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.mother.TupleToolTISTOS.Verbose = True +dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers +dtt.d2.ToolList += [ "TupleToolTISTOS" ] +dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d2.TupleToolTISTOS.Verbose = True +dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.d1.ToolList += [ "TupleToolTISTOS" ] +dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.d1.TupleToolTISTOS.Verbose = True +dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers +dtt.h1.ToolList += [ "TupleToolTISTOS" ] +dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h1.TupleToolTISTOS.Verbose = True +if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers +elif '_EPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_PiPi_' in stripping_line: + dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers +# else: # TODO remove +# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') + +dtt.h2.ToolList += [ "TupleToolTISTOS" ] +dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) +dtt.h2.TupleToolTISTOS.Verbose = True +if '_E_' in stripping_line or '_MuE_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers +elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: + dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers + +## MC truth value tupletools ## +if simulation == True: + MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present + # head_TRUEID : true pid + MCTruthTool.ToolList = [ + "MCTupleToolKinematic", + # head_TRUEP[E|X|Y|Z] : true four vector momentum + # head_TRUEPT : true transverse momentum, PT + # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. + # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) + # head_TRUEISSTABLE : MCAssociate has no daughters. + # head_TRUETAU : true propertime + "MCTupleToolHierarchy", + # head_MC_MOTHER_ID : true mc mother ID + # head_MC_MOTHER_KEY : true mc mother key + # head_MC_GD_MOTHER_ID : grand mother ID + # head_MC_GD_MOTHER_KEY : grand mother key + # head_MC_GD_GD_MOTHER_ID : grand grand mother ID + # head_MC_GD_GD_MOTHER_KEY : grand grand mother key + ] + + ## Hybrid tupletool ## + hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_dtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + + MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. + # head_BKGCAT : category + + # add mcdecaytreetuple + + def Make_MCTuple(decay): + MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") + + MCTuple.Decay = decay + MCTuple.setDescriptorTemplate( decay ) + MCTuple.ToolList = [ + "MCTupleToolKinematic" + , "MCTupleToolHierarchy" + , "MCTupleToolAngles" + , "MCTupleToolPID" + , "TupleToolEventInfo" + , "TupleToolRecoStats" + ] + ## Hybrid tupletool ## + hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') + hybrid_mc_mcdtt.Variables = { + 'MCETA' : "MCETA", #pseudorapidity + 'MCPHI' : "MCPHI", #asimuthal angle + } + return MCTuple + + + MCTuple = Make_MCTuple(mcdecay) + +######################### +# ## Configure DaVinci ### +from Configurables import GaudiSequencer +MySequencer = GaudiSequencer('Sequence') +if simulation == True: + MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] + # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] +else: + MySequencer.Members = [dtt] + +DaVinci().UserAlgorithms += [MySequencer] +DaVinci().EvtMax = -1 +DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/info.yaml b/lbtopktautau/info.yaml new file mode 100644 index 0000000000..94890cfce7 --- /dev/null +++ b/lbtopktautau/info.yaml @@ -0,0 +1,355 @@ +defaults: + wg: RD + output: ntuples.root + inform: + - lmadhanm@hep.phy.cam.ac.uk + - joshua.james.bex@cern.ch + automatically_configure: 'True' +MD_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST + options: + - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +MU_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST + options: + - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +MD_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST + options: + - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +MU_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST + options: + - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +MD_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST + options: + - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +MU_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST + options: + - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +MD_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST + options: + - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +MU_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST + options: + - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +MD_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST + options: + - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +MU_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST + options: + - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +MD_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST + options: + - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +MU_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST + options: + - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +MD_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST + options: + - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +MU_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST + options: + - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +MD_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST + options: + - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +MU_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST + options: + - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +MD_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST + options: + - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +MU_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: + application: DaVinci/v46r5 + input: + bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST + options: + - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +MD_2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15514042/PKTAUTAU.STRIP.DST + options: + - 2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py +MU_2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15514042/PKTAUTAU.STRIP.DST + options: + - 2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py +MD_2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15596900/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py +MU_2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15596900/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py +MD_2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576040/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py +MU_2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576040/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py +MD_2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576041/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py +MU_2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576041/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py +MD_2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576050/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py +MU_2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576050/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py +MD_2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576051/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py +MU_2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576051/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py +MD_2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/16574050/PKTAUTAU.STRIP.DST + options: + - 2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py +MU_2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/16574050/PKTAUTAU.STRIP.DST + options: + - 2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py +MD_2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/16574051/PKTAUTAU.STRIP.DST + options: + - 2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py +MU_2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/16574051/PKTAUTAU.STRIP.DST + options: + - 2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py +MD_2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574401/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py +MU_2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574401/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py +MD_2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574037/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py +MU_2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574037/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py +MD_2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574039/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py +MU_2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574039/PKTAUTAU.STRIP.DST + options: + - 2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py +MD_2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09l/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/15144001/ALLSTREAMS.DST + options: + - 2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +MU_2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2016/Beam6500GeV-2016-MagUp-Nu1.6-25ns-Pythia8/Sim09l/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/15144001/ALLSTREAMS.DST + options: + - 2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +MD_2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2017/Beam6500GeV-2017-MagDown-Nu1.6-25ns-Pythia8/Sim09h/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2p1NoPrescalingFlagged/15144001/ALLSTREAMS.DST + options: + - 2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +MU_2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2017/Beam6500GeV-2017-MagUp-Nu1.6-25ns-Pythia8/Sim09h/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2p1NoPrescalingFlagged/15144001/ALLSTREAMS.DST + options: + - 2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +MD_2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim09h/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p1NoPrescalingFlagged/15144001/ALLSTREAMS.DST + options: + - 2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +MU_2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim09h/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p1NoPrescalingFlagged/15144001/ALLSTREAMS.DST + options: + - 2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +MD_2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09k/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/13144041/ALLSTREAMS.DST + options: + - 2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +MU_2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2016/Beam6500GeV-2016-MagUp-Nu1.6-25ns-Pythia8/Sim09k/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/13144041/ALLSTREAMS.DST + options: + - 2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +MD_2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2017/Beam6500GeV-2017-MagDown-Nu1.6-25ns-Pythia8/Sim09k/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2p1NoPrescalingFlagged/13144041/ALLSTREAMS.DST + options: + - 2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +MU_2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2017/Beam6500GeV-2017-MagUp-Nu1.6-25ns-Pythia8/Sim09k/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2p1NoPrescalingFlagged/13144041/ALLSTREAMS.DST + options: + - 2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +MD_2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim09k/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p1NoPrescalingFlagged/13144041/ALLSTREAMS.DST + options: + - 2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +MU_2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim09k/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p1NoPrescalingFlagged/13144041/ALLSTREAMS.DST + options: + - 2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +MD_2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09l/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/11144001/ALLSTREAMS.DST + options: + - 2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py +MU_2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2016/Beam6500GeV-2016-MagUp-Nu1.6-25ns-Pythia8/Sim09l/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/11144001/ALLSTREAMS.DST + options: + - 2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py +MD_2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2017/Beam6500GeV-2017-MagDown-Nu1.6-25ns-Pythia8/Sim09l/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2NoPrescalingFlagged/11144001/ALLSTREAMS.DST + options: + - 2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py +MU_2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2017/Beam6500GeV-2017-MagUp-Nu1.6-25ns-Pythia8/Sim09l/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2NoPrescalingFlagged/11144001/ALLSTREAMS.DST + options: + - 2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py +MD_2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim09l/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34NoPrescalingFlagged/11144001/ALLSTREAMS.DST + options: + - 2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py +MU_2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: + application: DaVinci/v44r11p6 + input: + bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim09l/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34NoPrescalingFlagged/11144001/ALLSTREAMS.DST + options: + - 2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py -- GitLab From a501d0d00323bdaf9a4d86761a4a25e5080eace5 Mon Sep 17 00:00:00 2001 From: jbex <Josh Bex joshua.james.bex@cern.ch> Date: Fri, 27 Sep 2024 17:06:28 +0100 Subject: [PATCH 2/4] fixing restripping bug --- .../2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py | 2 +- .../2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py | 2 +- .../2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py | 2 +- ..._LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py | 2 +- .../2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py | 2 +- .../2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py | 2 +- ...oLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py | 2 +- ...Lcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py | 2 +- lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py | 2 +- .../2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py index 4dedb0b235..d48c2ba045 100644 --- a/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py index 4dedb0b235..d48c2ba045 100644 --- a/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py index 0b35650c70..2bd4d4f3fb 100644 --- a/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py index 4dedb0b235..d48c2ba045 100644 --- a/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py index e00a058d9b..0e1a0eab6e 100644 --- a/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py index e00a058d9b..0e1a0eab6e 100644 --- a/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py index 555558c541..e82e9083ad 100644 --- a/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py index 555558c541..e82e9083ad 100644 --- a/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py index 4dedb0b235..d48c2ba045 100644 --- a/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py index 5ddc4658b9..f5c15c63ee 100644 --- a/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -- GitLab From e0392154a82a440c71a793e4b56f860804eea4c3 Mon Sep 17 00:00:00 2001 From: jbex <Josh Bex joshua.james.bex@cern.ch> Date: Fri, 27 Sep 2024 18:03:46 +0100 Subject: [PATCH 3/4] reversepid data lines, additional filtered simulation finalised --- ...016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py | 672 ------------------ ...017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py | 672 ------------------ ...018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py | 672 ------------------ ...munu_pKmunu_mc_background-filt_Lb2pK_Mu.py | 2 +- lbtopktautau/info.yaml | 36 - 5 files changed, 1 insertion(+), 2053 deletions(-) delete mode 100644 lbtopktautau/2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py diff --git a/lbtopktautau/2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py b/lbtopktautau/2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py deleted file mode 100644 index 285ce848f0..0000000000 --- a/lbtopktautau/2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2016' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py b/lbtopktautau/2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py deleted file mode 100644 index 551376f179..0000000000 --- a/lbtopktautau/2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2017' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py b/lbtopktautau/2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py deleted file mode 100644 index d48c2ba045..0000000000 --- a/lbtopktautau/2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py index 5ddc4658b9..f5c15c63ee 100644 --- a/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py +++ b/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py @@ -3,7 +3,7 @@ # AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py simulation = True noPID = True -no_restrip = True +no_restrip = False stripping_stream = 'Semileptonic' stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' diff --git a/lbtopktautau/info.yaml b/lbtopktautau/info.yaml index 94890cfce7..e7e702355e 100644 --- a/lbtopktautau/info.yaml +++ b/lbtopktautau/info.yaml @@ -245,42 +245,6 @@ MU_2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu: bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574039/PKTAUTAU.STRIP.DST options: - 2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py -MD_2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09l/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/15144001/ALLSTREAMS.DST - options: - - 2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py -MU_2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2016/Beam6500GeV-2016-MagUp-Nu1.6-25ns-Pythia8/Sim09l/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/15144001/ALLSTREAMS.DST - options: - - 2016_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py -MD_2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2017/Beam6500GeV-2017-MagDown-Nu1.6-25ns-Pythia8/Sim09h/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2p1NoPrescalingFlagged/15144001/ALLSTREAMS.DST - options: - - 2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py -MU_2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2017/Beam6500GeV-2017-MagUp-Nu1.6-25ns-Pythia8/Sim09h/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2p1NoPrescalingFlagged/15144001/ALLSTREAMS.DST - options: - - 2017_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py -MD_2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim09h/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p1NoPrescalingFlagged/15144001/ALLSTREAMS.DST - options: - - 2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py -MU_2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim09h/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p1NoPrescalingFlagged/15144001/ALLSTREAMS.DST - options: - - 2018_LbtopKjpsi_mumu_mc_control_Lb2pK_Mu.py MD_2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: application: DaVinci/v44r11p6 input: -- GitLab From 1ba133d0382648d02716b7d322a891c92f1d18be Mon Sep 17 00:00:00 2001 From: jbex <Josh Bex joshua.james.bex@cern.ch> Date: Mon, 14 Oct 2024 11:09:37 +0100 Subject: [PATCH 4/4] correct reverse pid mu naming --- ..._BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py | 672 ------------------ ...si_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py | 672 ------------------ ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py | 672 ------------------ ...LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py | 672 ------------------ ...btopKtautau_data_Lb2pK_Mu_ReversePIDmu.py} | 52 +- ..._BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py | 672 ------------------ ...si_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py | 672 ------------------ ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py | 672 ------------------ ...LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py | 672 ------------------ ...btopKtautau_data_Lb2pK_Mu_ReversePIDmu.py} | 52 +- ..._BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py | 672 ------------------ ...si_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py | 672 ------------------ ...pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...taunu_Kmunu_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...nu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...u_DtoK0munu_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...unu_Kpimunu_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...unu_Kpimunu_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...unu_phitoKK_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...unu_phitoKK_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py | 672 ------------------ ...btopKtautau_data_Lb2pK_Mu_ReversePIDmu.py} | 52 +- ..._LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py | 672 ------------------ ...topKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py | 672 ------------------ ...munu_pKmunu_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ ...aunu_pKmunu_mc_background-filt_Lb2pK_Mu.py | 672 ------------------ lbtopktautau/info.yaml | 300 +------- 27 files changed, 60 insertions(+), 15852 deletions(-) delete mode 100644 lbtopktautau/2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py delete mode 100644 lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py rename lbtopktautau/{2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py => 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py} (94%) delete mode 100644 lbtopktautau/2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py delete mode 100644 lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py rename lbtopktautau/{2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py => 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py} (94%) delete mode 100644 lbtopktautau/2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py rename lbtopktautau/{2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py => 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py} (94%) delete mode 100644 lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py delete mode 100644 lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py delete mode 100644 lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py diff --git a/lbtopktautau/2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py b/lbtopktautau/2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py deleted file mode 100644 index d972dd36bb..0000000000 --- a/lbtopktautau/2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2016' -mcdecay = '[B_s0 ==> ^K+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py b/lbtopktautau/2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py deleted file mode 100644 index d9b79f0b6f..0000000000 --- a/lbtopktautau/2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2016' -mcdecay = '[B0 ==> ^K+ ^pi- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py deleted file mode 100644 index 6ac86280a7..0000000000 --- a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = False -noPID = False -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDK_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2016' -mcdecay = 'N/A' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py deleted file mode 100644 index 271375d1c2..0000000000 --- a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = False -noPID = False -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDMu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2016' -mcdecay = 'N/A' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py similarity index 94% rename from lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py rename to lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py index f3c8dc57e9..847e245ef9 100644 --- a/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +++ b/lbtopktautau/2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py @@ -5,7 +5,7 @@ simulation = False noPID = False no_restrip = False stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDp_line' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDmu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} year = '2016' @@ -334,25 +334,16 @@ PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices propert ## Isolation variables ## # cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +ConeIsoTool = dtt.addTupleTool('TupleToolConeIsolation') # choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 +ConeIsoTool.MinConeSize = 0.6 +ConeIsoTool.MaxConeSize = 0.6 +# ConeIsoTool.SizeStep = 0.2 # Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True +# ConeIsoTool.FillAsymmetry = True +# ConeIsoTool.FillDeltas = True +# ConeIsoTool.FillComponents = True + # head_cc: charged cone # head_nc: neutral cone @@ -376,23 +367,14 @@ ConeIsoToolinter.FillComponents = True # head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters # track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +TrackIsoTool = dtt.addTupleTool('TupleToolTrackIsolation') # choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 +TrackIsoTool.MinConeAngle = 0.6 +TrackIsoTool.MaxConeAngle = 0.6 +# TrackIsoTool.StepSize = 0.2 # fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True +TrackIsoTool.FillAsymmetry = True +# TrackIsoTool.FillDeltaAngles = True # Open up a cone around head, exclude all tracks that are in the decay descriptor # (i.e. that belong to the decay you are looking for), build the variables with @@ -426,9 +408,7 @@ TrackIsoToolinter.FillDeltaAngles = True # FillDeltaAngles: Flag to fill the delta angle variables (default = false) # vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') +VtxIsoTool = dtt.addTupleTool('TupleToolVtxIsoln') # head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window # head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window diff --git a/lbtopktautau/2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py b/lbtopktautau/2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py deleted file mode 100644 index dc03edda29..0000000000 --- a/lbtopktautau/2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2017' -mcdecay = '[B_s0 ==> ^K+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py b/lbtopktautau/2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py deleted file mode 100644 index a6f4d8fd79..0000000000 --- a/lbtopktautau/2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2017' -mcdecay = '[B0 ==> ^K+ ^pi- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py deleted file mode 100644 index 4d86d15531..0000000000 --- a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = False -noPID = False -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDK_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2017' -mcdecay = 'N/A' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py deleted file mode 100644 index a6a8516374..0000000000 --- a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = False -noPID = False -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDMu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2017' -mcdecay = 'N/A' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py similarity index 94% rename from lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py rename to lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py index 4b448bf760..5cc09245ec 100644 --- a/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +++ b/lbtopktautau/2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py @@ -5,7 +5,7 @@ simulation = False noPID = False no_restrip = False stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDp_line' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDmu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} year = '2017' @@ -334,25 +334,16 @@ PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices propert ## Isolation variables ## # cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +ConeIsoTool = dtt.addTupleTool('TupleToolConeIsolation') # choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 +ConeIsoTool.MinConeSize = 0.6 +ConeIsoTool.MaxConeSize = 0.6 +# ConeIsoTool.SizeStep = 0.2 # Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True +# ConeIsoTool.FillAsymmetry = True +# ConeIsoTool.FillDeltas = True +# ConeIsoTool.FillComponents = True + # head_cc: charged cone # head_nc: neutral cone @@ -376,23 +367,14 @@ ConeIsoToolinter.FillComponents = True # head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters # track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +TrackIsoTool = dtt.addTupleTool('TupleToolTrackIsolation') # choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 +TrackIsoTool.MinConeAngle = 0.6 +TrackIsoTool.MaxConeAngle = 0.6 +# TrackIsoTool.StepSize = 0.2 # fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True +TrackIsoTool.FillAsymmetry = True +# TrackIsoTool.FillDeltaAngles = True # Open up a cone around head, exclude all tracks that are in the decay descriptor # (i.e. that belong to the decay you are looking for), build the variables with @@ -426,9 +408,7 @@ TrackIsoToolinter.FillDeltaAngles = True # FillDeltaAngles: Flag to fill the delta angle variables (default = false) # vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') +VtxIsoTool = dtt.addTupleTool('TupleToolVtxIsoln') # head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window # head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window diff --git a/lbtopktautau/2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py b/lbtopktautau/2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py deleted file mode 100644 index f79cffa168..0000000000 --- a/lbtopktautau/2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[B_s0 ==> ^K+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py b/lbtopktautau/2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py deleted file mode 100644 index 36ebee1445..0000000000 --- a/lbtopktautau/2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[B0 ==> ^K+ ^pi- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index d48c2ba045..0000000000 --- a/lbtopktautau/2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index d48c2ba045..0000000000 --- a/lbtopktautau/2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index 2bd4d4f3fb..0000000000 --- a/lbtopktautau/2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu- ^pi0]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index d48c2ba045..0000000000 --- a/lbtopktautau/2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index 0e1a0eab6e..0000000000 --- a/lbtopktautau/2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^pi- ^K- ^pi+ ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index 0e1a0eab6e..0000000000 --- a/lbtopktautau/2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^pi- ^K- ^pi+ ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index e82e9083ad..0000000000 --- a/lbtopktautau/2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^K+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index e82e9083ad..0000000000 --- a/lbtopktautau/2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^K+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py deleted file mode 100644 index 5cea9b6643..0000000000 --- a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = False -noPID = False -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDMu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = 'N/A' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py similarity index 94% rename from lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py rename to lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py index 70ee7fb80c..5b0c6f08fe 100644 --- a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py +++ b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py @@ -5,7 +5,7 @@ simulation = False noPID = False no_restrip = False stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDK_line' +stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDmu_line' decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} year = '2018' @@ -334,25 +334,16 @@ PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices propert ## Isolation variables ## # cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') +ConeIsoTool = dtt.addTupleTool('TupleToolConeIsolation') # choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 +ConeIsoTool.MinConeSize = 0.6 +ConeIsoTool.MaxConeSize = 0.6 +# ConeIsoTool.SizeStep = 0.2 # Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True +# ConeIsoTool.FillAsymmetry = True +# ConeIsoTool.FillDeltas = True +# ConeIsoTool.FillComponents = True + # head_cc: charged cone # head_nc: neutral cone @@ -376,23 +367,14 @@ ConeIsoToolinter.FillComponents = True # head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters # track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') +TrackIsoTool = dtt.addTupleTool('TupleToolTrackIsolation') # choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 +TrackIsoTool.MinConeAngle = 0.6 +TrackIsoTool.MaxConeAngle = 0.6 +# TrackIsoTool.StepSize = 0.2 # fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True +TrackIsoTool.FillAsymmetry = True +# TrackIsoTool.FillDeltaAngles = True # Open up a cone around head, exclude all tracks that are in the decay descriptor # (i.e. that belong to the decay you are looking for), build the variables with @@ -426,9 +408,7 @@ TrackIsoToolinter.FillDeltaAngles = True # FillDeltaAngles: Flag to fill the delta angle variables (default = false) # vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') +VtxIsoTool = dtt.addTupleTool('TupleToolVtxIsoln') # head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window # head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window diff --git a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py b/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py deleted file mode 100644 index cd74cd96a0..0000000000 --- a/lbtopktautau/2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = False -noPID = False -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_ReversePIDp_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = 'N/A' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py b/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py deleted file mode 100644 index d48c2ba045..0000000000 --- a/lbtopktautau/2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Lambda_b0 ==> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index f5c15c63ee..0000000000 --- a/lbtopktautau/2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Xi_b0 -> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py b/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py deleted file mode 100644 index f5c15c63ee..0000000000 --- a/lbtopktautau/2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py +++ /dev/null @@ -1,672 +0,0 @@ - -########################################################## -# AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -simulation = True -noPID = True -no_restrip = False -stripping_stream = 'Semileptonic' -stripping_line = 'B2XTauTauLeptonic_Lb2pK_Mu_line' -decay = '(( Lambda_b0 -> ^(D0 -> ^mu+ ^mu-) ^(Lambda(1520)0 -> ^p+ ^K-) )) || (( Lambda_b~0 -> ^(D0 -> ^mu- ^mu+) ^(Lambda(1520)~0 -> ^p~- ^K+) )) ' -branches = {'mother': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'jpsi': '(( Lambda_b0 -> ^(D0 -> mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> ^(D0 -> mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd1': '(( Lambda_b0 -> (D0 -> ^mu+ mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> ^mu- mu+) (Lambda(1520)~0 -> p~- K+) ))', 'd2': '(( Lambda_b0 -> (D0 -> mu+ ^mu-) (Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- ^mu+) (Lambda(1520)~0 -> p~- K+) ))', 'inter': '(( Lambda_b0 -> (D0 -> mu+ mu-) ^(Lambda(1520)0 -> p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) ^(Lambda(1520)~0 -> p~- K+) ))', 'h1': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> ^p+ K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> ^p~- K+) ))', 'h2': '(( Lambda_b0 -> (D0 -> mu+ mu-) (Lambda(1520)0 -> p+ ^K-) )) || (( Lambda_b~0 -> (D0 -> mu- mu+) (Lambda(1520)~0 -> p~- ^K+) ))'} -year = '2018' -mcdecay = '[Xi_b0 -> ^p+ ^K- ^mu+ ^mu-]CC' -# END AUTOMATICALLY GENERATED FILE IN ganga_options_generic.py -# From here on, the file dv_options_generic.py will be used -# (Stripping will be added first for the lb2pkemu line) -########################################################### - -try: - simulation = simulation - noPID = noPID - no_restrip = no_restrip - stripping_stream = stripping_stream - stripping_line = stripping_line - decay = decay - branches = branches - year = year - mcdecay = mcdecay - -except NameError as error: - raise RuntimeError("""{error} - most likely due to incorrect usage; don't run this file directly. - The variables 'simulation', 'noPID', 'stripping_line', 'decay', 'branches', 'year', 'mcdecay' have to - be specified first. Correct usage is to run 'ganga_options_generic.py'""") - -# don't use f-strings as not supported pre python 3.6! -print("Simulation = {0}".format(simulation)) -print("noPID = {0}".format(noPID)) -print("no_restrip = {0}".format(no_restrip)) -print("year = {0}".format(year)) -print("mcdecay descriptor = {0}".format(mcdecay)) -print("stripping stream = {0}".format(stripping_stream)) -print("stripping line = {0}".format(stripping_line)) -print("decay = {0}".format(decay)) -print("branches = {0}".format(branches)) - - -from Gaudi.Configuration import * -from LHCbKernel.Configuration import * -from DaVinci.Configuration import * -from DecayTreeTuple.Configuration import * - -from Configurables import DaVinci, DecayTreeTuple, MCDecayTreeTuple -from Configurables import TupleToolTISTOS -from Configurables import EventNodeKiller, ProcStatusCheck -from Configurables import LoKi__HDRFilter - -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration -from StrippingArchive.Utils import buildStreams -from StrippingArchive import strippingArchive - -############################################## - -print("\n## Determined stripping line to be: \n ===>", stripping_line) - -print("\n## config determined") -print("\n===> stream = ", stripping_stream) -print("\n===> line = ", stripping_line) -print("\n===> decay = ", decay) -print("\n===> branches = ", branches) -################################# -# ## Stream and stripping line ### -stream = stripping_stream -line = stripping_line - -########################### -# ## Restripping process ### - -# In the case that we are dealing with simulation, we may need to restrip due to the fact -# that the stripping version for the simulation is different (older) than that of the -# stripping line - -# In the case that we remove the PID requirements, this changes the restripping process -# since we edit the config file to remove these requirements - -if simulation == True: - if no_restrip == False: - event_node_killer = EventNodeKiller('StripKiller') - event_node_killer.Nodes = ['/Event/AllStreams', '/Event/Strip'] - #################### - if noPID == False: # conventional restrip - if year == '2016': - strip = 'stripping28r2p2' - elif year == '2017': - strip = 'stripping29r2p3' - elif year == '2018': - strip = 'stripping34r0p3' - - streams = buildStreams(stripping=strippingConfiguration(strip), - archive=strippingArchive(strip)) - - custom_stream = StrippingStream('AllStreams') - custom_line = 'Stripping'+line - - for stream in streams: - for sline in stream.lines: - if sline.name() == custom_line: - custom_stream.appendLines([sline]) - ##################### - else: # remove PID requirements and restrip - # in this case we need to edit the config to remove PID requirements - # different stripping versions for different years - if year == '2016': - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping28r2p2.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2017': - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping29r2p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - elif year == '2018': - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import B2XTauTauLeptonicConf as builder - from StrippingArchive.Stripping34r0p3.StrippingRD.StrippingB2XTauTauLeptonic import default_config as config - - # print the unedited config file - print("OLD CONFIG below") - print(config['CONFIG']) - print("OLD CONFIG above") - - # edit the config - config1 = config['CONFIG'] - config1['MuonPID'] = -1001 - config1['ElectronPID'] = -1001 - config1['UseNoPIDsHadrons'] = True - - # then print the edited config file - print("NEW CONFIG below") - print(config1) - print("NEW CONFIG above") - - lb = builder('B2XTauTauLeptonic', config1) - custom_stream = StrippingStream('MyStream') - # Now we have the stream and the line and can add the lines to the stream - target_line = 'Stripping' + line - for sline in lb.lines(): - if sline.name() == target_line: - custom_stream.appendLines([sline]) - ####################### - filterBadEvents = ProcStatusCheck() - sc = StrippingConf(Streams=[custom_stream], - MaxCandidates=10000, - AcceptBadEvents=False, - BadEventSelection=filterBadEvents) - - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/Phys/{0}/Particles'.format(line)] - else: # no restrip - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] - -else: # data rather than simulation - ### Fill tuple with DecayTreeTuple ### - dtt = DecayTreeTuple('DecayTreeTuple') - dtt.Inputs = ['/Event/{0}/Phys/{1}/Particles'.format(stream,line)] -######################################## -# ## Define decay and create branches ### -dtt.Decay = decay -dtt.addBranches(branches) - -###################### -# ## Add tupletools ### -# # Generic tupletools ## -dtt.ToolList = [] #reset toollist to add verbose to geometry/kinematic - -SubMassTool = dtt.addTupleTool('TupleToolSubMass') - -# -# will create Sum_{p=2,max) C(N,p) new entries in the nTuple called [head]_M[ij...] -# Particle daughters are sorted by PID at each branch of the tree (cc-independant) -# -#**** Substitution property -# -# usage : TupleTool.Substitution += ["pi+ => K+"] TupleTool.Substitution += ["K+ => pi+"] -# produce alternative mass with substituted PID pi<->K (cc is assumed) -# -#-change only one pion (K) at once in case of several pion (K) in the decay tree (producing separate output par pion (K) ) -# -#**** DoubleSubstitution property -# -# usage : TupleTool.DoubleSubstitution += ["K+/pi- => pi+/K-"] TupleTool.DoubleSubstitution += ["K+/K-" => pi+/pi-"] -# change all [K+pi-]cc ([K+K-]cc) pairs to (pi+K-)cc ([pi+pi-]cc) -# change only one pair at once in case of several pairs in the decay tree (producing separate output per pair) -# -# "/" separator is not mandatory : K+pi- syntax is allowed (just a bit slower to parse) - - -GeometryTool = dtt.addTupleTool('TupleToolGeometry') #Fill geometry related information for DecayTreeTuple -GeometryTool.Verbose=True -# head_MINIP : minimum impact parameter on any PV -# head_MINIPCHI2 : minimum chi2 IP on all PVs -# head_ENDVERTEX_[X|Y|Z] : decay vertex position for composite particles -# head_ENDVERTEX_[X|Y|Z]ERR : decay vertex position error estimate for composite particles -# head_ENDVERTEX_CHI2 : decay vertex chi2 -# head_ENDVERTEX_NDOF : decay vertex nDoF -# head_OWNPV_[X|Y|Z] : related primary vertex position -# head_OWNPV_[X|Y|Z]ERR : related primary vertex position error estimate for composite particles -# head_OWNPV_CHI2 : related primary vertex chi2 -# head_OWNPV_NDOF : related primary vertex nDoF -# head_IP_OWNPV : impact parameter with respect to the PhysDesktop::relatedVertex() considered particle -# head_IPCHI2_OWNPV : impact parameter chi2 with respect to the relatedVertex() considered particle -# head_FD_OWNPV : flight distance of composite particle wrt. the relatedVertex() considered particle -# head_FDCHI2_OWNPV : flight distance significance in units of chi2 wrt. the relatedVertex() considered particle -# head_DIRA_OWNPV : direction angle wrt. the PhysDesktop::relatedVertex() considered particle - -# Verbose being true gives: -# head_TOPPV_[X|Y|Z] : PhysDesktop::relatedVertex() of the top of decay chain position -# head_TOPPV_[X|Y|Z]ERR : PhysDesktop::relatedVertex() of the top of decay chain position error estimate -# head_TOPPV_CHI2 : PhysDesktop::relatedVertex() of the top of decay chain chi2 -# head_TOPPV_NDOF : PhysDesktop::relatedVertex() of the top of decay chain nDoF -# head_IP_TOPPV : impact parameter with respect to the PhysDesktop::relatedVertex() of the top of decay chain -# head_IPCHI2_TOPPV : impact parameter chi2 with respect to the relatedVertex() of the top of decay chain -# head_FD_TOPPV : flight distance of composite particle wrt. the relatedVertex() of the top of decay chain -# head_FDCHI2_TOPPV : flight distance significance in units of chi2 wrt. the PhysDesktop::relatedVertex() of the top of decay chain -# head_DIRA_TOPPV : direction angle wrt. the relatedVertex() of the top of decay chain -# head_ORIVX_[X|Y|Z] : ancestor's related primary vertex position (when applicable) -# head_ORIVX_[X|Y|Z]ERR : ancestor's related primary vertex position error estimate (when applicable) -# head_ORIVX_CHI2 : ancestor's related primary vertex chi2 (when applicable) -# head_ORIVX_NDOF : ancestor's related primary vertex nDoF (when applicable) -# head_IP_ORIVX : impact parameter with respect to the ancestor's vertex (when applicable) -# head_IPCHI2_ORIVX : impact parameter chi2 with respect to the ancestor's vertex (when applicable) -# head_FD_ORIVX : flight distance of composite particle wrt. the ancestor's vertex (when applicable) -# head_FDCHI2_ORIVX : flight distance significance in units of chi2 wrt. ancestor's vertex (when applicable) -# head_DIRA_ORIVX : direction angle wrt. ancestor's vertex (when applicable) - -KinematicTool = dtt.addTupleTool('TupleToolKinematic') #Fill kinematic information for DecayTreeTuple -KinematicTool.Verbose=True -# head_P : momentum's amplitude -# head_PT : transverse momentum -# head_P[E|X|Y|Z] : four vector momentum -# head_MM : measured mass (or assigned mass in case of 'basic' particle -# head_M : mass calculated from momentum four-vector -# head_MMERR : error on the measured mass (only for non-basic parts) - -# Verbose being true gives: -# head_REFP[X|Y|Z]: one point the particle momentum extrapolation goes through -# head_PreFitMass: Mass of 4-vectors of daughters, not yet extrapolated to the head decay vertex (only for composites). -# This is the quantity used in ADAMASS or AM in CombineParticles.CombinationCut -# prefix_AtVtx_P[X|Y|Z]: momentum information of basic particles at origin vertex position - -TrackInfoTool = dtt.addTupleTool('TupleToolTrackInfo') #Fill track information for DecayTreeTuple -TrackInfoTool.Verbose=True -# X_TRACK_CHI2NDOF : track chi2/ndof -# X_TRACK_TYPE : track type -# X_TRACK_PCHI2 : track Chi2 probability -# X_TRACK_GhostProb : Ghost probability (run NeuralNetTmva to fill it) -# X_TRACK_CloneDist : Only available for 2009 data - -# Verbose being true gives: -# X_TRACK_CHI2 : track chi2 -# X_TRACK_NDOF : track ndof -# X_TRACK_VeloCHI2NDOF : Track fit velo chi2/nDoF -# X_TRACK_TCHI2NDOF : Track fit T chi2/nDoF -# X_TRACK_VELO_UTID : hopefully unique double constructed from multiplying all Velo hit IDs -# X_TRACK_TT_UTID : hopefully unique double constructed from multiplying all TT hit IDs -# X_TRACK_IT_UTID : hopefully unique double constructed from multiplying all IT hit IDs -# X_TRACK_OT_UTID : hopefully unique double constructed from multiplying all OT hit IDs -# X_TRACK_VP_UTID : hopefully unique double constructed from multiplying all VP hit IDs -# X_TRACK_UT_UTID : hopefully unique double constructed from multiplying all UT hit IDs -# X_TRACK_FT_UTID : hopefully unique double constructed from multiplying all FT hit IDs -# X_TRACK_nVeloHits : Number of Velo hits on the track -# X_TRACK_nVeloRHits : Number of Velo R hits on the track -# X_TRACK_nVeloPhiHits : Number of Velo phi hits on the track -# X_TRACK_nVeloPileUpHits : Number of Velo pile-up hits on the track -# X_TRACK_nTTHits : Number of TT hits on the track -# X_TRACK_nITHits : Number of IT hits on the track -# X_TRACK_nOTHits : Number of OT hits on the track -# X_TRACK_nVPHits : Number of VP hits on the track -# X_TRACK_nUTHits : Number of UT hits on the track -# X_TRACK_nFTHits : Number of FT hits on the track -# X_TRACK_FirstMeasurementX: x position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementY: y position of state at 'FirstMeasurement' -# X_TRACK_FirstMeasurementZ: z position of state at 'FirstMeasurement' -# X_TRACK_History: Algorithm which the track was made with -# X_TRACK_qOverp : q/p of state at 'FirstMeasurement' -# X_TRACK_Tx : x slope of state at 'FirstMeasurement' -# X_TRACK_Ty : y slope of state at 'FirstMeasurement' - -EventInfoTool = dtt.addTupleTool('TupleToolEventInfo') #Event and Run number for DecayTreeTuple -EventInfoTool.Verbose=True -# runNumber: well, the run number -# eventNumber: -# BCID and BC type -# Odin and Hlt TCKs -# GPS time -# If the property Mu is given it will fill the Mu of the run. A working dictionary can be -# found at https://twiki.cern.ch/twiki/bin/view/LHCb/NuMuPileUp - -# if Verbose is on, also gps time in year,month,day,hour,min,second Note that months are -# numbered [0-11]. That's a convention. Sorry. - -PropertimeTool = dtt.addTupleTool('TupleToolPropertime') #Fills the propertime for DecayTreeTuple -# PropertimeTool.Verbose=True -# head_TAU -# head_TAUERR -# head_TAUCHI2 - -RecoStatsTool = dtt.addTupleTool('TupleToolRecoStats') #Fills Reco stats, from RecSummary. -# RecoStatsTool.Verbose=True - -PidTool = dtt.addTupleTool('TupleToolPid') #DLL and PID information to be stored in a Tuple -# PidTool.Verbose=True -# head_ID : particleID().pid(); -# For the long lived particles (isBasicParticle()). -# head_PIDe : LHCb::ProtoParticle::CombDLLe -# head_PIDmu : LHCb::ProtoParticle::CombDLLmu -# head_PIDK : LHCb::ProtoParticle::CombDLLk -# head_PIDp : LHCb::ProtoParticle::CombDLLp - -ANNPIDTool = dtt.addTupleTool('TupleToolANNPID') #ProbNN values for "Electron", "Muon", "Pion", "Kaon", "Proton", "Ghost" -# ANNPIDTool.Verbose=True - -AnglesTool = dtt.addTupleTool('TupleToolAngles') #Fill MC Particle with decay angle in mother frame -# AnglesTool.Verbose=True -# head_CosTheta : angle in mother's frame -# if WRTMother is false, will calculate angle in frame of top of tree - -PrimariesTool = dtt.addTupleTool('TupleToolPrimaries') #Primary vertices properties for DecayTreeTuple -# PrimariesTool.Verbose=True -# coordinates PVX, PVY, PVZ -# errors PVXERR, PVYERR, PVZERR -# vertex chi2 PVCHI -# vertex ndf PVNDOF -# Nb of tracks used to do the vertex PVNTRACKS - -## Isolation variables ## - -# cone isolation # -ConeIsoToolmother = dtt.mother.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolmother.MinConeSize = 0.5 -ConeIsoToolmother.MaxConeSize = 0.9 -ConeIsoToolmother.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolmother.FillAsymmetry = True -ConeIsoToolmother.FillDeltas = True -ConeIsoToolmother.FillComponents = True -# also fill intermediate hadron branch -ConeIsoToolinter = dtt.inter.addTupleTool('TupleToolConeIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -ConeIsoToolinter.MinConeSize = 0.5 -ConeIsoToolinter.MaxConeSize = 0.9 -ConeIsoToolinter.SizeStep = 0.2 -# Fill asymmetry, delta, and component variables -ConeIsoToolinter.FillAsymmetry = True -ConeIsoToolinter.FillDeltas = True -ConeIsoToolinter.FillComponents = True - -# head_cc: charged cone -# head_nc: neutral cone - -# head_XX_mult : number of objects inside the cone -# head_XX_sPT : scalar-summed pT of the objects inside the cone -# head_XX_vPT : vector-summed pT of the objects inside the cone -# head_XX_P : x, y and z components of the cone momentum -# head_XX_asy_P : momentum asymmetry between the head and the cone defined as (head_P - head_XX_P) / (head_P + head_XX_P) -# head_XX_asy_P : x, y, z and transverse components of the momentum asymmetry -# head_XX_deltaEta : difference in eta between the head and the cone -# head_XX_deltaPhi : difference in phi between the head and the cone -# head_XX_IT : transverse isolation of the head in the cone, defined as head_PT / (head_P + head_XX_P)_T -# head_IT : transverse isolation of the head in the charged and neutral cones, defined as head_PT / (head_P + head_cc_P + head_nc_P)_T -# head_cc_maxPt_Q : charge of the max-pT object in the charged cone -# head_XX_maxPt_P : x, y, z (and e) components of the max-pT object momentum in the cone -# head_MasshPi0: invariant mass of the seed-Pi0 combinations -# head_Pi0_DeltaR: DeltaR between the seed and the pi0 directions -# head_Pi0_E, head_Pi0_PX, head_Pi0_PY, head_Pi0_PZ: four momentum of the pi0 -# head_Pi0_M: invariant mass of the pi0 -# head_Pi0Ph1_CL, head_Pi0Ph2_CL: confidence levels of the (photon) pi0 daughters - -# track isolation # -TrackIsoToolmother = dtt.mother.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolmother.MinConeAngle = 0.5 -TrackIsoToolmother.MaxConeAngle = 0.9 -TrackIsoToolmother.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolmother.FillAsymmetry = True -TrackIsoToolmother.FillDeltaAngles = True -# also fill intermediate hadron branch -TrackIsoToolinter = dtt.inter.addTupleTool('TupleToolTrackIsolation') -# choose cones to have a deltaR of 0.5, 0.7, 0.9 radians -TrackIsoToolinter.MinConeAngle = 0.5 -TrackIsoToolinter.MaxConeAngle = 0.9 -TrackIsoToolinter.StepSize = 0.2 -# fill asymmetry and DeltaAngles variables -TrackIsoToolinter.FillAsymmetry = True -TrackIsoToolinter.FillDeltaAngles = True - -# Open up a cone around head, exclude all tracks that are in the decay descriptor -# (i.e. that belong to the decay you are looking for), build the variables with -# the remaining tracks. - -# head_cmult : Number of tracks inside cone. -# head_cp : Summed p inside cone -# head_cpt : Summed pt inside cone -# head_cpx : Summed px inside cone -# head_cpy : Summed py inside cone -# head_cpz : Summed pz inside cone - -# If Verbose, or other flags are set: - -# Asymmetry variables - -# head_pasy : (head_P - head_cp)/(head_P + head_cp) -# head_ptasy : (head_PT - head_cpt)/(head_PT + head_cpt) -# head_pxasy : (head_Px - head_cpx)/(head_Px + head_cpx) -# head_pyasy : (head_Py - head_cpy)/(head_Py + head_cpy) -# head_pzasy : (head_Pz - head_cpz)/(head_Pz + head_cpz) Delta angle variables -# head_DeltaEta : Difference in eta between summed tracks and head -# head_DeltaPhi : Difference in phi between summed tracks and head - - -# MinConeAngle: Set the minimal deltaR of the cone (default = 0.5), in radians -# MaxConeAngle: Set the maximum deltaR of the cone (default = 1.0), in radians -# StepSize: Set the step of deltaR between two iterations (default = 0.1), in radians -# TrackType: Set the type of tracks which are considered inside the cone (default = 3) -# FillAsymmetry: Flag to fill the asymmetry variables (default = false) -# FillDeltaAngles: Flag to fill the delta angle variables (default = false) - -# vertex isolation # -# intermediate hadron is more likely to have a much tighter vertex than the mother but fill both -VtxIsoToolmother = dtt.mother.addTupleTool('TupleToolVtxIsoln') -VtxIsoToolinter = dtt.inter.addTupleTool('TupleToolVtxIsoln') - -# head_NOPARTWITHINDCHI2WDW : no. of non-signal particles that when added to vertex give delta chi2 < specified window -# head_NOPARTWITHINCHI2WDW : no. of non-signal particles that when added to vertex give chi2 < specified window -# head_SMALLESTCHI2: chi2 of smallest chi2 combination with any of the input Particles -# head_SMALLESTDELTACHI2: delta chi2 of smallest delta chi2 combination with any of the input Particles -#### updates: -# (head)_NumVtxWithinChi2WindowOneTrack: number of particles that generate a vertex within a chi2 window -# (head)_SmallestDeltaChi2OneTrack: smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassOneTrack: mass of the candidate with the smallest delta chi2 -# (head)_SmallestDeltaChi2TwoTracks: smallest delta chi2 when adding one track to the combination -# that has the smallest delta chi2 when adding one track -# (head)_SmallestDeltaChi2MassTwoTracks: mass of the candidate with the smallest delta chi2 when adding -# one track to the combination that has the smallest delta chi2 when adding one track - -## Hybrid tupletool ## -all_hybrid = dtt.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_All') -all_hybrid.Variables = { - 'ETA' : "ETA", #pseudorapidity - 'PHI' : "PHI", #asimuthal angle - 'MINIPCHI2' : "MIPCHI2DV(PRIMARY)", - #The special version of LoKi::Particles::MinImpParChi2 functor which gets all the primary - #vertices from desktop. - 'MINIP' : "MIPDV(PRIMARY)", - #The special version of LoKi::Particles::MinImpPar functor which gets all the primary - #vertices from desktop. - 'IPCHI2_OWNPV' : "BPVIPCHI2()", - #The special "context-dependent" version of LoKi::Particles::ImpParChi2 functor which gets - #the related primary vertex from IPhysDesktop tool - 'IP_OWNPV' : "BPVIP()", - #The special "context-dependent" version of LoKi::Particles::ImpPar functor which gets the - #related primary vertex from IPhysDesktop tool. - 'DIRA_OWNPV' : "BPVDIRA", - 'ghost' : "TRGHP", #simple evaluator of "ghost probability" - 'TrackCHI2DOF' : 'TRCHI2DOF', - 'FD_CHI2' : "BPVVDCHI2", - #BPV = Adaptor to "best-primary-vertex", VDCHI2 = Evaluator of the chi2 of GEOMETRY distance - #between the particle "endVertex" and "the vertex". - 'VCHI2DOF' : 'VFASPF(VCHI2/VDOF)', - # #Decay tree fitter functions: - # 'DTF_CHI2NDOF' : "DTF_CHI2NDOF( True )", - # #Simple evaluator of $\chi^2$ per degree of freedom for the decay tree fit. - # 'DTF_VCHI2NDOF' : "DTF_FUN ( VFASPF(VCHI2/VDOF) , True )", - # #VCHI2 = evaluator of the Chi2 of the vertex / VDOF = evaluator of the number of degrees - # #of freedom for the vertex - # 'DTF_MASS_JpsiConstr' : "DTF_FUN ( M , True , 'J/psi(1S)' )" , - # 'DTF_MASS' : "DTF_FUN ( M , True )" , - # 'DTF_CTAU"' : "DTF_CTAU( 0, True )", - # #Evaluate $c\tau$ for the dauthter particle in the decay tree. - # 'DTF_CTAUS' : "DTF_CTAUSIGNIFICANCE( 0, True )" - # #Evaluate $ \frac{c\tau}{\sigma \left( c\tau\right) } $ for the dauthter particle - # #in the decay tree. -} - -lb_hybrid = dtt.mother.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_Lb') -lb_hybrid.Variables = { - 'DOCAjpsiinter' : "DOCA(1,2)", - 'DOCAmotherjpsi' : "DOCA(0,1)", - 'DOCAmotherinter' : "DOCA(0,2)", - 'DOCAjpsiinterCHI2' : "DOCACHI2(1,2)", - 'DOCAmotherjpsiCHI2' : "DOCACHI2(0,1)", - 'DOCAmotherinterCHI2' : "DOCACHI2(0,2)" -} -jpsi_hybrid = dtt.jpsi.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_jpsi') -jpsi_hybrid.Variables = { - 'DOCAd1d2' : "DOCA(1,2)", - 'DOCAjpsid1' : "DOCA(0,1)", - 'DOCAjpsid2' : "DOCA(0,2)", - 'DOCAd1d2CHI2' : "DOCACHI2(1,2)", - 'DOCAjpsid1CHI2' : "DOCACHI2(0,1)", - 'DOCAjpsid2CHI2' : "DOCACHI2(0,2)" -} -inter_hybrid = dtt.inter.addTupleTool('LoKi::Hybrid::TupleTool/LoKi_inter') -inter_hybrid.Variables = { - #note that the end vertex of the intermediate hadron is also the end vertex of the lb - 'DOCAh1h2' : "DOCA(1,2)", - 'DOCAmotherh1' : "DOCA(0,1)", - 'DOCAmotherh2' : "DOCA(0,2)", - 'DOCAh1h2CHI2' : "DOCACHI2(1,2)", - 'DOCAmotherh1CHI2' : "DOCACHI2(0,1)", - 'DOCAmotherh2CHI2' : "DOCACHI2(0,2)" -} - -################ -### Triggers ### -# Add trigger list # - -L0Triggers = ['L0MuonDecision','L0DiMuonDecision','L0HadronDecision'] -Hlt1Triggers = [# muon lines - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - # dimuon lines - 'Hlt1DiMuonHighMassDecision','Hlt1DiMuonLowMassDecision', - # MVA lines - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - 'Hlt1TwoTrackMVALooseDecision','Hlt1TwoTrackMVADecision' - ] -Hlt2Triggers = [# topo lines - 'Hlt2Topo2BodyDecision','Hlt2Topo3BodyDecision','Hlt2Topo4BodyDecision', - 'Hlt2TopoMu2BodyDecision','Hlt2TopoMu3BodyDecision','Hlt2TopoMu4BodyDecision', - 'Hlt2TopoMuMu2BodyDecision','Hlt2TopoMuMu3BodyDecision','Hlt2TopoMuMu4BodyDecision', - # muon lines - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision','Hlt2SingleMuonLowPTDecision', - 'Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision', - # dimuon lines - 'Hlt2DiMuonDecision','Hlt2DiMuonJPsiDecision','Hlt2DiMuonDetachedDecision', - 'Hlt2DiMuonDetachedHeavyDecision','Hlt2DiMuonDetachedJPsiDecision', - 'Hlt2DiMuonDetachedPsi2SDecision','Hlt2DiMuonSoftDecision' - ] -# Electrons in Sel -if '_E_' in stripping_line or '_MuE_' in stripping_line or '_EPi_' in stripping_line: - L0Triggers += ["L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision"] - Hlt1Triggers += ["Hlt1SingleElectronNoIPDecision"] - Hlt2Triggers += ["Hlt2TopoE2BodyDecision","Hlt2TopoE3BodyDecision","Hlt2TopoE4BodyDecision", - "Hlt2TopoEE2BodyDecision","Hlt2TopoEE3BodyDecision","Hlt2TopoEE4BodyDecision", - "Hlt2TopoMuE2BodyDecision","Hlt2TopoMuE3BodyDecision","Hlt2TopoMuE4BodyDecision" - ] - -AllTriggers = L0Triggers + Hlt1Triggers + Hlt2Triggers - -MuonTriggers = [# L0 - 'L0MuonDecision', - # Hlt1 - 'Hlt1TrackMuonDecision','Hlt1SingleMuonNoIPDecision','Hlt1SingleMuonHighPTDecision', - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision','Hlt1TrackMuonMVADecision', - # Hlt2 - 'Hlt2SingleMuonDecision','Hlt2SingleMuonHighPTDecision', - 'Hlt2SingleMuonLowPTDecision','Hlt2SingleMuonRareDecision','Hlt2SingleMuonVHighPTDecision' - ] -HadronTriggers = [# L0 - 'L0HadronDecision', - # Hlt1 - 'Hlt1TrackMVADecision','Hlt1TrackMVALooseDecision' - ] -ElectronTriggers = [# L0 - "L0ElectronDecision","L0ElectronHiDecision","L0PhotonDecision","L0PhotonHiDecision", - # Hlt1 - "Hlt1SingleElectronNoIPDecision","Hlt1TrackMVADecision"] - -# TupleToolTISTOS # -# It saves the trigger TIS/TOS decisions for each particle for each Hlt Selection -dtt.mother.ToolList += [ "TupleToolTISTOS" ] -dtt.mother.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.mother.TupleToolTISTOS.Verbose = True -dtt.mother.TupleToolTISTOS.TriggerList = AllTriggers -dtt.d2.ToolList += [ "TupleToolTISTOS" ] -dtt.d2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d2.TupleToolTISTOS.Verbose = True -dtt.d2.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.d1.ToolList += [ "TupleToolTISTOS" ] -dtt.d1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.d1.TupleToolTISTOS.Verbose = True -dtt.d1.TupleToolTISTOS.TriggerList = HadronTriggers -dtt.h1.ToolList += [ "TupleToolTISTOS" ] -dtt.h1.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h1.TupleToolTISTOS.Verbose = True -if '_Mu_' in stripping_line or '_MuE_' in stripping_line or '_MuPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = MuonTriggers -elif '_EPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_PiPi_' in stripping_line: - dtt.h1.TupleToolTISTOS.TriggerList = HadronTriggers -# else: # TODO remove -# print('LOCAL: ERROR WITH h1 TRIGGER ASSIGNMENT') - -dtt.h2.ToolList += [ "TupleToolTISTOS" ] -dtt.h2.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" ) -dtt.h2.TupleToolTISTOS.Verbose = True -if '_E_' in stripping_line or '_MuE_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = ElectronTriggers -elif '_EPi_' in stripping_line or '_PiPi_' in stripping_line: - dtt.h2.TupleToolTISTOS.TriggerList = HadronTriggers - -## MC truth value tupletools ## -if simulation == True: - MCTruthTool = dtt.addTupleTool('TupleToolMCTruth') #Fill MC truth info if a link is present - # head_TRUEID : true pid - MCTruthTool.ToolList = [ - "MCTupleToolKinematic", - # head_TRUEP[E|X|Y|Z] : true four vector momentum - # head_TRUEPT : true transverse momentum, PT - # head_TRUEORIGINVERTEX_[X|Y|Z] : position of the true origin vertex. - # head_TRUEENDVERTEX_[X|Y|Z] : position of the true end vertex (the first one) - # head_TRUEISSTABLE : MCAssociate has no daughters. - # head_TRUETAU : true propertime - "MCTupleToolHierarchy", - # head_MC_MOTHER_ID : true mc mother ID - # head_MC_MOTHER_KEY : true mc mother key - # head_MC_GD_MOTHER_ID : grand mother ID - # head_MC_GD_MOTHER_KEY : grand mother key - # head_MC_GD_GD_MOTHER_ID : grand grand mother ID - # head_MC_GD_GD_MOTHER_KEY : grand grand mother key - ] - - ## Hybrid tupletool ## - hybrid_mc_dtt = dtt.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_dtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - - MCBackgroundInfoTool = dtt.addTupleTool('TupleToolMCBackgroundInfo') #Fill the info from IBackgroundCategory. - # head_BKGCAT : category - - # add mcdecaytreetuple - - def Make_MCTuple(decay): - MCTuple = MCDecayTreeTuple("MCDecayTreeTuple") - - MCTuple.Decay = decay - MCTuple.setDescriptorTemplate( decay ) - MCTuple.ToolList = [ - "MCTupleToolKinematic" - , "MCTupleToolHierarchy" - , "MCTupleToolAngles" - , "MCTupleToolPID" - , "TupleToolEventInfo" - , "TupleToolRecoStats" - ] - ## Hybrid tupletool ## - hybrid_mc_mcdtt = MCTuple.addTupleTool('LoKi::Hybrid::MCTupleTool/LoKi_All_MC') - hybrid_mc_mcdtt.Variables = { - 'MCETA' : "MCETA", #pseudorapidity - 'MCPHI' : "MCPHI", #asimuthal angle - } - return MCTuple - - - MCTuple = Make_MCTuple(mcdecay) - -######################### -# ## Configure DaVinci ### -from Configurables import GaudiSequencer -MySequencer = GaudiSequencer('Sequence') -if simulation == True: - MySequencer.Members = [event_node_killer, sc.sequence(), dtt, MCTuple] - # MySequencer.Members = [event_node_killer, sc.sequence(),dtt] -else: - MySequencer.Members = [dtt] - -DaVinci().UserAlgorithms += [MySequencer] -DaVinci().EvtMax = -1 -DaVinci().PrintFreq = 1000 diff --git a/lbtopktautau/info.yaml b/lbtopktautau/info.yaml index e7e702355e..602080acb4 100644 --- a/lbtopktautau/info.yaml +++ b/lbtopktautau/info.yaml @@ -5,315 +5,39 @@ defaults: - lmadhanm@hep.phy.cam.ac.uk - joshua.james.bex@cern.ch automatically_configure: 'True' -MD_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: +MD_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu: application: DaVinci/v46r5 input: bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST options: - - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py -MU_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py +MU_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu: application: DaVinci/v46r5 input: bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST options: - - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py -MD_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST - options: - - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py -MU_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST - options: - - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py -MD_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST - options: - - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py -MU_2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision16/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco16/Stripping28r2p2/90000000/SEMILEPTONIC.DST - options: - - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py -MD_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST - options: - - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py -MU_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST - options: - - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py -MD_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST - options: - - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py -MU_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST - options: - - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py -MD_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: + - 2016_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py +MD_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu: application: DaVinci/v46r5 input: bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST options: - - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py -MU_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: + - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py +MU_2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu: application: DaVinci/v46r5 input: bk_query: /LHCb/Collision17/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco17/Stripping29r2p3/90000000/SEMILEPTONIC.DST options: - - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py -MD_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + - 2017_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py +MD_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu: application: DaVinci/v46r5 input: bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST options: - - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py -MU_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp: + - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py +MU_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu: application: DaVinci/v46r5 input: bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST options: - - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDp.py -MD_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST - options: - - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py -MU_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST - options: - - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDK.py -MD_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagDown/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST - options: - - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py -MU_2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu: - application: DaVinci/v46r5 - input: - bk_query: /LHCb/Collision18/Beam6500GeV-VeloClosed-MagUp/Real Data/Reco18/Stripping34r0p3/90000000/SEMILEPTONIC.DST - options: - - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDMu.py -MD_2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15514042/PKTAUTAU.STRIP.DST - options: - - 2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py -MU_2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15514042/PKTAUTAU.STRIP.DST - options: - - 2018_LbtopKtautau_mumu_mc_signal-filt_Lb2pK_Mu.py -MD_2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15596900/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py -MU_2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15596900/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoDDpK_DtoK0munu_DtoK0munu_mc_background-filt_Lb2pK_Mu.py -MD_2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576040/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py -MU_2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576040/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoLcphimunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py -MD_2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576041/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py -MU_2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576041/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoLcphitaunu_LctopKmunu_phitoKK_mc_background-filt_Lb2pK_Mu.py -MD_2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576050/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py -MU_2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576050/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoDppimunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py -MD_2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576051/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py -MU_2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15576051/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoDppitaunu_Kpimunu_mc_background-filt_Lb2pK_Mu.py -MD_2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/16574050/PKTAUTAU.STRIP.DST - options: - - 2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py -MU_2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/16574050/PKTAUTAU.STRIP.DST - options: - - 2018_XibtoXicmunu_pKmunu_mc_background-filt_Lb2pK_Mu.py -MD_2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/16574051/PKTAUTAU.STRIP.DST - options: - - 2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py -MU_2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/16574051/PKTAUTAU.STRIP.DST - options: - - 2018_XibtoXictaunu_pKmunu_mc_background-filt_Lb2pK_Mu.py -MD_2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574401/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py -MU_2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574401/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoD0ptaunu_Kmunupi0_mc_background-filt_Lb2pK_Mu.py -MD_2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574037/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py -MU_2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574037/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoD0pmunu_Kmunu_mc_background-filt_Lb2pK_Mu.py -MD_2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574039/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py -MU_2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim10d/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p3Filtered/15574039/PKTAUTAU.STRIP.DST - options: - - 2018_LbtoD0ptaunu_Kmunu_mc_background-filt_Lb2pK_Mu.py -MD_2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09k/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/13144041/ALLSTREAMS.DST - options: - - 2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py -MU_2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2016/Beam6500GeV-2016-MagUp-Nu1.6-25ns-Pythia8/Sim09k/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/13144041/ALLSTREAMS.DST - options: - - 2016_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py -MD_2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2017/Beam6500GeV-2017-MagDown-Nu1.6-25ns-Pythia8/Sim09k/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2p1NoPrescalingFlagged/13144041/ALLSTREAMS.DST - options: - - 2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py -MU_2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2017/Beam6500GeV-2017-MagUp-Nu1.6-25ns-Pythia8/Sim09k/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2p1NoPrescalingFlagged/13144041/ALLSTREAMS.DST - options: - - 2017_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py -MD_2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim09k/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p1NoPrescalingFlagged/13144041/ALLSTREAMS.DST - options: - - 2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py -MU_2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim09k/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34r0p1NoPrescalingFlagged/13144041/ALLSTREAMS.DST - options: - - 2018_BstoKKjpsi_mumu_mc_background_Lb2pK_Mu.py -MD_2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2016/Beam6500GeV-2016-MagDown-Nu1.6-25ns-Pythia8/Sim09l/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/11144001/ALLSTREAMS.DST - options: - - 2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py -MU_2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2016/Beam6500GeV-2016-MagUp-Nu1.6-25ns-Pythia8/Sim09l/Trig0x6139160F/Reco16/Turbo03a/Stripping28r2NoPrescalingFlagged/11144001/ALLSTREAMS.DST - options: - - 2016_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py -MD_2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2017/Beam6500GeV-2017-MagDown-Nu1.6-25ns-Pythia8/Sim09l/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2NoPrescalingFlagged/11144001/ALLSTREAMS.DST - options: - - 2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py -MU_2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2017/Beam6500GeV-2017-MagUp-Nu1.6-25ns-Pythia8/Sim09l/Trig0x62661709/Reco17/Turbo04a-WithTurcal/Stripping29r2NoPrescalingFlagged/11144001/ALLSTREAMS.DST - options: - - 2017_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py -MD_2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagDown-Nu1.6-25ns-Pythia8/Sim09l/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34NoPrescalingFlagged/11144001/ALLSTREAMS.DST - options: - - 2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py -MU_2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu: - application: DaVinci/v44r11p6 - input: - bk_query: /MC/2018/Beam6500GeV-2018-MagUp-Nu1.6-25ns-Pythia8/Sim09l/Trig0x617d18a4/Reco18/Turbo05-WithTurcal/Stripping34NoPrescalingFlagged/11144001/ALLSTREAMS.DST - options: - - 2018_BtoKstjpsi_mumu_KsttoKpi_mc_background_Lb2pK_Mu.py + - 2018_LbtopKtautau_data_Lb2pK_Mu_ReversePIDmu.py -- GitLab