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