From c58bb59d8a44d2b044f6deb8bc717dffc433889a Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 22 Sep 2025 09:20:54 -0400 Subject: [PATCH 01/14] simon template for examples testing --- .../solutions/diffpy-cmi/fitBulkNi.py | 2 +- tests/conftest.py | 19 +++++++++++++++++++ tests/test_examples.py | 8 ++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/test_examples.py diff --git a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py index 5ff8f65..ce58d9d 100644 --- a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py +++ b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py @@ -33,7 +33,7 @@ # First we store the absolute directory of this script, # then two directories above this,with the directory # 'data' appended -PWD = Path(__file__).parent.absolute() +PWD = Path(__file__).parent.resolve() DPATH = PWD.parent.parent / "data" # 3: Give an identifying name for the refinement, similar diff --git a/tests/conftest.py b/tests/conftest.py index e3b6313..cf27678 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,27 @@ import json + +# tests/conftest.py +import shutil from pathlib import Path import pytest +PROJECT_ROOT = Path(__file__).resolve().parents[1] +EXAMPLES_ROOT = PROJECT_ROOT / "docs" / "examples" + + +@pytest.fixture(scope="session") +def tmp_examples(tmp_path_factory): + """Copy the entire examples/ tree into a temp directory once per + test session. + + Returns the path to that copy. + """ + tmpdir = tmp_path_factory.mktemp("examples") + tmp_examples = tmpdir / "examples" + shutil.copytree(EXAMPLES_ROOT, tmp_examples) + yield tmp_examples + @pytest.fixture def user_filesystem(tmp_path): diff --git a/tests/test_examples.py b/tests/test_examples.py new file mode 100644 index 0000000..00907fd --- /dev/null +++ b/tests/test_examples.py @@ -0,0 +1,8 @@ +import runpy + + +def test_all_examples(tmp_examples): + scripts = list(tmp_examples.rglob("**/solutions/diffpy-cmi/*.py")) + for script_path in scripts: + print(f"Testing {script_path.relative_to(tmp_examples)}") + runpy.run_path(str(script_path), run_name="__main__") From 7cb8a665e82229b72fb19de3373440780490190a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 10:53:27 -0400 Subject: [PATCH 02/14] add psutils to tests.txt --- requirements/tests.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements/tests.txt b/requirements/tests.txt index fde0e31..24664ee 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -8,3 +8,4 @@ pytest-env pytest-mock freezegun DeepDiff +psutils From 86d91e85b7ef22ccf3be964c74976f8423e0d8fe Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 10:53:57 -0400 Subject: [PATCH 03/14] condition that sets qdamp and qbroad if Ni fit is not ran --- docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py index 35f164d..243c06b 100644 --- a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py +++ b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py @@ -87,7 +87,9 @@ print("The Ni example refines instrument parameters\n") print("The instrument parameters are necessary to run this fit\n") print("Please run the Ni example first\n") - + print("Setting Q_damp and Q_broad to the refined values\n") + QDAMP_I = 0.045298 + QBROAD_I = 0.016809 # If we want to run using multiprocessors, we can switch this to 'True'. # This requires that the 'psutil' python package installed. RUN_PARALLEL = False From c8883e86c078c3c751233f686d6bcc86ea2c649a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 11:48:16 -0400 Subject: [PATCH 04/14] change mpl backend and remove old stylesheets --- .../ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py | 4 ---- .../ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py | 3 --- tests/conftest.py | 7 +++++++ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py b/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py index 2200179..e467803 100644 --- a/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py +++ b/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py @@ -447,10 +447,6 @@ def plot_results(recipe, fig_name): # Change some style details of the plot mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py b/docs/examples/ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py index 316948b..98fdae0 100644 --- a/docs/examples/ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py +++ b/docs/examples/ch11ClusterXYZ/solutions/diffpy-cmi/fitCdSeNP.py @@ -199,9 +199,6 @@ def plot_results(recipe, figname): diff = g - gcalc + diffzero mpl.rcParams.update(mpl.rcParamsDefault) - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) fig, ax1 = plt.subplots(1, 1) diff --git a/tests/conftest.py b/tests/conftest.py index cf27678..8565242 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,6 +4,7 @@ import shutil from pathlib import Path +import matplotlib import pytest PROJECT_ROOT = Path(__file__).resolve().parents[1] @@ -23,6 +24,12 @@ def tmp_examples(tmp_path_factory): yield tmp_examples +@pytest.fixture(scope="session", autouse=True) +def use_headless_matplotlib(): + """Force matplotlib to use a headless backend during tests.""" + matplotlib.use("Agg") + + @pytest.fixture def user_filesystem(tmp_path): base_dir = Path(tmp_path) From 199630b8e100bb3d63e4fe33d4253be690bcd322 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 11:51:51 -0400 Subject: [PATCH 05/14] news --- news/example-ci.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/example-ci.rst diff --git a/news/example-ci.rst b/news/example-ci.rst new file mode 100644 index 0000000..d0453da --- /dev/null +++ b/news/example-ci.rst @@ -0,0 +1,23 @@ +**Added:** + +* Add tests that run PDF example scripts + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From b40a87f0e2bcaabbb23d92429221644d6d9fc164 Mon Sep 17 00:00:00 2001 From: Caden Myers <158210249+cadenmyers13@users.noreply.github.com> Date: Mon, 22 Sep 2025 11:54:03 -0400 Subject: [PATCH 06/14] Remove comment from tests/conftest.py --- tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 8565242..1e1cbba 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,5 @@ import json -# tests/conftest.py import shutil from pathlib import Path From c7b94c49a482733dd925b39d9d30830ac9787aec Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 15:54:15 +0000 Subject: [PATCH 07/14] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 1e1cbba..3eaae7d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,4 @@ import json - import shutil from pathlib import Path From 949039422c4ba2059a615d1744a33129678a043b Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 11:57:21 -0400 Subject: [PATCH 08/14] fix typo in psutil name --- requirements/tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/tests.txt b/requirements/tests.txt index 24664ee..ac9ed7e 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -8,4 +8,4 @@ pytest-env pytest-mock freezegun DeepDiff -psutils +psutil From 5a1091af869de7dbe9ed788adcc32632e87dfc35 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 14:50:59 -0400 Subject: [PATCH 09/14] Add special handling to get Qdamp and Qbroad params --- .../solutions/diffpy-cmi/fitNPPt.py | 4 +- tests/test_examples.py | 39 ++++++++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py index 243c06b..35f164d 100644 --- a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py +++ b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py @@ -87,9 +87,7 @@ print("The Ni example refines instrument parameters\n") print("The instrument parameters are necessary to run this fit\n") print("Please run the Ni example first\n") - print("Setting Q_damp and Q_broad to the refined values\n") - QDAMP_I = 0.045298 - QBROAD_I = 0.016809 + # If we want to run using multiprocessors, we can switch this to 'True'. # This requires that the 'psutil' python package installed. RUN_PARALLEL = False diff --git a/tests/test_examples.py b/tests/test_examples.py index 00907fd..22b968c 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -1,8 +1,43 @@ +import re import runpy +def get_instrument_params(res_file): + """Parse Qdamp and Qbroad from a .res file.""" + qdamp = qbroad = None + with open(res_file, "r") as f: + for line in f: + if line.startswith("Calib_Qbroad"): + qbroad = float(re.split(r"\s+", line.strip())[1]) + elif line.startswith("Calib_Qdamp"): + qdamp = float(re.split(r"\s+", line.strip())[1]) + return qdamp, qbroad + + def test_all_examples(tmp_examples): - scripts = list(tmp_examples.rglob("**/solutions/diffpy-cmi/*.py")) + """Run all example scripts to ensure they execute without error.""" + # Run Ni example first to produce .res file + ni_script = list(tmp_examples.rglob("**/FitBulkNi.py"))[0] + runpy.run_path(str(ni_script), run_name="__main__") + res_file = ni_script.parent / "res" / "Fit_Ni_Bulk.res" + assert res_file.exists(), f"Ni results file not found: {res_file}" + + qdamp_i, qbroad_i = get_instrument_params(res_file) + pt_script = list(tmp_examples.rglob("**/fitNPPt.py"))[0] + refined_Ni_params = {"QDAMP_I": qdamp_i, "QBROAD_I": qbroad_i} + # run the NPPt script with the refined Ni params + runpy.run_path( + str(pt_script), run_name="__main__", init_globals=refined_Ni_params + ) + + # Run all other example scripts, patching the instrument values + all_scripts = list(tmp_examples.rglob("**/solutions/diffpy-cmi/*.py")) + scripts = [ + s for s in all_scripts if s.name not in ("fitBulkNi.py", "fitNPPt.py") + ] for script_path in scripts: print(f"Testing {script_path.relative_to(tmp_examples)}") - runpy.run_path(str(script_path), run_name="__main__") + mod_globals = {"QDAMP_I": qdamp_i, "QBROAD_I": qbroad_i} + runpy.run_path( + str(script_path), run_name="__main__", init_globals=mod_globals + ) From ba6825a72510908f09c2fc4e740722bf61fa8fb5 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 15:09:09 -0400 Subject: [PATCH 10/14] add bg stylesheets --- .../solutions/diffpy-cmi/fitBulkNi.py | 10 ++-------- .../solutions/diffpy-cmi/fitNPPt.py | 10 ++-------- .../ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py | 10 ++-------- .../solutions/diffpy-cmi/fitCrystalGen.py | 16 ++-------------- .../solutions/diffpy-cmi/fitTSeries.py | 16 ++-------------- 5 files changed, 10 insertions(+), 52 deletions(-) diff --git a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py index ce58d9d..599b0a2 100644 --- a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py +++ b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py @@ -9,9 +9,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -25,6 +25,7 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser +plt.style.use(all_styles["bg-style"]) # Config # 2: Give a file path to where your PDF (.gr) and # structure (.cif) files are located. @@ -264,13 +265,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py index 35f164d..f00afb4 100644 --- a/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py +++ b/docs/examples/ch03NiModelling/solutions/diffpy-cmi/fitNPPt.py @@ -13,9 +13,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -30,6 +30,7 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser +plt.style.use(all_styles["bg-style"]) # Config ############################## # 2: Give a file path to where your PDF (.gr) and structure (.cif) files # are located. @@ -241,13 +242,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py b/docs/examples/ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py index cd06828..3e12439 100644 --- a/docs/examples/ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py +++ b/docs/examples/ch05Fit2Phase/solutions/diffpy-cmi/fit2P.py @@ -10,9 +10,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -26,6 +26,7 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser +plt.style.use(all_styles["bg-style"]) # Config ############################## # 2: Give a file path to where your pdf (.gr) and (.cif) files are located. PWD = Path(__file__).parent.absolute() @@ -271,13 +272,6 @@ def plot_results(recipe, fig_name): ni_signal = ni_scale * recipe.crystal.G_Ni.profile.ycalc ni_signal += min(si_signal) - np.abs(max(ni_signal)) - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch06RefineCrystalStructureGen/solutions/diffpy-cmi/fitCrystalGen.py b/docs/examples/ch06RefineCrystalStructureGen/solutions/diffpy-cmi/fitCrystalGen.py index aa9feb8..75a5c9c 100644 --- a/docs/examples/ch06RefineCrystalStructureGen/solutions/diffpy-cmi/fitCrystalGen.py +++ b/docs/examples/ch06RefineCrystalStructureGen/solutions/diffpy-cmi/fitCrystalGen.py @@ -10,9 +10,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -27,12 +27,7 @@ from diffpy.structure.atom import Atom from diffpy.structure.parsers import getParser -try: - from bg_mpl_stylesheets.bg_mpl_stylesheet import bg_mpl_style - - plt.style.use(bg_mpl_style) -except ImportError: - pass +plt.style.use(all_styles["bg-style"]) # Config ############################## # 2: Give a file path to where your pdf (.gr) and (.cif) files are located. @@ -246,13 +241,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) diff --git a/docs/examples/ch07StructuralPhaseTransitions/solutions/diffpy-cmi/fitTSeries.py b/docs/examples/ch07StructuralPhaseTransitions/solutions/diffpy-cmi/fitTSeries.py index b7d03e5..654c50e 100644 --- a/docs/examples/ch07StructuralPhaseTransitions/solutions/diffpy-cmi/fitTSeries.py +++ b/docs/examples/ch07StructuralPhaseTransitions/solutions/diffpy-cmi/fitTSeries.py @@ -9,9 +9,9 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np +from bg_mpl_stylesheets.styles import all_styles from scipy.optimize import least_squares # ... and the relevant CMI packages @@ -25,12 +25,7 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser -try: - from bg_mpl_stylesheets.bg_mpl_stylesheet import bg_mpl_style - - plt.style.use(bg_mpl_style) -except ImportError: - pass +plt.style.use(all_styles["bg-style"]) # Config ############################## # 2: Give a file path to where your pdf (.gr) and (.cif) files are located. @@ -221,13 +216,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - if (PWD.parent.parent.parent / "utils" / "billinge.mplstyle").exists(): - plt.style.use( - str(PWD.parent.parent.parent / "utils" / "billinge.mplstyle") - ) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) From eb8cab3fa836c666fdc8ace5965d86f7ee4998c1 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 15:09:28 -0400 Subject: [PATCH 11/14] add bg stylesheets to requirments --- requirements/packs/plotting.txt | 1 + requirements/tests.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements/packs/plotting.txt b/requirements/packs/plotting.txt index 6b41443..6a968c8 100644 --- a/requirements/packs/plotting.txt +++ b/requirements/packs/plotting.txt @@ -1,4 +1,5 @@ ipywidgets matplotlib ipympl +bg-mpl-stylesheets py3dmol>=2.0.1 diff --git a/requirements/tests.txt b/requirements/tests.txt index ac9ed7e..a1092fb 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -9,3 +9,4 @@ pytest-mock freezegun DeepDiff psutil +bg-mpl-stylesheets From b77fb30216b0c561e929a715ce68e3e6e2074318 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 15:12:50 -0400 Subject: [PATCH 12/14] remove mpl defaults override --- .../ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py b/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py index e467803..bdacb52 100644 --- a/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py +++ b/docs/examples/ch08NPRefinement/solutions/diffpy-cmi/fitCdSeNP.py @@ -10,7 +10,6 @@ # 1: Import relevant system packages that we will need... from pathlib import Path -import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np from scipy.optimize import least_squares @@ -445,9 +444,6 @@ def plot_results(recipe, fig_name): # Calculate the residual (difference) array and offset it vertically. diff = g - gcalc + diffzero - # Change some style details of the plot - mpl.rcParams.update(mpl.rcParamsDefault) - # Create a figure and an axis on which to plot fig, ax1 = plt.subplots(1, 1) From 9b7c4c271f8489a0e99f12337c966602bcf7aa81 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 16:45:20 -0400 Subject: [PATCH 13/14] fix so fitbulkni runs first --- tests/test_examples.py | 45 +++++++----------------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/tests/test_examples.py b/tests/test_examples.py index 22b968c..8ce06f1 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -1,43 +1,12 @@ -import re import runpy -def get_instrument_params(res_file): - """Parse Qdamp and Qbroad from a .res file.""" - qdamp = qbroad = None - with open(res_file, "r") as f: - for line in f: - if line.startswith("Calib_Qbroad"): - qbroad = float(re.split(r"\s+", line.strip())[1]) - elif line.startswith("Calib_Qdamp"): - qdamp = float(re.split(r"\s+", line.strip())[1]) - return qdamp, qbroad - - def test_all_examples(tmp_examples): """Run all example scripts to ensure they execute without error.""" - # Run Ni example first to produce .res file - ni_script = list(tmp_examples.rglob("**/FitBulkNi.py"))[0] - runpy.run_path(str(ni_script), run_name="__main__") - res_file = ni_script.parent / "res" / "Fit_Ni_Bulk.res" - assert res_file.exists(), f"Ni results file not found: {res_file}" - - qdamp_i, qbroad_i = get_instrument_params(res_file) - pt_script = list(tmp_examples.rglob("**/fitNPPt.py"))[0] - refined_Ni_params = {"QDAMP_I": qdamp_i, "QBROAD_I": qbroad_i} - # run the NPPt script with the refined Ni params - runpy.run_path( - str(pt_script), run_name="__main__", init_globals=refined_Ni_params - ) - - # Run all other example scripts, patching the instrument values - all_scripts = list(tmp_examples.rglob("**/solutions/diffpy-cmi/*.py")) - scripts = [ - s for s in all_scripts if s.name not in ("fitBulkNi.py", "fitNPPt.py") - ] - for script_path in scripts: - print(f"Testing {script_path.relative_to(tmp_examples)}") - mod_globals = {"QDAMP_I": qdamp_i, "QBROAD_I": qbroad_i} - runpy.run_path( - str(script_path), run_name="__main__", init_globals=mod_globals - ) + scripts = list(tmp_examples.rglob("**/solutions/diffpy-cmi/*.py")) + # sort list so that fitBulkNi.py runs first + scripts.sort(key=lambda s: 0 if s.name == "fitBulkNi.py" else 1) + for script in scripts: + script_relative_path = script.relative_to(tmp_examples).as_posix() + print(f"Testing {script_relative_path}") + runpy.run_path(str(script), run_name="__main__") From b8822b21850d9562c10f3ccf3053d1fa8d7d0094 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 22 Sep 2025 20:23:16 -0400 Subject: [PATCH 14/14] remove posix --- tests/test_examples.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_examples.py b/tests/test_examples.py index 8ce06f1..96cd573 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -8,5 +8,6 @@ def test_all_examples(tmp_examples): scripts.sort(key=lambda s: 0 if s.name == "fitBulkNi.py" else 1) for script in scripts: script_relative_path = script.relative_to(tmp_examples).as_posix() + print("hello", script_relative_path) print(f"Testing {script_relative_path}") runpy.run_path(str(script), run_name="__main__")