Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
generate_particle_data_table.py
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file generate_particle_data_table.py
1 #!/usr/bin/env python3
2 #
3 # use scikit-hep/particle to generate c++ code for the particle data table.
4 #
5 
6 import io
7 import sys
8 import subprocess
9 
10 from particle import Particle
11 
12 
13 def main(output_file):
14  """
15  Generate the code and write it to the given output file.
16  """
17  # extract relevant entries into a single table
18  table = []
19  for p in Particle.all():
20  table.append((int(p.pdgid), int(p.three_charge), p.mass, p.name))
21  # use the extracted table to generate the code
22  code = generate_code(table)
23  code = clang_format(code)
24  output_file.write(code)
25 
26 
27 CODE_HEADER = """\
28 // This file is part of the Acts project.
29 //
30 // Copyright (C) 2020 CERN for the benefit of the Acts project
31 //
32 // This Source Code Form is subject to the terms of the Mozilla Public
33 // License, v. 2.0. If a copy of the MPL was not distributed with this
34 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
35 
36 // The entries within this file have been automatically created using the
37 // particle data files from the 2019 edition of the Review of Particle Physics
38 // by the Berkeley Particle Data Group.
39 
40 #pragma once
41 
42 #include <cstdint>
43 
44 // Rows within the particle data table are sorted by their signed PDG particle
45 // number and are then stored column-wise. Since the PDG particle number column
46 // is sorted it can be used to quickly search for the index of a particle
47 // within all column arrays.
48 
49 """
50 
51 
52 def generate_code(table):
53  """
54  Generate
55  """
56  # ensure the rows are sorted by the signed pdg number (first column)
57  table = sorted(table, key=lambda _: _[0])
58  num_rows = len(table)
59  # name, c++ type, and output format for each column
60  columns = [
61  ("PdgNumber", "int32_t", "{}"),
62  ("ThreeCharge", "int8_t", "{}"),
63  ("MassMeV", "float", "{}f"),
64  ("Name", "char* const ", '"{}"'),
65  ]
66  lines = [
67  CODE_HEADER,
68  f"static constexpr uint32_t kParticlesCount = {num_rows}u;",
69  ]
70  # build a separate array for each column
71  for i, (variable_name, type_name, value_format) in enumerate(columns):
72  lines.append(
73  f"static const {type_name} kParticles{variable_name}[kParticlesCount] = {{"
74  )
75  lines.append(
76  " " + ", ".join(value_format.format(row[i]) for row in table) + ","
77  )
78  lines.append("};")
79  # ensure we end with a newline
80  lines.append("")
81  return "\n".join(lines)
82 
83 
84 def clang_format(content):
85  """
86  Format the given content using clang-format and return it.
87  """
88  args = [
89  "clang-format",
90  "--assume-filename=ParticleData.hpp",
91  "-",
92  ]
93  process = subprocess.run(
94  args,
95  input=content,
96  capture_output=True,
97  check=True,
98  encoding="utf-8",
99  text=True,
100  )
101  return process.stdout
102 
103 
104 if __name__ == "__main__":
105  if 2 < len(sys.argv):
106  print("usage: {} [<output_file>]".format(sys.argv[0]))
107  sys.exit(2)
108  if len(sys.argv) == 1:
109  output_file = sys.stdout
110  else:
111  # will overwrite existing file
112  output_file = io.open(sys.argv[1], mode="wt", encoding="utf-8")
113  main(output_file)