diff --git a/becquerel/tools/materials_compendium.py b/becquerel/tools/materials_compendium.py index af5988ba..0e2af699 100644 --- a/becquerel/tools/materials_compendium.py +++ b/becquerel/tools/materials_compendium.py @@ -18,7 +18,7 @@ import warnings import numpy as np import pandas as pd -from .materials_error import MaterialsWarning +from .materials_error import MaterialsWarning, MaterialsError FNAME = os.path.join(os.path.split(__file__)[0], "MaterialsCompendium.json") @@ -60,6 +60,23 @@ def fetch_compendium_data(): 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] diff --git a/tests/materials_test.py b/tests/materials_test.py index ced6db6b..6fe3a4fe 100644 --- a/tests/materials_test.py +++ b/tests/materials_test.py @@ -87,8 +87,11 @@ def test_materials_dummy_csv(): @pytest.mark.webtest -def test_materials_dummy_compendium(): - """Test fetch_materials with a dummy Compendium JSON file.""" +def test_materials_dummy_compendium_pre2022(): + """Test fetch_materials with a dummy Compendium JSON file. + + The dummy JSON file uses the format seen prior to March 2022. + """ # point to an generate a dummy JSON file fname_orig = materials_compendium.FNAME materials_compendium.FNAME = fname_orig[:-5] + "_dummy.json" @@ -128,6 +131,79 @@ def test_materials_dummy_compendium(): materials_compendium.FNAME = fname_orig +@pytest.mark.webtest +def test_materials_dummy_compendium_2022(): + """Test fetch_materials with a dummy Compendium JSON file. + + The dummy JSON file uses the format first seen in March 2022. + """ + # point to an generate a dummy JSON file + fname_orig = materials_compendium.FNAME + materials_compendium.FNAME = fname_orig[:-5] + "_dummy.json" + data = { + "siteVersion": "0.0.0", + "data": [ + { + "Density": 8.4e-5, + "Elements": [ + { + "AtomFraction_whole": 1.0, + "Element": "H", + "WeightFraction_whole": 1.0, + } + ], + "Formula": "H2", + "Name": "Hydrogen", + }, + { + "Density": 1.16e-3, + "Elements": [ + { + "AtomFraction_whole": 1.0, + "Element": "N", + "WeightFraction_whole": 1.0, + } + ], + "Formula": "N2", + "Name": "Nitrogen", + }, + ], + } + with open(materials_compendium.FNAME, "w") as f: + json.dump(data, f, indent=4) + with pytest.warns(None) as record: + materials._load_and_compile_materials() + assert len(record) == 0, "Expected no MaterialsWarnings to be raised" + # remove siteVersion and make sure there is an error raised + del data["siteVersion"] + with open(materials_compendium.FNAME, "w") as f: + json.dump(data, f, indent=4) + with pytest.raises(MaterialsError): + materials._load_and_compile_materials() + # remove the dummy file and point back to original + os.remove(materials_compendium.FNAME) + materials_compendium.FNAME = fname_orig + + +@pytest.mark.webtest +def test_materials_dummy_compendium_error(): + """Test fetch_materials with a dummy Compendium JSON file. + + The dummy JSON file returns something that is not a list or dict. + """ + # point to an generate a dummy JSON file + fname_orig = materials_compendium.FNAME + materials_compendium.FNAME = fname_orig[:-5] + "_dummy.json" + data = None + with open(materials_compendium.FNAME, "w") as f: + json.dump(data, f, indent=4) + with pytest.raises(MaterialsError): + materials._load_and_compile_materials() + # remove the dummy file and point back to original + os.remove(materials_compendium.FNAME) + materials_compendium.FNAME = fname_orig + + @pytest.mark.webtest def test_materials_no_compendium(): """Test fetch_materials with no Compendium JSON file."""