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