Belle II Software development
eventLevelClusteringInfo_countOutOfTime.py
1#!/usr/bin/env python3
2
3
10
11"""
12Test EventLevelClusteringInfo counting of out of time ECLCalDigits.
13
14Creates 1 ECLCalDigit in each ECL detector region (FWD, Barrel, BWD).
15
16The created digits cover all possible combinations of:
17time above threshold for counting
18time below threshold for counting
19energy above threshold for counting
20energy below threshold for counting
21
22In order to be counted, both energy and time have to be above threshold
23"""
24
25import basf2 as b2
26from ROOT import Belle2
27from unittest import TestCase
28import itertools
29
30from b2test_utils import skip_test_if_light
31skip_test_if_light() # light builds don't contain ECLCalDigits
32
33b2.set_random_seed(42)
34
35# global variable that holds expected number of out of time digits
36expectOutOfTime = {"FWD": 0, "BRL": 0, "BWD": 0}
37
38
39class addECLCalDigitsModule(b2.Module):
40 """
41 Add combinations of ECLCalDigits above/below threshold to be counted as out of time
42 """
43
44 def __init__(self):
45 """
46 Prepare ECLCalDigits parameters
47 """
48 super().__init__()
49
50
51 self.eventCounter = 0
52
53 aboveEnergyThresh = [True, False]
54 aboveTimeThresh = [True, False]
55 thresholdNames = ["aboveEnergythresh", "aboveTimethresh"]
56
57 thresholdsPerRegion = [dict(zip(thresholdNames, thresholds))
58 for thresholds in itertools.product(aboveEnergyThresh, aboveTimeThresh)]
59
60 fwdThresholds, brlThresholds, bwdThresholds = itertools.tee(thresholdsPerRegion, 3)
61
62 regions = ["FWD", "BRL", "BWD"]
63
64
65 self.digitParams = [dict(zip(regions, thresholds))
66 for thresholds in itertools.product(fwdThresholds, brlThresholds, bwdThresholds)]
67
68
69 self.energyThresh = -1
70
71 self.timeThresh = -1
72
73 def initialize(self):
74 """ module initialize - register ECLCalDigit in datastore """
75
76
77 self.eclCalDigits = Belle2.PyStoreArray(Belle2.ECLCalDigit.Class())
78 self.eclCalDigits.registerInDataStore()
79 # Necessary for ECLDigitCalibrator
80 eclDigits = Belle2.PyStoreArray(Belle2.ECLDigit.Class())
81 eclDigits.registerInDataStore()
82
83 def event(self):
84 """
85 Add ECLCalDigits according to self.digitParams
86 """
87 eclCalDigits = Belle2.PyStoreArray('ECLCalDigits')
88
89 # cellIds for corresponding to different regions
90 cellId = {"FWD": 1, "BRL": 1153, "BWD": 7777}
91
92 b2.B2DEBUG(37, "Event " + str(self.eventCounter))
93
94 # ECLCalDigit parameter for this event
95 digitParam = self.digitParams[self.eventCounter]
96
97 # Loop on detector regions
98 for region in cellId:
99
100 # Create new ECLCalDigit
101 eclCalDigit = Belle2.ECLCalDigit()
102
103 # Fill ECLCalDigit
104 eclCalDigit.setCellId(cellId[region])
105
106 # Increment cellId.
107 # Important if we ever expand this test to have more than 1 digit per region.
108 cellId[region] += 1
109
110 energy = digitParam[region]["aboveEnergythresh"] * (self.energyThresh + 1)
111 time = digitParam[region]["aboveTimethresh"] * (self.timeThresh + 1)
112 eclCalDigit.setEnergy(energy)
113 eclCalDigit.setTime(time)
114
115 # Add ECLDigit to datastore
116 newDigit = eclCalDigits.appendNew()
117 newDigit.__assign__(eclCalDigit)
118
119 # Set expected number of out of time calDigits per region
120 expectOutOfTime[region] = int(digitParam[region]["aboveEnergythresh"] and digitParam[region]["aboveTimethresh"])
121 b2.B2DEBUG(35, region + ": expecting " + str(expectOutOfTime[region]))
122 b2.B2DEBUG(39, "region = " + region + ", time = " + str(time) + ", energy = " + str(energy))
123
124 # Increment event counter
125 self.eventCounter += 1
126
127
129 """
130 module which checks the number of out of time digits in EventLevelClusteringInfo is as expected
131 """
132
133 def event(self):
134 """
135 event function
136 """
137 eventLevelClusteringInfo = Belle2.PyStoreObj('EventLevelClusteringInfo').obj()
138
139 tc = TestCase('__init__')
140
141 tc.assertEqual(eventLevelClusteringInfo.getNECLCalDigitsOutOfTimeFWD(), expectOutOfTime["FWD"])
142 tc.assertEqual(eventLevelClusteringInfo.getNECLCalDigitsOutOfTimeBarrel(), expectOutOfTime["BRL"])
143 tc.assertEqual(eventLevelClusteringInfo.getNECLCalDigitsOutOfTimeBWD(), expectOutOfTime["BWD"])
144 tc.assertEqual(eventLevelClusteringInfo.getNECLCalDigitsOutOfTime(),
145 expectOutOfTime["FWD"] + expectOutOfTime["BRL"] + expectOutOfTime["BWD"])
146
147
148main = b2.create_path()
149
150# Create Event information
151eventinfosetter = b2.register_module('EventInfoSetter')
152main.add_module(eventinfosetter)
153
154gearbox = b2.register_module('Gearbox')
155main.add_module(gearbox)
156
157geometry = b2.register_module('Geometry', useDB=False)
158geometry.param('components', ['ECL'])
159main.add_module(geometry)
160
161# Add ECLCalDigits
162addECLCalDigits = main.add_module(addECLCalDigitsModule())
163addECLCalDigits.logging.log_level = b2.LogLevel.DEBUG
164addECLCalDigits.logging.debug_level = 10
165
166# Set number of events according to number of different combination in addECLCalDigits
167eventinfosetter.param({'evtNumList': [len(addECLCalDigits.digitParams)], 'runList': [0]})
168
169ECLDigitCalibrator = b2.register_module('ECLDigitCalibrator')
170main.add_module(ECLDigitCalibrator)
171
172# Extract energy and time threshold from ECLDigitCalibrator module
173for param in ECLDigitCalibrator.available_params():
174 if param.name == "backgroundEnergyCut":
175 addECLCalDigits.energyThresh = param.values
176 elif param.name == "backgroundTimingCut":
177 addECLCalDigits.timeThresh = param.values
178
179main.add_module(checkNumOutOfTimeDigitsModule())
180
181# Process events
182b2.process(main)
Class to store calibrated ECLDigits: ECLCalDigits.
Definition: ECLCalDigit.h:23
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
a (simplified) python wrapper for StoreObjPtr.
Definition: PyStoreObj.h:67
eventCounter
count number of times event method is called (each time use different combinations of ECLCalDigits