Belle II Software light-2409-toyger
059_vertex_fitting.py
1#!/usr/bin/env python3
2
3import sys
4import basf2 as b2
5import modularAnalysis as ma
6import stdV0s
7import flavorTagger as ft
8from variables import variables as vm # shorthand for VariableManager
9import variables.collections as vc
10import variables.utils as vu
11import vertex
12
13# get input file number from the command line
14filenumber = sys.argv[1]
15
16# set analysis global tag (needed for flavor tagging)
17b2.conditions.prepend_globaltag(ma.getAnalysisGlobaltag())
18
19# create path
20main = b2.Path()
21
22# load input data from mdst/udst file
23ma.inputMdstList(
24 filelist=[b2.find_file(f"starterkit/2021/1111540100_eph3_BGx0_{filenumber}.root", "examples")],
25 path=main,
26)
27
28# fill final state particle lists
29ma.fillParticleList(
30 "e+:uncorrected",
31 "electronID > 0.1 and dr < 0.5 and abs(dz) < 2 and thetaInCDCAcceptance",
32 path=main,
33)
34stdV0s.stdKshorts(path=main)
35
36# apply Bremsstrahlung correction to electrons
37vm.addAlias(
38 "goodFWDGamma", "passesCut(clusterReg == 1 and clusterE > 0.075)"
39)
40vm.addAlias(
41 "goodBRLGamma", "passesCut(clusterReg == 2 and clusterE > 0.05)"
42)
43vm.addAlias(
44 "goodBWDGamma", "passesCut(clusterReg == 3 and clusterE > 0.1)"
45)
46vm.addAlias(
47 "goodGamma", "passesCut(goodFWDGamma or goodBRLGamma or goodBWDGamma)"
48)
49ma.fillParticleList("gamma:brems", "goodGamma", path=main)
50ma.correctBrems("e+:corrected", "e+:uncorrected", "gamma:brems", path=main)
51vm.addAlias("isBremsCorrected", "extraInfo(bremsCorrected)")
52
53# combine final state particles to form composite particles
54ma.reconstructDecay(
55 "J/psi:ee -> e+:corrected e-:corrected ?addbrems",
56 cut="abs(dM) < 0.11",
57 path=main,
58)
59
60# perform vertex fit of J/psi candidates
61vertex.kFit("J/psi:ee", conf_level=0.0, path=main)
62
63# combine J/psi and KS candidates to form B0 candidates
64ma.reconstructDecay(
65 "B0 -> J/psi:ee K_S0:merged",
66 cut="Mbc > 5.2 and abs(deltaE) < 0.15",
67 path=main,
68)
69
70# match reconstructed with MC particles
71ma.matchMCTruth("B0", path=main)
72
73# build the rest of the event
74ma.buildRestOfEvent("B0", fillWithMostLikely=True, path=main)
75track_based_cuts = "thetaInCDCAcceptance and pt > 0.075 and dr < 5 and abs(dz) < 10"
76ecl_based_cuts = "thetaInCDCAcceptance and E > 0.05"
77roe_mask = ("my_mask", track_based_cuts, ecl_based_cuts)
78ma.appendROEMasks("B0", [roe_mask], path=main)
79
80# call flavor tagging
81ft.flavorTagger(["B0"], path=main)
82
83# fit B vertex on the tag-side
84vertex.TagV("B0", fitAlgorithm="Rave", path=main)
85
86# perform best candidate selection
87b2.set_random_seed("Belle II StarterKit")
88ma.rankByHighest("B0", variable="random", numBest=1, path=main)
89
90# Create list of variables to save into the output file
91b_vars = []
92
93standard_vars = vc.kinematics + vc.mc_kinematics + vc.mc_truth
94b_vars += vc.deltae_mbc
95b_vars += standard_vars
96
97# ROE variables
98roe_kinematics = ["roeE()", "roeM()", "roeP()", "roeMbc()", "roeDeltae()"]
99roe_multiplicities = [
100 "nROE_Charged()",
101 "nROE_Photons()",
102 "nROE_NeutralHadrons()",
103]
104b_vars += roe_kinematics + roe_multiplicities
105# Let's also add a version of the ROE variables that includes the mask:
106for roe_variable in roe_kinematics + roe_multiplicities:
107 # e.g. instead of 'roeE()' (no mask) we want 'roeE(my_mask)'
108 roe_variable_with_mask = roe_variable.replace("()", "(my_mask)")
109 b_vars.append(roe_variable_with_mask)
110
111b_vars += ft.flavor_tagging
112b_vars += vc.tag_vertex + vc.mc_tag_vertex
113
114# Variables for final states (electrons, positrons, pions)
115fs_vars = vc.pid + vc.track + vc.track_hits + standard_vars
116b_vars += vu.create_aliases_for_selected(
117 fs_vars + ["isBremsCorrected"],
118 "B0 -> [J/psi -> ^e+ ^e-] K_S0",
119 prefix=["ep", "em"],
120)
121b_vars += vu.create_aliases_for_selected(
122 fs_vars, "B0 -> J/psi [K_S0 -> ^pi+ ^pi-]", prefix=["pip", "pim"]
123)
124# Variables for J/Psi, KS
125jpsi_ks_vars = vc.inv_mass + standard_vars
126jpsi_ks_vars += vc.vertex + vc.mc_vertex
127b_vars += vu.create_aliases_for_selected(jpsi_ks_vars, "B0 -> ^J/psi ^K_S0")
128# Add the J/Psi mass calculated with uncorrected electrons:
129vm.addAlias(
130 "Jpsi_M_uncorrected", "daughter(0, daughterCombination(M,0:0,1:0))"
131)
132b_vars += ["Jpsi_M_uncorrected"]
133# Also add kinematic variables boosted to the center of mass frame (CMS)
134# for all particles
135cmskinematics = vu.create_aliases(
136 vc.kinematics, "useCMSFrame({variable})", "CMS"
137)
138b_vars += vu.create_aliases_for_selected(
139 cmskinematics, "^B0 -> [^J/psi -> ^e+ ^e-] [^K_S0 -> ^pi+ ^pi-]"
140)
141
142vm.addAlias(
143 "withBremsCorrection",
144 "passesCut(passesCut(ep_isBremsCorrected == 1) or passesCut(em_isBremsCorrected == 1))",
145)
146b_vars += ["withBremsCorrection"]
147
148# Save variables to an output file (ntuple)
149ma.variablesToNtuple(
150 "B0",
151 variables=b_vars,
152 filename="Bd2JpsiKS.root",
153 treename="tree",
154 path=main,
155)
156
157# Start the event loop (actually start processing things)
158b2.process(main)
159
160# print out the summary
161print(b2.statistics)
def stdKshorts(prioritiseV0=True, fitter='TreeFit', path=None, updateAllDaughters=False, writeOut=False)
Definition: stdV0s.py:17
def kFit(list_name, conf_level, fit_type='vertex', constraint='', daughtersUpdate=False, decay_string='', massConstraint=[], recoilMass=0, smearing=0, path=None)
Definition: vertex.py:129
def TagV(list_name, MCassociation='', confidenceLevel=0., trackFindingType="standard_PXD", constraintType="tube", askMCInfo=False, reqPXDHits=0, maskName='all', fitAlgorithm='KFit', kFitReqReducedChi2=5.0, useTruthInFit=False, useRollBack=False, path=None)
Definition: vertex.py:319