Belle II Software  release-08-01-10
pxd_packer_unpacker.py
1 #!/usr/bin/env python3
2 
3 
10 
11 
12 # print("TEST SKIPPED: Test fails due to changes in packer which were not propagated to unpacker. See BII-1647", file=sys.stderr)
13 # sys.exit(1)
14 
15 import basf2 as b2
16 from ROOT import Belle2
17 import numpy
18 
19 import simulation
20 from rawdata import add_packers
21 from rawdata import add_unpackers
22 
23 pxd_rawhits_pack_unpack_collection = "PXDRawHits_test"
24 pxd_rawhits_pack_unpack_collection_digits = "PXDDigits_test"
25 pxd_rawhits_pack_unpack_collection_adc = pxd_rawhits_pack_unpack_collection + "_adc"
26 pxd_rawhits_pack_unpack_collection_roi = pxd_rawhits_pack_unpack_collection + "_roi"
27 b2.set_random_seed(42)
28 
29 
30 class PxdPackerUnpackerTestModule(b2.Module):
31 
32  """
33  Module which checks if a collection of PXDDigits and
34  a collection of PXDRawHits from the packing/unpacking procedure are equal.
35  The PXDUnpacker does not create PXDDigits but PXDRawHits and therefore these two lists
36  must be compared.
37  """
38 
39  def __init__(self, rawhits_collection='PXDRawHits', digits_collection="PXDDigits"):
40  """constructor"""
41  # call constructor of base class, required if you implement __init__ yourself!
42  super().__init__()
43  # and do whatever else is necessary like declaring member variables
44 
45  self.rawhits_collectionrawhits_collection = rawhits_collection
46 
47  self.digits_collectiondigits_collection = digits_collection
48 
49  def sortDigits(self, unsortedPyStoreArray):
50  """ use a some digit information to sort the PXDDigits list
51  Returns a python-list containing the PXDDigts
52  """
53 
54  # first convert to a python-list to be abple to sort
55  py_list = [x for x in unsortedPyStoreArray]
56 
57  # sort via a hierachy of sort keys
58  return sorted(
59  py_list,
60  key=lambda x: (
61  x.getSensorID(),
62  x.getVCellID(),
63  x.getUCellID()))
64 
65  def sortRawHits(self, unsortedPyStoreArray):
66  """ use a some digit information to sort the PXDRawHits list
67  Returns a python-list containing the PXDRawHits
68  """
69 
70  # first convert to a python-list to be able to sort
71  py_list = [x for x in unsortedPyStoreArray]
72 
73  # sort via a hierachy of sort keys
74  return sorted(
75  py_list,
76  key=lambda x: (
77  x.getSensorID(),
78  x.getRow(),
79  x.getColumn()))
80 
81  def event(self):
82  """ load the PXD Digits of the simulation and the packed/unpacked ones
83  and compare them"""
84 
85  # load the digits and the collection which results from the packer and unpacker
86  # processed by packer and unpacker
87  pxdRawHitsPackedUnpacked_unsorted = Belle2.PyStoreArray(self.rawhits_collectionrawhits_collection)
88  # direct from simulation
89  pxdDigits_unsorted = Belle2.PyStoreArray(self.digits_collectiondigits_collection)
90 
91  # sort the digits, because the order gets
92  # lost during the packing/unpacking process
93  pxdDigits = self.sortDigitssortDigits(pxdDigits_unsorted)
94  pxdRawHitsPackedUnpacked = self.sortRawHitssortRawHits(pxdRawHitsPackedUnpacked_unsorted)
95 
96  if not len(pxdDigits) == len(pxdRawHitsPackedUnpacked):
97  b2.B2FATAL("PXDDigits and PXDRawHits count not equal after packing and unpacking")
98 
99  print(f"Comparing {len(pxdDigits)} pxd digits ")
100 
101  # check all quantities between the direct and the packed/unpacked pxd digits
102  for i in range(len(pxdDigits)):
103  digit = pxdDigits[i]
104  rawHitPackedUnpacked = pxdRawHitsPackedUnpacked[i]
105 
106  # compare all available quantities
107  # cannot compare frame number, because it is not availabl on PXDDigits
108  assert rawHitPackedUnpacked.getSensorID().getID() == digit.getSensorID().getID()
109  assert rawHitPackedUnpacked.getRow() == digit.getVCellID()
110  assert rawHitPackedUnpacked.getColumn() == digit.getUCellID()
111  # There are some rare cases (~ every 10th event), where the PXD Digits have a charge
112  # larger than 255 which will be clipped by the packer to 8bit (at most 255)
113  # therefor, limit the maximal charge of the digit here in the comparison
114  assert numpy.isclose(min(255.0, digit.getCharge()), rawHitPackedUnpacked.getCharge())
115 
116 
117 # to run the framework the used modules need to be registered
118 particlegun = b2.register_module('ParticleGun')
119 particlegun.param('pdgCodes', [13, -13])
120 particlegun.param('nTracks', 10)
121 
122 # Create Event information
123 eventinfosetter = b2.register_module('EventInfoSetter')
124 eventinfosetter.param({'evtNumList': [50]})
125 # Show progress of processing
126 progress = b2.register_module('Progress')
127 
128 main = b2.create_path()
129 # init path
130 main.add_module(eventinfosetter)
131 main.add_module(particlegun)
132 # add simulation for pxd only
133 simulation.add_simulation(main, components=['PXD'], forceSetPXDDataReduction=True, usePXDDataReduction=False)
134 b2.set_module_parameters(main, type="Geometry", useDB=False, components=["PXD"])
135 
136 main.add_module(progress)
137 
138 # Create raw data form simulated digits
139 add_packers(main, components=['PXD'])
140 
141 # Unpack raw data to pack_unpack_collections
142 add_unpackers(main, components=['PXD'])
143 
144 # Change names of collections to avoid conflicts
145 for e in main.modules():
146  if e.name() == 'PXDUnpacker':
147  e.param("PXDRawHitsName", pxd_rawhits_pack_unpack_collection)
148  e.param("PXDRawAdcsName", pxd_rawhits_pack_unpack_collection_adc)
149  e.param("PXDRawROIsName", pxd_rawhits_pack_unpack_collection_roi)
150 
151  if e.name() == 'PXDRawHitSorter':
152  e.param('rawHits', pxd_rawhits_pack_unpack_collection)
153  e.param('digits', pxd_rawhits_pack_unpack_collection_digits)
154 
155 
156 # run custom test module to check if the simulated PXDDigits and the
157 # pxd_digits_pack_unpack_collection collections are equal
158 main.add_module(PxdPackerUnpackerTestModule(rawhits_collection=pxd_rawhits_pack_unpack_collection, digits_collection="PXDDigits"))
159 
160 
161 # run custom test module 2nd time to check if the collection pxd_rawhits_pack_unpack_collection_digits
162 # and the pxd_digits_pack_unpack_collection collections are equal
163 main.add_module(
165  rawhits_collection=pxd_rawhits_pack_unpack_collection,
166  digits_collection=pxd_rawhits_pack_unpack_collection_digits))
167 
168 
169 # Process events
170 b2.process(main)
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
def __init__(self, rawhits_collection='PXDRawHits', digits_collection="PXDDigits")
int getID(const std::vector< double > &breaks, double t)
get id of the time point t
Definition: calibTools.h:60
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:121