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