Skip to content

Commit e2abca4

Browse files
authored
Improve the PDG header script (#14769)
* Add main * Produce the whole file * Write to the file * Cosmetics * Update docstring * Write a newline at the EOF * Cosmetics * Check loaded environment * Improve exception handling
1 parent 80f2bea commit e2abca4

File tree

1 file changed

+110
-46
lines changed

1 file changed

+110
-46
lines changed

Common/Constants/include/CommonConstants/make_pdg_header.py

Lines changed: 110 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# or submit itself to any jurisdiction.
1313

1414
"""!
15-
@brief Generates the body of a C++ header with PDG codes and particle masses.
15+
@brief Generates and updates the body of a C++ header with PDG codes and particle masses.
1616
@author Vít Kučera <vit.kucera@cern.ch>, Inha University
1717
@date 2023-09-21
1818
"""
@@ -21,9 +21,12 @@
2121
from ctypes import c_bool
2222
from enum import Enum
2323

24-
import ROOT # pylint: disable=import-error
24+
try:
25+
import ROOT # pylint: disable=import-error
26+
from ROOT import o2
27+
except (ModuleNotFoundError, ImportError) as exc:
28+
raise OSError("O2 environment is not loaded.") from exc
2529

26-
name_script = os.path.basename(__file__)
2730

2831
# Enum of PDG_t particles
2932
class PdgROOT(Enum):
@@ -149,7 +152,8 @@ class Pdg(Enum):
149152
kHyperHelium4Sigma = 1110020040
150153
kLambda1520_Py = 102134 # PYTHIA code different from PDG
151154

152-
dbPdg = ROOT.o2.O2DatabasePDG
155+
156+
dbPdg = o2.O2DatabasePDG
153157

154158

155159
def mass(code):
@@ -159,49 +163,109 @@ def mass(code):
159163
return dbPdg.Mass(code, success)
160164

161165

162-
def declare_mass(pdg, type="double") -> str:
166+
def declare_mass(pdg, mass_type="double") -> str:
163167
"""Returns a C++ declaration of a particle mass constant."""
164-
return f"constexpr {type} Mass{pdg.name[1:]} = {mass(pdg.value)};\n"
168+
return f"constexpr {mass_type} Mass{pdg.name[1:]} = {mass(pdg.value)};"
165169

166170

167-
# Comment at the beginning of the output
168-
str_block_begin = f"""// BEGINNING OF THE GENERATED BLOCK.
169-
// DO NOT EDIT THIS BLOCK DIRECTLY!
170-
// It has been generated by the {name_script} script.
171-
// For modifications, edit the script and generate this block again.
172-
"""
173-
# Comment at the end of the output
174-
str_block_end = """// END OF THE GENERATED BLOCK
175-
"""
176-
# Start of enum declarations of additional particles
177-
str_enum_head = """/// \\brief Declarations of named PDG codes of particles missing in ROOT PDG_t
178-
/// \\note Follow kCamelCase naming convention
179-
/// \\link https://root.cern/doc/master/TPDGCode_8h.html
180-
enum Pdg {
181-
"""
182-
# End of enum declarations of additional particles
183-
str_enum_foot = "};\n"
184-
# Documentation string for mass declarations of additional particles
185-
str_mass_o2_head = """/// \\brief Declarations of masses for additional particles
186-
"""
187-
# Documentation string for mass declarations of PDG_t particles
188-
str_mass_root_head = """/// \\brief Declarations of masses for particles in ROOT PDG_t
189-
"""
171+
def main():
172+
"""Main function"""
173+
174+
path_header = "PhysicsConstants.h"
175+
name_script = os.path.basename(__file__)
176+
177+
# Comment at the beginning of the output
178+
block_begin = "// BEGINNING OF THE GENERATED BLOCK."
179+
# Comment at the end of the output
180+
block_end = "// END OF THE GENERATED BLOCK"
181+
# Preamble with instructions
182+
block_preamble = (
183+
"// DO NOT EDIT THIS BLOCK DIRECTLY!"
184+
f"\n// It has been generated by the {name_script} script."
185+
"\n// For modifications, edit the script and generate this block again."
186+
)
187+
# Start of enum declarations of additional particles
188+
enum_o2_head = (
189+
"/// \\brief Declarations of named PDG codes of particles missing in ROOT PDG_t"
190+
"\n/// \\note Follow kCamelCase naming convention"
191+
"\n/// \\link https://root.cern/doc/master/TPDGCode_8h.html"
192+
"\nenum Pdg {"
193+
)
194+
# End of enum declarations of additional particles
195+
enum_o2_foot = "};"
196+
# Documentation string for mass declarations of additional particles
197+
mass_o2_head = "/// \\brief Declarations of masses for additional particles"
198+
# Documentation string for mass declarations of PDG_t particles
199+
mass_root_head = "/// \\brief Declarations of masses for particles in ROOT PDG_t"
200+
201+
# Get header content before and after the generated block.
202+
print(f'File "{path_header}" will be updated.')
203+
try:
204+
with open(path_header, encoding="utf-8") as file:
205+
content_old = file.readlines()
206+
except OSError as exc:
207+
raise OSError(f'Failed to open file "{path_header}".') from exc
208+
lines_header_before: list[str] = []
209+
lines_header_after: list[str] = []
210+
got_block_begin = False
211+
got_block_end = False
212+
for line in content_old:
213+
line = line.strip()
214+
if line == block_begin:
215+
got_block_begin = True
216+
if not got_block_begin:
217+
lines_header_before.append(line)
218+
if got_block_end:
219+
lines_header_after.append(line)
220+
if line == block_end:
221+
got_block_end = True
222+
if not got_block_begin:
223+
raise ValueError("Did not find the beginning of the block.")
224+
if not got_block_end:
225+
raise ValueError("Did not find the end of the block.")
226+
227+
# Additional particles
228+
lines_enum_o2: list[str] = [enum_o2_head]
229+
lines_mass_o2: list[str] = [mass_o2_head]
230+
for pdg_o2 in Pdg:
231+
lines_enum_o2.append(f" {pdg_o2.name} = {pdg_o2.value},")
232+
lines_mass_o2.append(declare_mass(pdg_o2))
233+
lines_enum_o2[-1] = lines_enum_o2[-1][:-1] # Remove the last comma.
234+
lines_enum_o2.append(enum_o2_foot)
235+
236+
# PDG_t particles
237+
lines_mass_root: list[str] = [mass_root_head]
238+
for pdg_root in PdgROOT:
239+
lines_mass_root.append(declare_mass(pdg_root))
240+
241+
# Header body
242+
content_new = "\n".join(
243+
(
244+
*lines_header_before,
245+
block_begin,
246+
block_preamble,
247+
"",
248+
*lines_enum_o2,
249+
"",
250+
*lines_mass_o2,
251+
"",
252+
*lines_mass_root,
253+
"",
254+
block_end,
255+
*lines_header_after,
256+
"",
257+
)
258+
)
259+
# print(content_new)
260+
261+
# Overwrite the input file.
262+
try:
263+
with open(path_header, "w", encoding="utf-8") as file:
264+
file.write(content_new)
265+
print(f'File "{path_header}" has been overwritten.')
266+
except OSError as exc:
267+
raise OSError(f'Failed to write to file "{path_header}".') from exc
268+
190269

191-
# Additional particles
192-
str_enum = str_enum_head
193-
str_mass_o2 = str_mass_o2_head
194-
for c in Pdg:
195-
str_enum += f" {c.name} = {c.value},\n"
196-
str_mass_o2 += declare_mass(c)
197-
str_enum = str_enum[:-2] + "\n" # Remove the last comma.
198-
str_enum += str_enum_foot
199-
200-
# PDG_t particles
201-
str_mass_root = str_mass_root_head
202-
for d in PdgROOT:
203-
str_mass_root += declare_mass(d)
204-
205-
# Header body
206-
str_header = "\n".join((str_block_begin, str_enum, str_mass_o2, str_mass_root, str_block_end))
207-
print(str_header)
270+
if __name__ == "__main__":
271+
main()

0 commit comments

Comments
 (0)