From 3fc9e5abee29e63b0f51131cbd57df2ba5cff056 Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Mon, 4 Nov 2024 10:12:50 -0500 Subject: [PATCH 1/4] make mud an optional argument, add options for entering sample/energy/density/diameter so that we can compute muD for user --- src/diffpy/labpdfproc/labpdfprocapp.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/diffpy/labpdfproc/labpdfprocapp.py b/src/diffpy/labpdfproc/labpdfprocapp.py index d63af8f..dc9d31a 100644 --- a/src/diffpy/labpdfproc/labpdfprocapp.py +++ b/src/diffpy/labpdfproc/labpdfprocapp.py @@ -9,7 +9,7 @@ def get_args(override_cli_inputs=None): p = ArgumentParser() - p.add_argument("mud", help="Value of mu*D for your " "sample. Required.", type=float) + p.add_argument("mud", nargs="?", help="Value of mu*D for your sample.", default=None, type=float) p.add_argument( "input", nargs="+", @@ -126,9 +126,13 @@ def get_args(override_cli_inputs=None): p.add_argument( "-z", "--z-scan-file", - help="Path to the z-scan file to be loaded to determine the mu*D value", + help="Path to the z-scan file to be loaded to determine the mu*D value.", default=None, ) + p.add_argument("--sample", help="The chemical formula or name of your material.", default=None) + p.add_argument("--energy", help="The energy in eV", default=None, type=float) + p.add_argument("--density", help="The material density in gr/cm^3.", default=None, type=float) + p.add_argument("--diameter", help="The capillary diameter in mm.", default=None, type=float) args = p.parse_args(override_cli_inputs) return args From c537fe4199e217a84bfd228c990c4d30eecab9ba Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Mon, 4 Nov 2024 11:34:52 -0500 Subject: [PATCH 2/4] add option for user to enter mu and diameter separately --- src/diffpy/labpdfproc/labpdfprocapp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/diffpy/labpdfproc/labpdfprocapp.py b/src/diffpy/labpdfproc/labpdfprocapp.py index dc9d31a..6bb5d59 100644 --- a/src/diffpy/labpdfproc/labpdfprocapp.py +++ b/src/diffpy/labpdfproc/labpdfprocapp.py @@ -129,6 +129,7 @@ def get_args(override_cli_inputs=None): help="Path to the z-scan file to be loaded to determine the mu*D value.", default=None, ) + p.add_argument("--mu", help="The sample linear absorption coefficient.", default=None, type=float) p.add_argument("--sample", help="The chemical formula or name of your material.", default=None) p.add_argument("--energy", help="The energy in eV", default=None, type=float) p.add_argument("--density", help="The material density in gr/cm^3.", default=None, type=float) From bcff3873dd9e701b24bf12dd3f48758169e2054b Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Mon, 4 Nov 2024 11:48:25 -0500 Subject: [PATCH 3/4] add functions to compute muD from xraydb database --- src/diffpy/labpdfproc/tools.py | 52 ++++++++++++++++++++++++++++++++-- tests/test_tools.py | 38 +++++++++++++++++++++---- 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/src/diffpy/labpdfproc/tools.py b/src/diffpy/labpdfproc/tools.py index 02b5451..3e40790 100644 --- a/src/diffpy/labpdfproc/tools.py +++ b/src/diffpy/labpdfproc/tools.py @@ -1,6 +1,8 @@ import copy from pathlib import Path +from xraydb import material_mu + from diffpy.labpdfproc.mud_calculator import compute_mud from diffpy.utils.scattering_objects.diffraction_objects import QQUANTITIES, XQUANTITIES from diffpy.utils.tools import get_package_info, get_user_info @@ -158,9 +160,9 @@ def set_xtype(args): return args -def set_mud(args): +def set_mud_from_zscan_file(args): """ - Set the mud based on the given input arguments + Set the mud based on the given z-scan file Parameters ---------- @@ -180,6 +182,49 @@ def set_mud(args): return args +def set_mud_using_xraydb(args): + """ + Set the mud using xraydb, prompting for parameters if not provided by the user + + The function works in this way: + (1) if mu*D is provided, no further input is required, and any additional inputs are written to metadata. + (2) if mu*D is missing but mu is provided, prompt for diameter if missing and compute muD = mu * d. + (3) if neither is provided, prompt for sample name, energy, density, and diameter as needed, then compute muD. + Reference for the xraydb database: https://xraypy.github.io/XrayDB/python.html#xraydb.material_mu. + + Parameters + ---------- + args argparse.Namespace + the arguments from the parser + sample str + the chemical formula or name of material + energy float + the energy in eV + density float or None + material density in gr/cm^3 + diameter float + the capillary diameter in mm + + Returns + ------- + the updated args argparse.Namespace with mu*D + """ + + if args.mud: + return args + if args.mu: + args.diameter = args.diameter or float(input("Please enter the capillary diameter (mm): ").strip()) + args.mud = args.mu * args.diameter + return args + args.sample = args.sample or input("Please enter the chemical formula or name of material: ").strip() + args.energy = args.energy or float(input("Please enter the energy (eV): ").strip()) + args.density = args.density or float(input("Please enter material density (gr/cm^3): ").strip()) + args.diameter = args.diameter or float(input("Please enter the capillary diameter (mm): ").strip()) + args.mu = material_mu(args.sample, args.energy, density=args.density, kind="total") / 10 + args.mud = args.mu * args.diameter + return args + + def _load_key_value_pair(s): items = s.split("=") key = items[0].strip() @@ -281,7 +326,8 @@ def preprocessing_args(args): args.output_directory = set_output_directory(args) args = set_wavelength(args) args = set_xtype(args) - args = set_mud(args) + args = set_mud_from_zscan_file(args) + args = set_mud_using_xraydb(args) args = load_user_metadata(args) return args diff --git a/tests/test_tools.py b/tests/test_tools.py index f7c6425..e62675c 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -13,7 +13,8 @@ load_user_metadata, preprocessing_args, set_input_lists, - set_mud, + set_mud_from_zscan_file, + set_mud_using_xraydb, set_output_directory, set_wavelength, set_xtype, @@ -216,10 +217,10 @@ def test_set_xtype_bad(): actual_args = set_xtype(actual_args) -def test_set_mud(user_filesystem): +def test_set_mud_from_zscan_file(user_filesystem): cli_inputs = ["2.5", "data.xy"] actual_args = get_args(cli_inputs) - actual_args = set_mud(actual_args) + actual_args = set_mud_from_zscan_file(actual_args) assert actual_args.mud == pytest.approx(2.5, rel=1e-4, abs=0.1) assert actual_args.z_scan_file is None @@ -230,16 +231,41 @@ def test_set_mud(user_filesystem): expected = [3, str(test_dir / "testfile.xy")] cli_inputs = ["2.5", "data.xy"] + inputs actual_args = get_args(cli_inputs) - actual_args = set_mud(actual_args) + actual_args = set_mud_from_zscan_file(actual_args) assert actual_args.mud == pytest.approx(expected[0], rel=1e-4, abs=0.1) assert actual_args.z_scan_file == expected[1] -def test_set_mud_bad(): +def test_set_mud_from_zscan_file_bad(): cli_inputs = ["2.5", "data.xy", "--z-scan-file", "invalid file"] actual_args = get_args(cli_inputs) with pytest.raises(FileNotFoundError, match="Cannot find invalid file. Please specify a valid file path."): - actual_args = set_mud(actual_args) + actual_args = set_mud_from_zscan_file(actual_args) + + +params_mud = [ + # user specified mud + (["0.7952", "data.xy"], [""]), + # user specified mu but not mud + (["data.xy", "--mu", "1.2522", "--diameter", "0.635"], [""]), + (["data.xy", "--mu", "1.2522"], ["0.635"]), + # user did not specify mud or mu + (["data.xy"], ["ZrO2", "17445", "1.009", "0.635"]), + (["data.xy", "--energy", "17445", "--density", "1.009", "--diameter", "0.635"], ["ZrO2"]), + (["data.xy", "--sample", "ZrO2", "--density", "1.009", "--diameter", "0.635"], ["17445.362740959618"]), + (["data.xy", "--sample", "ZrO2", "--energy", "17445", "--diameter", "0.635"], ["1.009"]), + (["data.xy", "--sample", "ZrO2", "--energy", "17445", "--density", "1.009"], ["0.635"]), + (["data.xy", "--sample", "ZrO2", "--energy", "17445", "--density", "1.009", "--diameter", "0.635"], [""]), +] + + +@pytest.mark.parametrize("cli_inputs, user_inputs", params_mud) +def test_set_mud_using_xraydb(cli_inputs, user_inputs, monkeypatch): + inp_iter = iter(user_inputs) + monkeypatch.setattr("builtins.input", lambda _: next(inp_iter)) + actual_args = get_args(cli_inputs) + actual_args = set_mud_using_xraydb(actual_args) + assert actual_args.mud == pytest.approx(0.7952, rel=1e-4, abs=0.1) params5 = [ From 1127a0cc3d7e6db84988dc7c22850b06ceca6ee1 Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Wed, 6 Nov 2024 10:41:57 -0500 Subject: [PATCH 4/4] add news --- news/muD.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/muD.rst diff --git a/news/muD.rst b/news/muD.rst new file mode 100644 index 0000000..db21844 --- /dev/null +++ b/news/muD.rst @@ -0,0 +1,23 @@ +**Added:** + +* function to compute mu*D based on basic information provided + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +*