Belle II Software  release-08-01-10
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 b2test_utils
22 import shutil
23 import sys
24 import re
25 import os
26 import subprocess
27 
28 # if we have extra arguments only keep the payloads given as arguments
29 interested = sys.argv[1:]
30 
31 # remove existing local database
32 shutil.rmtree("localdb", ignore_errors=True)
33 
34 # create phase3 geometry: This is the default in Belle2.xml
35 phase3 = basf2.Path()
36 phase3.add_module("EventInfoSetter")
37 phase3.add_module("Gearbox")
38 phase3.add_module("Geometry", createPayloads=True, payloadIov=[0, 0, 0, -1])
40 
41 # create post LS1 geometry: Identical to the default one
42 postLS1 = basf2.Path()
43 postLS1.add_module("EventInfoSetter")
44 postLS1.add_module("Gearbox")
45 postLS1.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.
50 phase2_detectors = "BeamPipe PXD SVD ServiceGapsMaterial MICROTPC PINDIODE BEAMABORT HE3TUBE CLAWS FANGS PLUME QCSMONITOR".split()
51 phase2 = basf2.create_path()
52 phase2.add_module("EventInfoSetter")
53 phase2.add_module("Gearbox")
54 phase2.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
60 early3 = basf2.Path()
61 early3.add_module("EventInfoSetter")
62 early3.add_module("Gearbox")
63 early3.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
71 phase2 = ["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
74 early3 = ["PXDGeometryPar"]
75 database_content = []
76 line_match = re.compile(r"^dbstore/(.*?) ([0-9a-f]+) ([0-9\-,]*)$")
77 keep = set()
78 with 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
107 database_content.sort()
108 with open("localdb/database.txt", "w") as dbfile:
109  dbfile.writelines(database_content)
110 
111 # Ok, finally remove all unneeded payload files ...
112 for 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