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