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