Belle II Software development
CheckNegativeWeights.py
1#!/usr/bin/env python3
2
3
10
11import basf2 as b2
12from ROOT import Belle2
13import svd
14import pxd
15
16b2.logging.log_level = b2.LogLevel.WARNING
17
18
19class CheckNegativeWeights(b2.Module):
20
21 """
22 Lists signs of MCParticle relation weights for VXD Clusters based on
23 MCParticle and TrueHit information.
24 Breakdown of data:
25 MCParticle primary/secondary/remapped/none (no relation to MCParticle)
26 Relation sign positive/negative
27 """
28
29 def __init__(self):
30 """Initialize the module"""
31
32 super().__init__()
33
35 'primary': {'positive': 0, 'negative': 0},
36 'secondary': {'positive': 0, 'negative': 0},
37 'remapped': {'positive': 0, 'negative': 0},
38 'none': {'positive': 0, 'negative': 0}
39 }
40
42 'primary': {'positive': 0, 'negative': 0},
43 'secondary': {'positive': 0, 'negative': 0},
44 'remapped': {'positive': 0, 'negative': 0},
45 'none': {'positive': 0, 'negative': 0}
46 }
47
48 def initialize(self):
49 """ Does nothing """
50
51 def beginRun(self):
52 """ Does nothing """
53
54 def event(self):
55 """
56 Goes through event's PXD and SVD clusters and looks at MCParticles
57 and TrueHits relations for the sign of relations.
58 """
59 # PXD part -------------------------------------------------------
60 pxd_clusters = Belle2.PyStoreArray('PXDClusters')
61
62 for cluster in pxd_clusters:
63 # Determine MCParticle tag and MCParticle relation weight sign
64 mcparticle_tag = 'none'
65 sign_tag = 'positive' # convention if there is no relation
66 # From MCParticles we can determine if the particle is primary
67 # or secondary, and we get the sign of the weight.
68 # To determine if a MCParticle is remapped, we need TrueHit
69 # and the sign of its relation to the MCParticle.
70 mcparticle_relations = cluster.getRelationsTo('MCParticles')
71 n_mcparticle_relations = mcparticle_relations.size()
72 for mcparticle_index in range(n_mcparticle_relations):
73 mcparticle = mcparticle_relations[mcparticle_index]
74 mcparticle_weight = \
75 mcparticle_relations.weight(mcparticle_index)
76 if mcparticle_weight < 0:
77 sign_tag = 'negative'
78 if mcparticle.hasStatus(Belle2.MCParticle.c_PrimaryParticle):
79 mcparticle_tag = 'primary'
80 # The primary particle may be remapped. Check TrueHits!
81 cluster_truehits = cluster.getRelationsTo('PXDTrueHits')
82 # Identify the TrueHit related to the current MCParticle.
83 mcparticle_array_index = mcparticle.getArrayIndex()
84 for hit in cluster_truehits:
85 hit_particle_relations = \
86 hit.getRelationsFrom('MCParticles')
87 n_relations = hit_particle_relations.size()
88 for particle_index in range(n_relations):
89 hit_particle = \
90 hit_particle_relations[particle_index]
91 if hit_particle.getArrayIndex() == \
92 mcparticle_array_index:
93 # check sign of the weight
94 weight = hit_particle_relations.weight(
95 particle_index)
96 if weight < 0:
97 mcparticle_tag = 'remapped'
98 break
99 else:
100 mcparticle_tag = 'secondary'
101 # That's it, store the result
102 # If there are more MCParticles per cluster (possible), we
103 # make an entry for each.
104 self.sign_stats_pxd[mcparticle_tag][sign_tag] += 1
105
106 # SVD part -------------------------------------------------------
107 svd_clusters = Belle2.PyStoreArray('SVDClusters')
108
109 for cluster in svd_clusters:
110 # Determine MCParticle tag and MCParticle relation weight sign
111 mcparticle_tag = 'none'
112 sign_tag = 'positive' # convention if there is no relation
113 # From MCParticles we can determine if the particle is primary
114 # or secondary, and we get the sign of the weight.
115 # To determine if a MCParticle is remapped, we need TrueHit
116 # and the sign of its relation to the MCParticle.
117 mcparticle_relations = cluster.getRelationsTo('MCParticles')
118 n_mcparticle_relations = mcparticle_relations.size()
119 for mcparticle_index in range(n_mcparticle_relations):
120 mcparticle = mcparticle_relations[mcparticle_index]
121 mcparticle_weight = \
122 mcparticle_relations.weight(mcparticle_index)
123 if mcparticle_weight < 0:
124 sign_tag = 'negative'
125 if mcparticle.hasStatus(Belle2.MCParticle.c_PrimaryParticle):
126 mcparticle_tag = 'primary'
127 # The primary particle may be remapped. Check TrueHits!
128 cluster_truehits = cluster.getRelationsTo('SVDTrueHits')
129 # Identify the TrueHit related to the current MCParticle.
130 mcparticle_array_index = mcparticle.getArrayIndex()
131 for hit in cluster_truehits:
132 hit_particle_relations = \
133 hit.getRelationsFrom('MCParticles')
134 n_relations = hit_particle_relations.size()
135 for particle_index in range(n_relations):
136 hit_particle = \
137 hit_particle_relations[particle_index]
138 if hit_particle.getArrayIndex() == \
139 mcparticle_array_index:
140 # check sign of the weight
141 weight = hit_particle_relations.weight(
142 particle_index)
143 if weight < 0:
144 mcparticle_tag = 'remapped'
145 break
146 else:
147 mcparticle_tag = 'secondary'
148 # That's it, store the result
149 self.sign_stats_svd[mcparticle_tag][sign_tag] += 1
150
151 def terminate(self):
152 """ Write results """
153 b2.B2INFO(
154 f'\nResults for PXD: \n{str(self.sign_stats_pxd)}\nResults for SVD: \n{str(self.sign_stats_svd)}\n'
155 )
156
157
158# Particle gun module
159particlegun = b2.register_module('ParticleGun')
160# Create Event information
161eventinfosetter = b2.register_module('EventInfoSetter')
162# Show progress of processing
163progress = b2.register_module('Progress')
164# Load parameters
165gearbox = b2.register_module('Gearbox')
166# Create geometry
167geometry = b2.register_module('Geometry')
168# Run simulation
169simulation = b2.register_module('FullSim')
170# simulation.param('StoreAllSecondaries', True)
171printWeights = CheckNegativeWeights()
172printWeights.set_log_level(b2.LogLevel.INFO)
173
174# Specify number of events to generate
175eventinfosetter.param({'evtNumList': [1000], 'runList': [1]})
176
177# Set parameters for particlegun
178particlegun.param({
179 'nTracks': 1,
180 'varyNTracks': True,
181 'pdgCodes': [211, -211, 11, -11],
182 'momentumGeneration': 'normalPt',
183 'momentumParams': [2, 1],
184 'phiGeneration': 'normal',
185 'phiParams': [0, 360],
186 'thetaGeneration': 'uniformCos',
187 'thetaParams': [17, 150],
188 'vertexGeneration': 'normal',
189 'xVertexParams': [0, 1],
190 'yVertexParams': [0, 1],
191 'zVertexParams': [0, 1],
192 'independentVertices': False,
193})
194
195
196# create processing path
197main = b2.create_path()
198main.add_module(eventinfosetter)
199main.add_module(progress)
200main.add_module(particlegun)
201main.add_module(gearbox)
202main.add_module(geometry)
203main.add_module(simulation)
208main.add_module(printWeights)
209
210# generate events
211b2.process(main)
212
213# show call statistics
214print(b2.statistics)
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
sign_stats_svd
Relation sign statistics for PXDClusters.
sign_stats_pxd
Relation sign statistics for PXDClusters.
def add_pxd_simulation(path, digitsName=None, activatePixelMasks=True, activateGainCorrection=True)
Definition: __init__.py:147
def add_pxd_reconstruction(path, clusterName=None, digitsName=None, usePXDClusterShapes=False, spacePointsName='PXDSpacePoints')
Definition: __init__.py:105
def add_svd_simulation(path, useConfigFromDB=False, daqMode=2, relativeShift=9)
Definition: __init__.py:244
def add_svd_reconstruction(path, isROIsimulation=False, createRecoDigits=False, applyMasking=False)
Definition: __init__.py:14