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