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"""
2121from ctypes import c_bool
2222from 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
2932class 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
155159def 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+ "\n enum 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