Belle II Software  release-05-01-25
ecl_packer_unpacker.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 
4 # Inspired by cdc/tests/cdc_packer_unpacker.py
5 
6 # This test checks if ECLDigits that are packed and then unpacked are identical to the originals.
7 # ECLDigits are obtained in 2 ways:
8 # 1) From simulated muons
9 # 2) "Custom" ECLDigits that have different combinations of parameters spanning the allowed range.
10 
11 from basf2 import *
12 from ROOT import Belle2
13 from unittest import TestCase
14 from ROOT import gRandom
15 import simulation
16 import itertools
17 
18 logLevel = LogLevel.INFO # LogLevel.DEBUG #
19 set_random_seed(42)
20 
21 eclDigitsDatastoreName = 'ECLDigits'
22 unpackerOutputDatastoreName = 'someECLUnpackerDatastoreName'
23 
24 import random
25 
26 
27 class addECLDigitsModule(Module):
28  """
29  Adds ECLDigits with very large/small time/amplitude values
30  """
31 
32  def __init__(self):
33  """constructor"""
34  super().__init__()
35  amps = [0, 1, 100000, 262015]
36  times = [-2048, -100, 0, 100, 2047]
37  qualitys = [0, 1, 2, 3]
38  chis = [0, 1, 254, 511]
39  paramNames = ["amp", "time", "quality", "chi"]
40 
41  self.digitParams = [dict(zip(paramNames, params)) for params in itertools.product(amps, times, qualitys, chis)]
42 
43  def event(self):
44  """
45  event function
46  """
47  eclDigitsFromSimulation = Belle2.PyStoreArray(eclDigitsDatastoreName)
48 
49  # Check for used cellIds
50  usedCellIds = list(map(lambda eclDigit: eclDigit.getCellId(), eclDigitsFromSimulation))
51 
52  # Create new ECLDigits and add them to datastore
53  for digitParam in self.digitParams:
54  # Skip combination of quality != 2 and chi != 0. Electronics can't output this
55  if (digitParam['quality'] is not 2) and (digitParam['chi'] is not 0):
56  continue
57 
58  # Skip combination of quality == 2 and amp != 0. Electronics can't output this
59  if (digitParam['quality'] is 2) and (digitParam['time'] is not 0):
60  continue
61 
62  # Choose cellId that's not already used
63  cellId = int(gRandom.Uniform(1, 8736))
64  while cellId in usedCellIds:
65  cellId = int(gRandom.Uniform(1, 8736))
66 
67  usedCellIds.append(cellId)
68  # Create new ECLDigit
69  eclDigit = Belle2.ECLDigit()
70 
71  # Fill ECLDigit
72  eclDigit.setCellId(cellId)
73  eclDigit.setAmp(digitParam['amp'])
74  eclDigit.setTimeFit(digitParam['time'])
75  eclDigit.setQuality(digitParam['quality'])
76  eclDigit.setChi(digitParam['chi'])
77 
78  # Add ECLDigit to datastore
79  newDigit = eclDigitsFromSimulation.appendNew()
80  newDigit.__assign__(eclDigit)
81 
82 
84  """
85  module which checks if two collections of ECLDigits are equal
86  """
87 
88  def sortECLDigits(self, unsortedPyStoreArray):
89  """ use a some information to sort the ECLDigits list
90  Returns a python-list containing the ECLDigits
91  """
92  # first convert to a python-list to be able to sort
93  py_list = [x for x in unsortedPyStoreArray]
94 
95  # sort via a hierachy of sort keys
96  return sorted(
97  py_list,
98  key=lambda x: (
99  x.getCellId()))
100 
101  def event(self):
102  """
103  event function
104  """
105 
106  # load the ECLDigits that were packed and unpacked
107  eclDigitsPackedUnpacked_unsorted = Belle2.PyStoreArray(unpackerOutputDatastoreName)
108  # ECLDigits direct from simulation
109  eclDigitsFromSimulation_unsorted = Belle2.PyStoreArray(eclDigitsDatastoreName)
110 
111  if not len(eclDigitsFromSimulation_unsorted) == len(eclDigitsPackedUnpacked_unsorted):
112  B2FATAL("Different number of ECLDigits from simulation and after packing+unpacking")
113 
114  eclDigitsPackedUnpacked = self.sortECLDigits(eclDigitsPackedUnpacked_unsorted)
115  eclDigitsFromSimulation = self.sortECLDigits(eclDigitsFromSimulation_unsorted)
116 
117  tc = TestCase('__init__')
118 
119  # check all quantities between the direct and the packed/unpacked ECLDigits
120  for idx in range(len(eclDigitsPackedUnpacked)):
121  digit = eclDigitsFromSimulation[idx]
122  digitPackedUnpacked = eclDigitsPackedUnpacked[idx]
123 
124  B2DEBUG(5, 'MC digit: cellid = ' +
125  str(digit.getCellId()) +
126  ', amp = ' +
127  str(digit.getAmp()) +
128  ', time = ' +
129  str(digit.getTimeFit()) +
130  ', quality = ' +
131  str(digit.getQuality()) +
132  ', chi = ' +
133  str(digit.getChi()) +
134  '\nUnpackedDigit: cellid = ' +
135  str(digitPackedUnpacked.getCellId()) +
136  ', amp = ' +
137  str(digitPackedUnpacked.getAmp()) +
138  ', time = ' +
139  str(digitPackedUnpacked.getTimeFit()) +
140  ', quality = ' +
141  str(digitPackedUnpacked.getQuality()) +
142  ', chi = ' +
143  str(digitPackedUnpacked.getChi()))
144 
145  tc.assertEqual(digit.getCellId(), digitPackedUnpacked.getCellId())
146  tc.assertEqual(digit.getAmp(), digitPackedUnpacked.getAmp())
147  tc.assertEqual(digit.getTimeFit(), digitPackedUnpacked.getTimeFit())
148  tc.assertEqual(digit.getQuality(), digitPackedUnpacked.getQuality())
149  tc.assertEqual(digit.getChi(), digitPackedUnpacked.getChi())
150 
151 
152 main = create_path()
153 # Create Event information
154 eventinfosetter = register_module('EventInfoSetter')
155 eventinfosetter.param({'evtNumList': [10]})
156 main.add_module(eventinfosetter)
157 
158 # to run the framework the used modules need to be registered
159 particlegun = register_module('ParticleGun')
160 particlegun.param('pdgCodes', [13, -13])
161 particlegun.param('nTracks', 10)
162 main.add_module(particlegun)
163 
164 # add simulation for ECL only
165 simulation.add_simulation(main, components=['ECL'])
166 set_module_parameters(main, type="Geometry", useDB=False, components=["ECL"])
167 
168 # Add ECLDigits with wide range of amp, time, quality, chi2
169 main.add_module(addECLDigitsModule())
170 
171 # add the packer which packs the ECLDigits from the simulation
172 ecl_packer = register_module('ECLPacker')
173 main.add_module(ecl_packer)
174 
175 # add the unpacker which unpacks the RawECL into ECLDigits and store them in a seperate datstore container
176 ecl_unpacker = register_module('ECLUnpacker')
177 # set the unpacker output datastore name, so that we don't overwrite the "normal" ECLDigits
178 ecl_unpacker.param('ECLDigitsName', unpackerOutputDatastoreName)
179 main.add_module(ecl_unpacker)
180 
181 # Run test module to check if the original ECLDigits and the ones that were packed and unpacked are identical
182 eclPackUnpackerChecker = ECLPackerUnpackerTestModule()
183 main.add_module(eclPackUnpackerChecker, logLevel=logLevel)
184 
185 
186 # Process events
187 process(main)
ecl_packer_unpacker.addECLDigitsModule
Definition: ecl_packer_unpacker.py:27
ecl_packer_unpacker.addECLDigitsModule.digitParams
digitParams
ecl digit parameters
Definition: ecl_packer_unpacker.py:41
ecl_packer_unpacker.ECLPackerUnpackerTestModule.event
def event(self)
Definition: ecl_packer_unpacker.py:101
ecl_packer_unpacker.addECLDigitsModule.__init__
def __init__(self)
Definition: ecl_packer_unpacker.py:32
simulation.add_simulation
def add_simulation(path, components=None, bkgfiles=None, bkgOverlay=True, forceSetPXDDataReduction=False, usePXDDataReduction=True, cleanupPXDDataReduction=True, generate_2nd_cdc_hits=False, simulateT0jitter=False, usePXDGatedMode=False)
Definition: simulation.py:114
ecl_packer_unpacker.ECLPackerUnpackerTestModule
Definition: ecl_packer_unpacker.py:83
ecl_packer_unpacker.ECLPackerUnpackerTestModule.sortECLDigits
def sortECLDigits(self, unsortedPyStoreArray)
Definition: ecl_packer_unpacker.py:88
ecl_packer_unpacker.addECLDigitsModule.event
def event(self)
Definition: ecl_packer_unpacker.py:43
Belle2::ECLDigit
Class to store ECL digitized hits (output of ECLDigi) relation to ECLHit filled in ecl/modules/eclDig...
Definition: ECLDigit.h:34
Belle2::PyStoreArray
a (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:58