From e6b57f2e6681fa600ed72db01d6dc423ad04a979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 17:33:23 +0200 Subject: [PATCH 1/9] Add main --- .../CommonConstants/make_pdg_header.py | 101 ++++++++++-------- 1 file changed, 55 insertions(+), 46 deletions(-) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index a94450e659acd..0f87ce803ce4f 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -23,7 +23,6 @@ import ROOT # pylint: disable=import-error -name_script = os.path.basename(__file__) # Enum of PDG_t particles class PdgROOT(Enum): @@ -149,6 +148,7 @@ class Pdg(Enum): kHyperHelium4Sigma = 1110020040 kLambda1520_Py = 102134 # PYTHIA code different from PDG + dbPdg = ROOT.o2.O2DatabasePDG @@ -159,49 +159,58 @@ def mass(code): return dbPdg.Mass(code, success) -def declare_mass(pdg, type="double") -> str: +def declare_mass(pdg, val_type="double") -> str: """Returns a C++ declaration of a particle mass constant.""" - return f"constexpr {type} Mass{pdg.name[1:]} = {mass(pdg.value)};\n" - - -# Comment at the beginning of the output -str_block_begin = f"""// BEGINNING OF THE GENERATED BLOCK. -// DO NOT EDIT THIS BLOCK DIRECTLY! -// It has been generated by the {name_script} script. -// For modifications, edit the script and generate this block again. -""" -# Comment at the end of the output -str_block_end = """// END OF THE GENERATED BLOCK -""" -# Start of enum declarations of additional particles -str_enum_head = """/// \\brief Declarations of named PDG codes of particles missing in ROOT PDG_t -/// \\note Follow kCamelCase naming convention -/// \\link https://root.cern/doc/master/TPDGCode_8h.html -enum Pdg { -""" -# End of enum declarations of additional particles -str_enum_foot = "};\n" -# Documentation string for mass declarations of additional particles -str_mass_o2_head = """/// \\brief Declarations of masses for additional particles -""" -# Documentation string for mass declarations of PDG_t particles -str_mass_root_head = """/// \\brief Declarations of masses for particles in ROOT PDG_t -""" - -# Additional particles -str_enum = str_enum_head -str_mass_o2 = str_mass_o2_head -for c in Pdg: - str_enum += f" {c.name} = {c.value},\n" - str_mass_o2 += declare_mass(c) -str_enum = str_enum[:-2] + "\n" # Remove the last comma. -str_enum += str_enum_foot - -# PDG_t particles -str_mass_root = str_mass_root_head -for d in PdgROOT: - str_mass_root += declare_mass(d) - -# Header body -str_header = "\n".join((str_block_begin, str_enum, str_mass_o2, str_mass_root, str_block_end)) -print(str_header) + return f"constexpr {val_type} Mass{pdg.name[1:]} = {mass(pdg.value)};\n" + + +def main(): + """Main function""" + + name_script = os.path.basename(__file__) + + # Comment at the beginning of the output + str_block_begin = "// BEGINNING OF THE GENERATED BLOCK." + # Preamble with instructions + str_block_preamble = ( + "// DO NOT EDIT THIS BLOCK DIRECTLY!" + f"\n// It has been generated by the {name_script} script." + "\n// For modifications, edit the script and generate this block again.\n" + ) + # Comment at the end of the output + str_block_end = "// END OF THE GENERATED BLOCK" + # Start of enum declarations of additional particles + str_enum_head = ( + "/// \\brief Declarations of named PDG codes of particles missing in ROOT PDG_t" + "\n/// \\note Follow kCamelCase naming convention" + "\n/// \\link https://root.cern/doc/master/TPDGCode_8h.html" + "\nenum Pdg {" + ) + # End of enum declarations of additional particles + str_enum_foot = "};\n" + # Documentation string for mass declarations of additional particles + str_mass_o2_head = "/// \\brief Declarations of masses for additional particles" + # Documentation string for mass declarations of PDG_t particles + str_mass_root_head = "/// \\brief Declarations of masses for particles in ROOT PDG_t" + + # Additional particles + str_enum = str_enum_head + str_mass_o2 = str_mass_o2_head + for c in Pdg: + str_enum += f" {c.name} = {c.value},\n" + str_mass_o2 += declare_mass(c) + str_enum = str_enum[:-2] + "\n" # Remove the last comma. + str_enum += str_enum_foot + + # PDG_t particles + str_mass_root = str_mass_root_head + for d in PdgROOT: + str_mass_root += declare_mass(d) + + # Header body + str_header = "\n".join((str_block_begin, str_block_preamble, str_enum, str_mass_o2, str_mass_root, str_block_end)) + print(str_header) + + +if __name__ == "__main__": + main() From d9b80ebbbde59df04050f527324377d2e4c18958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 18:39:08 +0200 Subject: [PATCH 2/9] Produce the whole file --- .../CommonConstants/make_pdg_header.py | 85 ++++++++++++++----- 1 file changed, 64 insertions(+), 21 deletions(-) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index 0f87ce803ce4f..e14a4407e8c80 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -18,6 +18,7 @@ """ import os +import sys from ctypes import c_bool from enum import Enum @@ -161,7 +162,7 @@ def mass(code): def declare_mass(pdg, val_type="double") -> str: """Returns a C++ declaration of a particle mass constant.""" - return f"constexpr {val_type} Mass{pdg.name[1:]} = {mass(pdg.value)};\n" + return f"constexpr {val_type} Mass{pdg.name[1:]} = {mass(pdg.value)};" def main(): @@ -170,46 +171,88 @@ def main(): name_script = os.path.basename(__file__) # Comment at the beginning of the output - str_block_begin = "// BEGINNING OF THE GENERATED BLOCK." + block_begin = "// BEGINNING OF THE GENERATED BLOCK." # Preamble with instructions - str_block_preamble = ( + block_preamble = ( "// DO NOT EDIT THIS BLOCK DIRECTLY!" f"\n// It has been generated by the {name_script} script." - "\n// For modifications, edit the script and generate this block again.\n" + "\n// For modifications, edit the script and generate this block again." ) # Comment at the end of the output - str_block_end = "// END OF THE GENERATED BLOCK" + block_end = "// END OF THE GENERATED BLOCK" # Start of enum declarations of additional particles - str_enum_head = ( + enum_o2_head = ( "/// \\brief Declarations of named PDG codes of particles missing in ROOT PDG_t" "\n/// \\note Follow kCamelCase naming convention" "\n/// \\link https://root.cern/doc/master/TPDGCode_8h.html" "\nenum Pdg {" ) # End of enum declarations of additional particles - str_enum_foot = "};\n" + enum_o2_foot = "};" # Documentation string for mass declarations of additional particles - str_mass_o2_head = "/// \\brief Declarations of masses for additional particles" + mass_o2_head = "/// \\brief Declarations of masses for additional particles" # Documentation string for mass declarations of PDG_t particles - str_mass_root_head = "/// \\brief Declarations of masses for particles in ROOT PDG_t" + mass_root_head = "/// \\brief Declarations of masses for particles in ROOT PDG_t" + + # Get header content before and after the generated block. + path_header = "PhysicsConstants.h" + try: + with open(path_header, encoding="utf-8") as file: + content_old = file.readlines() + except OSError: + print(f'Failed to open file "{path_header}".') + sys.exit(1) + lines_header_before: list[str] = [] + lines_header_after: list[str] = [] + got_block_begin = False + got_block_end = False + for line in content_old: + line = line.strip() + if line == block_begin: + got_block_begin = True + if not got_block_begin: + lines_header_before.append(line) + if got_block_end: + lines_header_after.append(line) + if line == block_end: + got_block_end = True + if not got_block_begin: + raise ValueError("Did not find the beginning of the block.") + if not got_block_end: + raise ValueError("Did not find the end of the block.") # Additional particles - str_enum = str_enum_head - str_mass_o2 = str_mass_o2_head - for c in Pdg: - str_enum += f" {c.name} = {c.value},\n" - str_mass_o2 += declare_mass(c) - str_enum = str_enum[:-2] + "\n" # Remove the last comma. - str_enum += str_enum_foot + lines_enum_o2: list[str] = [enum_o2_head] + lines_mass_o2: list[str] = [mass_o2_head] + for pdg_o2 in Pdg: + lines_enum_o2.append(f" {pdg_o2.name} = {pdg_o2.value},") + lines_mass_o2.append(declare_mass(pdg_o2)) + lines_enum_o2[-1] = lines_enum_o2[-1][:-1] # Remove the last comma. + lines_enum_o2.append(enum_o2_foot) # PDG_t particles - str_mass_root = str_mass_root_head - for d in PdgROOT: - str_mass_root += declare_mass(d) + lines_mass_root: list[str] = [mass_root_head] + for pdg_root in PdgROOT: + lines_mass_root.append(declare_mass(pdg_root)) # Header body - str_header = "\n".join((str_block_begin, str_block_preamble, str_enum, str_mass_o2, str_mass_root, str_block_end)) - print(str_header) + content_new = "\n".join( + ( + *lines_header_before, + block_begin, + block_preamble, + "", + *lines_enum_o2, + "", + *lines_mass_o2, + "", + *lines_mass_root, + "", + block_end, + *lines_header_after, + ) + ) + print(content_new) if __name__ == "__main__": From b57b40ddb3b53056ecd16d385f3d65a3068ccc76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 18:54:45 +0200 Subject: [PATCH 3/9] Write to the file --- .../include/CommonConstants/make_pdg_header.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index e14a4407e8c80..651b83ecfeb08 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -196,6 +196,7 @@ def main(): # Get header content before and after the generated block. path_header = "PhysicsConstants.h" + print(f"File {path_header} will be updated.") try: with open(path_header, encoding="utf-8") as file: content_old = file.readlines() @@ -252,7 +253,15 @@ def main(): *lines_header_after, ) ) - print(content_new) + # print(content_new) + + try: + with open(path_header, "w", encoding="utf-8") as file: + file.write(content_new) + print(f"File {path_header} has been overwritten.") + except OSError: + print(f'Failed to write to file "{path_header}".') + sys.exit(1) if __name__ == "__main__": From 972a01298384bb87fb23ed0dc52cbbde7c3dbfad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 19:05:31 +0200 Subject: [PATCH 4/9] Cosmetics --- Common/Constants/include/CommonConstants/make_pdg_header.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index 651b83ecfeb08..edb73c03e658c 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -160,14 +160,15 @@ def mass(code): return dbPdg.Mass(code, success) -def declare_mass(pdg, val_type="double") -> str: +def declare_mass(pdg, mass_type="double") -> str: """Returns a C++ declaration of a particle mass constant.""" - return f"constexpr {val_type} Mass{pdg.name[1:]} = {mass(pdg.value)};" + return f"constexpr {mass_type} Mass{pdg.name[1:]} = {mass(pdg.value)};" def main(): """Main function""" + path_header = "PhysicsConstants.h" name_script = os.path.basename(__file__) # Comment at the beginning of the output @@ -195,7 +196,6 @@ def main(): mass_root_head = "/// \\brief Declarations of masses for particles in ROOT PDG_t" # Get header content before and after the generated block. - path_header = "PhysicsConstants.h" print(f"File {path_header} will be updated.") try: with open(path_header, encoding="utf-8") as file: From 31ef2d14a387edc2ec2a722f02bb2a82d8ef315b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 19:10:12 +0200 Subject: [PATCH 5/9] Update docstring --- Common/Constants/include/CommonConstants/make_pdg_header.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index edb73c03e658c..0810cd54e290b 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -12,7 +12,7 @@ # or submit itself to any jurisdiction. """! -@brief Generates the body of a C++ header with PDG codes and particle masses. +@brief Generates and updates the body of a C++ header with PDG codes and particle masses. @author Vít Kučera , Inha University @date 2023-09-21 """ From c4297afd3744208fdf8987cdec9bdb1aaa2c65fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 19:32:14 +0200 Subject: [PATCH 6/9] Write a newline at the EOF --- Common/Constants/include/CommonConstants/make_pdg_header.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index 0810cd54e290b..29ff442f7a5a5 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -251,6 +251,7 @@ def main(): "", block_end, *lines_header_after, + "", ) ) # print(content_new) From eb014f6121a2edbea27c7695cc966ab78402dda0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 19:39:33 +0200 Subject: [PATCH 7/9] Cosmetics --- Common/Constants/include/CommonConstants/make_pdg_header.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index 29ff442f7a5a5..edfe3b875bdaf 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -173,14 +173,14 @@ def main(): # Comment at the beginning of the output block_begin = "// BEGINNING OF THE GENERATED BLOCK." + # Comment at the end of the output + block_end = "// END OF THE GENERATED BLOCK" # Preamble with instructions block_preamble = ( "// DO NOT EDIT THIS BLOCK DIRECTLY!" f"\n// It has been generated by the {name_script} script." "\n// For modifications, edit the script and generate this block again." ) - # Comment at the end of the output - block_end = "// END OF THE GENERATED BLOCK" # Start of enum declarations of additional particles enum_o2_head = ( "/// \\brief Declarations of named PDG codes of particles missing in ROOT PDG_t" @@ -256,6 +256,7 @@ def main(): ) # print(content_new) + # Overwrite the input file. try: with open(path_header, "w", encoding="utf-8") as file: file.write(content_new) From cce313e357e59d297e83798723aaa80a27f5a7bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 19:55:56 +0200 Subject: [PATCH 8/9] Check loaded environment --- .../Constants/include/CommonConstants/make_pdg_header.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index edfe3b875bdaf..4f0912a30ea57 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -22,7 +22,11 @@ from ctypes import c_bool from enum import Enum -import ROOT # pylint: disable=import-error +try: + import ROOT # pylint: disable=import-error + from ROOT import o2 +except (ModuleNotFoundError, ImportError) as exc: + raise Exception("O2 environment is not loaded.") from exc # Enum of PDG_t particles @@ -150,7 +154,7 @@ class Pdg(Enum): kLambda1520_Py = 102134 # PYTHIA code different from PDG -dbPdg = ROOT.o2.O2DatabasePDG +dbPdg = o2.O2DatabasePDG def mass(code): From 869930e351f023020c9ae912122579b15202d16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Oct 2025 20:04:03 +0200 Subject: [PATCH 9/9] Improve exception handling --- .../include/CommonConstants/make_pdg_header.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index 4f0912a30ea57..f83c44bb401db 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -18,7 +18,6 @@ """ import os -import sys from ctypes import c_bool from enum import Enum @@ -26,7 +25,7 @@ import ROOT # pylint: disable=import-error from ROOT import o2 except (ModuleNotFoundError, ImportError) as exc: - raise Exception("O2 environment is not loaded.") from exc + raise OSError("O2 environment is not loaded.") from exc # Enum of PDG_t particles @@ -200,13 +199,12 @@ def main(): mass_root_head = "/// \\brief Declarations of masses for particles in ROOT PDG_t" # Get header content before and after the generated block. - print(f"File {path_header} will be updated.") + print(f'File "{path_header}" will be updated.') try: with open(path_header, encoding="utf-8") as file: content_old = file.readlines() - except OSError: - print(f'Failed to open file "{path_header}".') - sys.exit(1) + except OSError as exc: + raise OSError(f'Failed to open file "{path_header}".') from exc lines_header_before: list[str] = [] lines_header_after: list[str] = [] got_block_begin = False @@ -264,10 +262,9 @@ def main(): try: with open(path_header, "w", encoding="utf-8") as file: file.write(content_new) - print(f"File {path_header} has been overwritten.") - except OSError: - print(f'Failed to write to file "{path_header}".') - sys.exit(1) + print(f'File "{path_header}" has been overwritten.') + except OSError as exc: + raise OSError(f'Failed to write to file "{path_header}".') from exc if __name__ == "__main__":