Belle II Software development
ConvertAndReconstruct.py
1#!/usr/bin/env python3
2
3
10
11import os
12import sys
13
14import basf2
15import modularAnalysis as ma
16import variables as va
17import variables.collections as vc
18import variables.utils as vu
19from vertex import kFit
20from b2biiConversion import convertBelleMdstToBelleIIMdst
21from b2biiMonitors import addBeamParamsConversionMonitors
22from b2biiMonitors import addTrackConversionMonitors
23from b2biiMonitors import addNeutralsConversionMonitors
24
25os.environ['USE_GRAND_REPROCESS_DATA'] = '1'
26os.environ['PGUSER'] = 'g0db'
27
28# If you want to create the monitoring histograms (recommended in the beginning of your analysis), just provide any argument
29monitoring = False
30if len(sys.argv) == 1:
31 basf2.B2WARNING("In the beginning of an analysis it is recommended to study the monitoring histograms.\n"
32 "These tell you if the conversion works as expected.\n"
33 "If you want to create them, just provide any argument to this script.")
34else:
35 monitoring = True
36
37print('BELLE2_EXTERNALS_DIR = ' + str(os.getenv('BELLE2_EXTERNALS_DIR')))
38print('BELLE2_EXTERNALS_SUBDIR = ' + str(os.getenv('BELLE2_EXTERNALS_SUBDIR')))
39print('BELLE2_EXTERNALS_OPTION = ' + str(os.getenv('BELLE2_EXTERNALS_OPTION')))
40print('BELLE2_EXTERNALS_VERSION = ' + str(os.getenv('BELLE2_EXTERNALS_VERSION')))
41print('BELLE2_LOCAL_DIR = ' + str(os.getenv('BELLE2_LOCAL_DIR')))
42print('BELLE2_RELEASE = ' + str(os.getenv('BELLE2_RELEASE')))
43print('BELLE2_OPTION = ' + str(os.getenv('BELLE2_OPTION')))
44print('BELLE_POSTGRES_SERVER = ' + str(os.getenv('BELLE_POSTGRES_SERVER')))
45print('USE_GRAND_REPROCESS_DATA = ' + str(os.getenv('USE_GRAND_REPROCESS_DATA')))
46print('PANTHER_TABLE_DIR = ' + str(os.getenv('PANTHER_TABLE_DIR')))
47print('PGUSER = ' + str(os.getenv('PGUSER')))
48
49# Convert
50mypath = basf2.create_path()
51inputfile = basf2.find_file('b2bii_input_evtgen_exp_07_BptoD0pip-D0toKpipi0-0.mdst', 'examples', False)
52convertBelleMdstToBelleIIMdst(inputfile, path=mypath)
53
54# Reconstruct
55if monitoring:
56 # Create monitoring histograms if requested
57 addBeamParamsConversionMonitors(path=mypath)
58 addTrackConversionMonitors(path=mypath)
59 addNeutralsConversionMonitors(path=mypath)
60
61# Only charged final state particles need to be loaded. The neutral particles
62# gamma, pi0, K_S0, K_L0, and Lambda0 are already loaded to the 'gamma:mdst',
63# 'pi0:mdst', 'K_S0:mdst', 'K_L0:mdst', and 'Lambda0:mdst' particle lists,
64# respectively.
65ma.fillParticleList('pi+:all', '', path=mypath)
66ma.fillParticleList('K+:all', '', path=mypath)
67ma.fillParticleList('mu+:all', '', path=mypath)
68ma.fillParticleList('e+:all', '', path=mypath)
69
70# Let's have a look at the pi0 candidates in 'pi0:mdst' and print the values of some variables
71# In order to access the MC information we need to run the MC matching first
72ma.matchMCTruth('pi0:mdst', path=mypath)
73ma.printVariableValues('gamma:mdst', ['mcPDG', 'E', 'clusterE9E25'], path=mypath)
74ma.printVariableValues('pi0:mdst', ['mcPDG', 'p', 'M', 'InvM'], path=mypath)
75
76# The advantage of the pre-loaded V0s (which are the only ones that you should
77# use in B2BII analyses) is that the momenta and the position of the daughter
78# tracks are determined wrt. a pivot at the decay vertex of the V0. In
79# addition, K_S0:mdst (Lambda0:mdst) has goodKs (goodLambda) and nisKsFinder
80# outputs attached as extra info. It can be used to select good candidates.
81ma.cutAndCopyList('K_S0:good', 'K_S0:mdst', cut='goodBelleKshort', path=mypath)
82
83# It makes sense to perform a vertex fit of the K_S0 candidates and accept
84# only those candidates where the vertex fit converged
85kFit('K_S0:good', 0, path=mypath)
86
87# Again, let's print a few variable values:
88ma.matchMCTruth('K_S0:good', path=mypath)
89ma.printVariableValues('K_S0:good', ['mcPDG', 'M', 'InvM', 'p', 'px', 'py', 'pz',
90 'extraInfo(goodKs)', 'extraInfo(ksnbVLike)', 'extraInfo(ksnbNoLam)'], path=mypath)
91
92# The Belle PID variables are: atcPIDBelle(sigHyp, bkgHyp), muIDBelle, and eIDBelle
93va.variables.addAlias('Lkpi', 'atcPIDBelle(3,2)')
94va.variables.addAlias('Lppi', 'atcPIDBelle(4,2)')
95va.variables.addAlias('Lpk', 'atcPIDBelle(4,3)')
96
97# Since we did not apply any PID requirement the 'pi+:all' particle list
98# contains all type of charged final state particles. Have a look at the
99# printOut and notice how the true identity correlates with the corresponding
100# PID values.
101ma.printVariableValues('pi+:all', ['mcPDG', 'p', 'Lkpi', 'Lppi', 'muIDBelle',
102 'muIDBelleQuality', 'eIDBelle', 'nSVDHits'], path=mypath)
103
104# Now, let's really reconstruct a B decay with an intermediate D meson:
105ma.reconstructDecay('D0:Kpipi0 -> K-:all pi+:all pi0:mdst', '1.7 < M < 2.0', path=mypath)
106ma.reconstructDecay('B+:D0pi -> anti-D0:Kpipi0 pi+:all', '4.8 < M < 5.5', path=mypath)
107
108ma.matchMCTruth('B+:D0pi', path=mypath)
109
110# create and fill flat Ntuple with MCTruth and kinematic information
111kinematics_and_truth = vc.kinematics + vc.mc_truth
112variables = vu.create_aliases_for_selected(kinematics_and_truth, '^B+ -> [ ^D0 -> ^K- ^pi+ ^pi0] ^pi+')
113
114belle1pid = ['eIDBelle', 'muIDBelleQuality', 'muIDBelle', 'Lkpi', 'Lppi', 'Lpk']
115variables += vu.create_aliases_for_selected(belle1pid, 'B+ -> [ D0 -> ^K- ^pi+ pi0] ^pi+')
116
117ma.variablesToNtuple('B+:D0pi', variables, filename='B2BII_ConvertAndReconstruct_Example.root', path=mypath)
118
119# progress
120mypath.add_module('Progress')
121
122basf2.process(mypath)
123
124# Print call statistics
125print(basf2.statistics)