Belle II Software  release-05-01-25
create_geometry_payloads.py
1 #!/usr/bin/env python3
2 
3 # @cond no_doxygen
4 
5 """
6 Create a full set of consistent geometry payloads for nominal geometry, phase 2
7 geometry, and early phase 3 gometry from XML files.
8 
9 Optionally one can give a list of payload names to keep only a subset of payloads
10 """
11 
12 import basf2
13 import shutil
14 import sys
15 import re
16 import os
17 import subprocess
18 
19 # if we have extra arguments only keep the payloads given as arguments
20 interested = sys.argv[1:]
21 
22 # remove existing local database
23 shutil.rmtree("localdb", ignore_errors=True)
24 
25 # create phase3 geometry: This is the default in Belle2.xml
26 phase3 = basf2.Path()
27 phase3.add_module("EventInfoSetter")
28 phase3.add_module("Gearbox")
29 phase3.add_module("Geometry", createPayloads=True, payloadIov=[0, 0, -1, -1])
30 basf2.process(phase3)
31 
32 # create phase2 geometry. For this we need to manually add all the phase2
33 # detectors and remove the phase3-only detectors.
34 phase2_detectors = "BeamPipe PXD SVD ServiceGapsMaterial MICROTPC PINDIODE BEAMABORT HE3TUBE CLAWS FANGS PLUME QCSMONITOR".split()
35 phase2 = basf2.create_path()
36 phase2.add_module("EventInfoSetter")
37 phase2.add_module("Gearbox")
38 phase2.add_module("Geometry", createPayloads=True, payloadIov=[1002, 0, 1002, -1],
39  excludedComponents=["BeamPipe", "PXD", "SVD", "VXDService", "ServiceGapsMaterial"],
40  additionalComponents=[e + "-phase2" for e in phase2_detectors])
41 basf2.process(phase2)
42 
43 # create early phase3 geometry: same as phase 3 but different PXD configuration
44 early3 = basf2.Path()
45 early3.add_module("EventInfoSetter")
46 early3.add_module("Gearbox")
47 early3.add_module("Geometry", createPayloads=True, payloadIov=[1003, 0, 1003, -1],
48  excludedComponents=['PXD', "ServiceGapsMaterial"],
49  additionalComponents=['PXD-earlyPhase3', 'ServiceGapsMaterial-earlyPhase3'])
50 basf2.process(early3)
51 
52 # most of the components are identical so we avoid uploading two
53 # revisions so we remove most of them. We only need separate payloads for the
54 # for some of them
55 phase2 = ["GeoConfiguration", "PXDGeometryPar", "SVDGeometryPar", "BeamPipeGeo", "ServiceGapsMaterialsPar"]
56 # once we have a different ServiceGapsMaterial configuration for phase 3 we
57 # want to put that here as well
58 early3 = ["PXDGeometryPar"]
59 database_content = []
60 line_match = re.compile(r"^dbstore/(.*?) (\d+) ([0-9\-,]*)$")
61 keep = set()
62 with open("localdb/database.txt") as dbfile:
63  for line in dbfile:
64  match = line_match.search(line)
65  name, revision, iov = match.groups()
66  revision = int(revision)
67  # do we want to keep that payload at all?
68  if interested and name not in interested:
69  continue
70  # if so check whether we can unify the payloads
71  iov = tuple(int(e) for e in iov.split(','))
72  if iov[0] == 0:
73  if name in phase2:
74  keep.add((name, str(revision))) # we keep all revision one payloads somehow
75  database_content.append(f'dbstore/{name} {revision} 0,0,0,-1\n')
76  if name not in early3:
77  database_content.append(f'dbstore/{name} {revision} 1003,0,1003,-1\n')
78  # luckily nothing we have in early phase 3 is identical between
79  # phase 3 and phase 2 so need for extra checks if in early3 but
80  # not phase2
81  continue
82  elif iov[0] == 1002 and name not in phase2:
83  continue
84  elif iov[0] == 1003 and name not in early3:
85  continue
86 
87  # otherwise keep as it is ...
88  keep.add((name, str(revision)))
89  database_content.append(line)
90 
91 # and write new database file
92 database_content.sort()
93 with open("localdb/database.txt", "w") as dbfile:
94  dbfile.writelines(database_content)
95 
96 # Ok, finally remove all unneeded payload files ...
97 for filename in os.scandir('localdb/'):
98  match = re.match(r"dbstore_(.*?)_rev_(\d*).root", filename.name)
99  if not match:
100  continue
101  if match and match.groups() not in keep:
102  print(f"Removing {filename.name}: not needed")
103  os.unlink(filename.path)
104  else:
105  print(f"Normalizing {filename.name} as '{match.group(1)}'")
106  subprocess.call(["b2file-normalize", "-i", "-n", match.group(1), filename.path])
107 
108 # @endcond
basf2.process
def process(path, max_event=0)
Definition: __init__.py:25