Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#!/usr/bin/env python3
import sys, math, itertools, re, csv, pprint
from collections import OrderedDict
import io
##############################################################
#
# reading input data, return media properties data
# c.f. https://pdg.lbl.gov/2020/AtomicNuclearProperties/Properties8_Key.pdf
#
def parseData(filename):
with open(filename) as f:
line = f.readline()
while (line.strip() != ""):
entry = {}
# main material data line
entry["sternheimer_index"] = int(line[:5])
entry["sternheimer_label"] = line[5:10].strip()
index = 0
words = line[11:].split()
entry["sign_figures_weight"] = int(words[index])
index += 1
entry["weight"] = float(words[index])
index += 1
entry["error_last_digit"] = 0
if (entry["weight"]>0):
entry["error_last_digit"] = int(words[index])
index += 1
entry["Z_over_A"] = float(words[index])
index += 1
entry["sternheimhers_density"] = float(words[index])
index += 1
entry["corrected_density"] = float(words[index])
index += 1
entry["state"] = words[index] # Solid, Liquid, Gas, Diatomic gas
index += 1
entry["num_elements"] = int(words[index])
index += 1
entry["num_atoms_1"] = int(words[index])
index += 1
entry["num_extra_lines"] = int(words[index])
index += 1
entry["type"] = words[index] # Element, Radioactive, Inorg. comp., Org. comp., Polymer, Mixture, Biological/dosimetry
index += 1
if (index != len(words)):
print ("error in line: " + line + " index=" + str(index) + " len=" + str(len(words)))
sys.exit(1)
# name line
line = f.readline()
words = line.split()
index = 0
if (entry["type"] in ["E", "R"] ):
entry["symbol"] = words[index]
index += 1
entry["name"] = words[index]
index += 1
if (index != len(words)):
print ("error in line: " + line + " index=" + str(index) + " len=" + str(len(words)))
sys.exit(1)
# name+formula line
line = f.readline()
entry["name_and_formula"] = line.strip()
# ionization data
line = f.readline()
words = line.split()
index = 0
entry["Ieff"] = float(words[index])
index += 1
entry["Cbar"] = float(words[index])
index += 1
entry["x0"] = float(words[index])
index += 1
entry["x1"] = float(words[index])
index += 1
entry["aa"] = float(words[index])
index += 1
entry["sk"] = float(words[index])
index += 1
entry["dlt0"] = float(words[index])
index += 1
if (index != len(words)):
print ("error in line: " + line + " index=" + str(index) + " len=" + str(len(words)))
sys.exit(1)
for i in range(entry["num_elements"]):
elem = "element_{}".format(i)
if (not elem in entry):
entry[elem] = {}
line = f.readline()
words = line.split()
index = 0
entry[elem]["Z"] = int(words[index])
index += 1
entry[elem]["Num_frac"] = float(words[index])
index += 1
entry[elem]["weight_frac"] = float(words[index])
index += 1
if (index != len(words)):
print ("error in line: " + line + " index=" + str(index) + " len=" + str(len(words)))
sys.exit(1)
skip = False
for i in range(entry["num_extra_lines"]):
# optional lines
line = f.readline()
if (skip):
continue
key = line[:5]
if (key == " " or
key == "Note:"):
skip = True
continue
n_empty = 0
comment = key
c = 6
while (c<=25):
comment += line[c]
c += 1
if (line[c].strip() == ''):
n_empty += 1
else:
n_empty = 0
if (n_empty > 3):
break
value = float(line[c:45])
if (not "properties" in entry):
entry["properties"] = {}
entry["properties"][key] = value;
line = f.readline() # move to separator line "---------------"
line = f.readline() # move to next entry
yield entry
def TypeEnum(type):
if type=='E':
return "Element"
elif type=='R':
return "RadioactiveElement"
elif type=='I':
return 'InorganicCompound'
elif type=='O':
return "OrganicCompound"
elif type=="P":
return "Polymer"
elif type=='M':
return "Mixture"
elif type=="B":
return "BiologicalDosimetry"
else:
return "Unkonwn"
def StateEnum(state):
if state=='S':
return "Solid"
elif state=='L':
return "Liquid"
elif state=='G':
return 'Gas'
elif state=='D':
return "DiatomicGas"
else:
return "Unkonwn"
def ClassName(name):
name = name.replace('-', '_')
words = name.split('_')
str = ""
for w in words:
str += w.capitalize()
if str[0].isdigit():
str = "_" + str
return str
##########################################################
#
# returns dict containing all data from pythia-xml input
#
def read_data(filename):
data = []
counter = 0
for entry in parseData(filename):
data.append(entry)
return data
###############################################################
#
# return string with a list of classes for all particles
#
def gen_code(media_db):
string = """
// enum for all media
enum class Medium : MediumIntType {
Unkown,
"""
imedium = 0
for entry in media_db:
cname = ClassName(entry["name"])
string += " {} = {} ,\n".format(cname, imedium)
imedium += 1
string += " {} = {} ,\n".format("First", 0)
string += " {} = {} ,\n".format("Last", imedium-1)
return string
###############################################################
#
# return string with a list of classes for all particles
#
def gen_classes(media_db):
string = """
list of C++ classes to access media properties
@{
*/
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
"""
for entry in media_db:
cname = ClassName(entry["name"])
constituents = "{"
comma = ""
for i in range(entry["num_elements"]):
elem = "element_{}".format(i)
constituents += "{}{{ {{ {{\"Z\", {} }}, {{\"NumFrac\", {} }}, {{\"WeightFrac\", {} }} }} }}".format(comma, entry[elem]["Z"],
entry[elem]["Num_frac"],
entry[elem]["weight_frac"])
comma = ", "
constituents += "}"
properties = "{"
if "properties" in entry:
comma = ""
for k,v in entry["properties"].items():
properties += "{}{{ \"{}\", {} }}".format(comma, k, v)
comma = ", "
properties += "}"
symbol = "Unknown";
if ("symbol" in entry):
symbol = entry["symbol"]
class_string = """
/**
*
* Media properties from properties8.dat file from NIST:
* - Sternheimer index: {stern_index}, label: {stern_label}, name: {name}, nice_name: {nice_name}, symbol: {symbol}
* - weight: {weight}, weight_significant_figure: {weight_significant_figure}, weight_error_last_digit: {weight_error_last_digit}
* - Z_over_A: {Z_over_A}, sternheimhers_density: {sternheimer_density}, corrected_density: {corrected_density},
* - StateOfMatter::{state}, MediumType::{type}, Ieff={Ieff}, Cbar={Cbar}, X0={x0}, x1={x1}, aa={aa}, sk={sk}, dlt0={dlt0}
public:
static constexpr Medium medium() {{ return Medium::{cname}; }}

Dominik Baack
committed
static std::string const getName() {{ return data_.getName(); }}
static std::string const getPrettyName() {{ return data_.getPrettyName(); }}
static double getWeight() {{ return data_.getWeight (); }}
static int weight_significant_figure() {{ return data_.weight_significant_figure (); }}
static int weight_error_last_digit() {{ return data_.weight_error_last_digit(); }}
static double Z_over_A() {{ return data_.Z_over_A(); }}

Dominik Baack
committed
static double getSternheimerDensity() {{ return data_.getSternheimerDensity(); }}
static double getCorrectedDensity() {{ return data_.getCorrectedDensity(); }}
static StateOfMatter getStateOfMatter() {{ return data_.getStateOfMatter(); }}

Dominik Baack
committed
static MediumType getType() {{ return data_.getType(); }}
static std::string const getSymbol() {{ return data_.getSymbol(); }}
static double getIeff() {{ return data_.getIeff(); }}
static double getCbar() {{ return data_.getCbar(); }}
static double getX0() {{ return data_.getX0(); }}
static double getX1() {{ return data_.getX1(); }}
static double getAA() {{ return data_.getAA(); }}
static double getSK() {{ return data_.getSK(); }}
static double getDlt0() {{ return data_.getDlt0(); }}
//static constexpr Constituents constituents() {{ return {constituents}; }}
//static constexpr Properties properties() {{ return {properties}; }}
inline static const MediumData data_ {{ "{name}", "{nice_name}", {weight},
{weight_significant_figure}, {weight_error_last_digit}, {Z_over_A},
{sternheimer_density}, {corrected_density}, StateOfMatter::{state},
MediumType::{type}, "{symbol}", {Ieff}, {Cbar}, {x0}, {x1}, {aa}, {sk}, {dlt0} }};
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
}};
""".format(cname=cname,
stern_label=entry["sternheimer_label"],
stern_index=entry["sternheimer_index"],
weight_significant_figure=entry["sign_figures_weight"],
weight=entry["weight"],
weight_error_last_digit=entry["error_last_digit"],
Z_over_A = entry["Z_over_A"],
sternheimer_density = entry["sternheimhers_density"],
corrected_density = entry["corrected_density"],
state=StateEnum(entry["state"]),
type=TypeEnum(entry["type"]),
symbol=symbol,
name=entry["name"],
nice_name=entry["name_and_formula"].replace('\\','\\\\'),
Ieff=entry["Ieff"],
Cbar=entry["Cbar"],
x0=entry["x0"],
x1=entry["x1"],
aa=entry["aa"],
sk=entry["sk"],
dlt0=entry["dlt0"],
constituents=constituents,
properties=properties);
string += class_string
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
return string
###############################################################
#
# return string with a list of classes for all particles
#
def gen_data_array(media_db):
string = """
// array of MediumData entries
static const std::array<const MediumData, static_cast<MediumIntType>(Medium::Last)+1> medium_data = {
"""
comma=""
for entry in media_db:
cname = ClassName(entry["name"])
string += "{} {}::data_".format(comma, cname)
comma = ",\n"
string += " };\n\n"
return string
###############################################################
#
# return string with a list of classes for all particles
#
def gen_media_map(media_db):
string = """
// mapping of enum Medium to Medium classes
static auto MediumMap = std::make_tuple(
"""
comma=""
for entry in media_db:
cname = ClassName(entry["name"])
string += "{} {}()".format(comma, cname)
comma = ",\n"
string += " );\n\n"
return string
###############################################################
#
#
def inc_start():
string = """
// generated by readProperties.py
// MANUAL EDITS ON OWN RISK. THEY WILL BE OVERWRITTEN.
// since this is automatic code, we don't attempt to generate automatic unit testing, too: LCOV_EXCL_START

Dominik Baack
committed
#pragma once
namespace corsika {
"""
return string
###############################################################
#
#
def detail_start():
string = (' /** @} */ \n'
'namespace detail {\n\n')
return string
###############################################################
#
#
def detail_end():
string = "\n}//end namespace detail\n"
return string
###############################################################
#
#
def inc_end():
string = """

Dominik Baack
committed
\n} // end namespace corsika
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
// since this was automatic code, we didn't attempt to generate automatic unit testing, too: LCOV_EXCL_STOP
"""
return string
###################################################################
#
# Main function
#
if __name__ == "__main__":
if len(sys.argv) != 2:
print("usage: {:s} <properties8.dat>".format(sys.argv[0]), file=sys.stderr)
sys.exit(1)
print("\n readProperties.py: automatically produce media properties from input files\n")
media_db = read_data(sys.argv[1])
with open("GeneratedMediaProperties.inc", "w") as f:
print(inc_start(), file=f)
print(gen_code(media_db), file=f)
print(gen_classes(media_db), file=f)
print(detail_start(), file=f)
print(gen_data_array(media_db), file=f)
print(detail_end(), file=f)
print(inc_end(), file=f)