-
Notifications
You must be signed in to change notification settings - Fork 16
/
materials_compendium.py
93 lines (78 loc) · 3.15 KB
/
materials_compendium.py
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
"""Read material densities and compositions from the PNNL Compendium.
The report is:
Detwiler, Rebecca S., McConn, Ronald J., Grimes, Thomas F., Upton, Scott
A., & Engel, Eric J. Compendium of Material Composition Data for Radiation
Transport Modeling. United States. PNNL-15870 Revision 2.
https://doi.org/10.2172/1782721
and it is available at:
https://compendium.cwmd.pnnl.gov
"""
import json
import os
import warnings
import numpy as np
import pandas as pd
from .materials_error import MaterialsWarning, MaterialsError
FNAME = os.path.join(os.path.split(__file__)[0], "MaterialsCompendium.json")
def json_elements_to_weight_fractions(elements):
"""Calculate element weight fractions from the Elements data."""
results = []
for element in elements:
assert element["Element"].isalpha()
line = f"{element['Element']} {element['WeightFraction_whole']:.6f}"
results.append(line)
return results
def json_elements_to_atom_fractions(elements):
"""Calculate element atomic number fractions from the Elements data."""
results = []
for element in elements:
line = f"{element['Element']} {element['AtomFraction_whole']:.6f}"
results.append(line)
return results
def fetch_compendium_data():
"""Read material data from the Compendium."""
# read the file
if not os.path.exists(FNAME):
warnings.warn(
'Material data from the "Compendium of Material Composition Data for '
'Radiation Transport Modeling" cannot be found. If these data are '
"desired, please visit the following URL: "
'https://compendium.cwmd.pnnl.gov and select "Download JSON". Then '
f"move the resulting file to the following path: {FNAME}",
MaterialsWarning,
)
data = []
else:
with open(FNAME, "r") as f:
data = json.load(f)
# extract relevant data
if isinstance(data, list):
print("Pre-March 2022 JSON detected")
elif isinstance(data, dict):
print("Post-March 2022 JSON detected")
if "siteVersion" not in data.keys() or "data" not in data.keys():
raise MaterialsError(
"Attempt to read Compendium JSON failed; "
"dictionary must have keys 'siteVersion' "
"and 'data' but have keys " + str(list(data.keys()))
)
print(f"Compendium data - site version: {data['siteVersion']}")
data = data["data"]
else:
raise MaterialsError(
"Attempt to read Compendium JSON failed; "
"object must be a list or dict but is a " + str(type(data))
)
names = [datum["Name"] for datum in data]
formulae = [datum["Formula"] if "Formula" in datum else "-" for datum in data]
densities = [datum["Density"] for datum in data]
weight_fracs = [
json_elements_to_weight_fractions(datum["Elements"]) for datum in data
]
# assemble data into a dataframe like the NIST data
df = pd.DataFrame()
df["Material"] = names
df["Formula"] = formulae
df["Density"] = np.array(densities, dtype=float)
df["Composition_symbol"] = weight_fracs
return df