Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add xraydb function to compute muD #126

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions news/muD.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* function to compute mu*D based on basic information provided

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
9 changes: 7 additions & 2 deletions src/diffpy/labpdfproc/labpdfprocapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -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="+",
Expand Down Expand Up @@ -126,9 +126,14 @@ 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("--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)
p.add_argument("--diameter", help="The capillary diameter in mm.", default=None, type=float)
args = p.parse_args(override_cli_inputs)
return args

Expand Down
52 changes: 49 additions & 3 deletions src/diffpy/labpdfproc/tools.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
----------
Expand All @@ -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()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some input prompts because it might be easier to enter from here than from cli inputs.

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()
Expand Down Expand Up @@ -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)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I am thinking that during the pre-processing we first check for z-scan files and read muD from there. If there's no file /muD provided, we then proceed to ask for other information.

args = set_mud_using_xraydb(args)
args = load_user_metadata(args)
return args

Expand Down
38 changes: 32 additions & 6 deletions tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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

Expand All @@ -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 = [
Expand Down