Belle II Software  release-05-01-25
isSignalAcceptFlags.py
1 #!/usr/bin/env/python3
2 # -*-coding: utf-8-*-
3 
4 # isSignalAcceptFlags or isSignalAcceptSomething, means a special isSignal variable that accepts certain
5 # bits in the mcErrors to be set. For example, the pure isSignal equals to 1 only when mcErrors == 0, while
6 # isSignalAcceptMissingGamma euqals to 1 when mcErrors == 0 or mcErrors == 16, which could be interpreted
7 # as "After setting the MissGamma bit (the 5th bit, or 16 = 0b00010000) to 0, if mcErrors == 0, then
8 # isSignalAcceptMissingGamma euqals to 1". A new isSignalAcceptSomething variables could be added conveniently
9 # by create_isSignal_alias() in variable.utils:
10 # >>> c_MissGamma = 16
11 # >>> c_DecayInFlight = 4
12 # >>> vu.create_isSignal_alias("isSignalAcceptMissingGammaAndDecayInFlight", [c_MissGamma, c_DecayInFlight])
13 #
14 #
15 # if you want to know the detail of create_isSignal_alias(), you could read the paragraph below then check the code
16 # in analysis/scripts/variables/utils.py
17 # The operation, setting certain bits in a variable to 0, is called "unmask", in contrast to "mask".
18 # The function create_isSignal_alias() adds new isSignalAcceptSomething variable by unmasking the mcErrors
19 # code using the meta function unmask() like:
20 # >>> c_MissGamma = 16
21 # >>> c_DecayInFlight = 4
22 # >>> c_Correct = 0
23 # >>> vm.addAlias("isSignalAcceptMissingGammaAndDecayInFlight", "passesCut(unmask(mcErrors," +
24 # ... "%d) == %d)" % (c_MissGamma | c_DecayInFlight, c_Correct))
25 # The full definition of mc match error flags could be found in:
26 # https://b2-master.belle2.org/software/development/sphinx/analysis/doc/MCMatching.html#error-flags
27 #
28 # Guanda Gong
29 #
30 # For full documentation please refer to https://software.belle2.org
31 # Anything unclear? Ask questions at https://questions.belle2.org
32 
33 import basf2 as b2
34 import modularAnalysis as ma
35 from variables import variables as vm
36 import variables.collections as vc
37 import variables.utils as vu
38 import stdV0s
39 
40 # adjust log level, which would be helpful when debugging
41 # b2.logging.log_level = b2.LogLevel.DEBUG
42 
43 # Create a new path
44 mypath = b2.Path()
45 
46 # Add input file and ParticleLoader modules to the path
47 ma.inputMdstList('default', [b2.find_file('analysis/tests/mdst.root')], path=mypath)
48 
49 # Add ParticleLoader and ParticleCombiner modules to the path, reconstructing the process
50 # Ds*+ -> pi+ D0
51 # D0 -> pi- pi+ K_S0
52 # K_S0 -> pi+ pi-
53 ma.fillParticleList('pi+:all', '', path=mypath)
54 ma.fillParticleList('K+:all', '', path=mypath)
55 stdV0s.stdKshorts(path=mypath)
56 ma.reconstructDecay('D0:Example -> pi-:all pi+:all K_S0:merged', '1.7 < M < 2.0', path=mypath)
57 ma.reconstructDecay('D*+:Example -> pi+:all D0:Example', '0 < Q < 0.022 and useCMSFrame(p)>2.3', path=mypath)
58 
59 # add MC matching process, during which the isSignal and mcErrors are calculated
60 ma.matchMCTruth(list_name='D*+:Example', path=mypath)
61 
62 # declare what variables are needed
63 basic_vars = vc.inv_mass + vc.kinematics + vc.mc_truth + vc.mc_variables
64 
65 # The following isSignalSomething variables are predefined in Variable Manager,
66 isSignalSomething_vars = ["isSignalAcceptWrongFSPs"]
67 isSignalSomething_vars += ["isSignalAcceptMissingNeutrino", "isSignalAcceptMissingMassive"]
68 isSignalSomething_vars += ["isSignalAcceptMissingGamma", "isSignalAcceptMissing", "mcParticleStatus"]
69 
70 # Try to define your own isSignalAcceptSomething
71 c_Correct = 0 # This Particle and all its daughters are perfectly reconstructed.
72 c_MissFSR = 1 # A Final State Radiation (FSR) photon is not reconstructed (based
73 # on MCParticle::c_IsFSRPhoton).
74 c_MissingResonance = 2 # The associated MCParticle decay contained additional non-final-state
75 # particles (e.g. a rho) that weren't reconstructed. This is probably O.K. in most cases
76 c_DecayInFlight = 4 # A Particle was reconstructed from the secondary decay product of the actual particle.
77 # This means that a wrong hypothesis was used to reconstruct it, which e.g. for tracks might
78 # mean a pion hypothesis was used for a secondary electron.
79 c_MissNeutrino = 8 # A neutrino is missing (not reconstructed).
80 c_MissGamma = 16 # A photon (not FSR) is missing (not reconstructed).
81 c_MissMassiveParticle = 32 # A generated massive FSP is missing (not reconstructed).
82 c_MissKlong = 64 # A Klong is missing (not reconstructed).
83 c_MisID = 128 # One of the charged final state particles is mis-identified.
84 c_AddedWrongParticle = 256 # A non-FSP Particle has wrong PDG code, meaning one of the daughters (or their daughters)
85 # belongs to another Particle.
86 c_InternalError = 512 # There was an error in MC matching. Not a valid match. Might indicate fake/background track or cluster.
87 c_MissPHOTOS = 1024 # A photon created by PHOTOS was not reconstructed (based on MCParticle::c_IsPHOTOSPhoton)
88 c_AddedRecoBremsPhoton = 2048 # A photon added with the bremsstrahlung recovery tools (correctBrems or correctBremsBelle)
89 # has no MC particle assigned, or it doesn't belong to the decay chain
90 
91 # the indicated flags should be provided as an integer list
92 vu.create_isSignal_alias("isSignalAcceptMissingGammaAndMissingNeutrino", [16, 8])
93 isSignalSomething_vars += ["isSignalAcceptMissingGammaAndMissingNeutrino"]
94 
95 vu.create_isSignal_alias("isSignalAcceptMissingGammaAndDecayInFlight", [c_MissGamma, c_DecayInFlight])
96 isSignalSomething_vars += ["isSignalAcceptMissingGammaAndDecayInFlight"]
97 
98 # this line show how create_isSignal_alias() work, and is equivalent to the lines above
99 vm.addAlias("isSignalAcceptMissingNeutrinoAndWrongFSP", "passesCut(unmask(mcErrors," +
100  "%d) == %d)" % (c_MissGamma | c_MissMassiveParticle | c_MissKlong | c_MissKlong, c_Correct))
101 isSignalSomething_vars += ["isSignalAcceptMissingNeutrinoAndWrongFSP"]
102 
103 basic_vars += isSignalSomething_vars
104 
105 vm.printAliases()
106 
107 
108 # save the variables using variablesToNtuple
109 ma.variablesToNtuple('D*+:Example', basic_vars, filename="isSignalAcceptFlags.root",
110  treename='Dst', path=mypath)
111 
112 b2.process(mypath)
113 print(b2.statistics)
variables.utils
Definition: utils.py:1
stdV0s.stdKshorts
def stdKshorts(prioritiseV0=True, fitter='TreeFit', path=None)
Definition: stdV0s.py:10
variables.collections
Definition: collections.py:1