-
Notifications
You must be signed in to change notification settings - Fork 21
compute mu #278
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
compute mu #278
Changes from 8 commits
5180eeb
5ff2c23
1826221
e54f9bb
be7c275
9e4bc0d
1879f44
a108205
0bdbbb4
00f36ad
255c603
5492ad8
a4a217d
953e187
dd52ad9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
**Added:** | ||
|
||
* function to compute x-ray attenuation coefficient (mu) using XrayDB | ||
|
||
**Changed:** | ||
|
||
* <news item> | ||
|
||
**Deprecated:** | ||
|
||
* <news item> | ||
|
||
**Removed:** | ||
|
||
* <news item> | ||
|
||
**Fixed:** | ||
|
||
* <news item> | ||
|
||
**Security:** | ||
|
||
* <news item> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
numpy | ||
xraydb |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
numpy | ||
xraydb |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ | |
from copy import copy | ||
from pathlib import Path | ||
|
||
from xraydb import material_mu | ||
|
||
|
||
def clean_dict(obj): | ||
"""Remove keys from the dictionary where the corresponding value is None. | ||
|
@@ -206,3 +208,31 @@ def get_package_info(package_names, metadata=None): | |
pkg_info.update({package: importlib.metadata.version(package)}) | ||
metadata["package_info"] = pkg_info | ||
return metadata | ||
|
||
|
||
def compute_mu_using_xraydb(sample_composition, energy, density=None, packing_fraction=1): | ||
"""Compute the attenuation coefficient (mu) using the XrayDB database. | ||
|
||
Computes mu based on the sample composition and energy. | ||
User can provide a measured density or an estimated packing fraction. | ||
Specifying the density is recommended, though not required for some pure or standard materials. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. edit docstring There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think using xrayDB functionality here is not useful. The number of materials is so small, so there is no point to offer this to users as an option. It will just confuse them. We could offer other approaches:
|
||
Reference: https://xraypy.github.io/XrayDB/python.html#xraydb.material_mu. | ||
|
||
Parameters | ||
---------- | ||
sample_composition : str | ||
The chemical formula or the name of the material. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not the name, just chemical formula. |
||
energy : float | ||
The energy in keV. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change unit to keV There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "The energy of the incident x-rays in keV" |
||
density : float, optional, Default is None | ||
The mass density of the packed powder/sample in gr/cm^3. | ||
sbillinge marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. g/cm*3, not gr/cm^3 |
||
packing_fraction : float, optional, Default is 1 | ||
The fraction of sample in the capillary (between 0 and 1). | ||
sbillinge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Returns | ||
------- | ||
mu : float | ||
The attenuation coefficient mu in mm^{-1}. | ||
""" | ||
mu = material_mu(sample_composition, energy * 1000, density=density, kind="total") * packing_fraction / 10 | ||
return mu |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,12 @@ | |
|
||
import pytest | ||
|
||
from diffpy.utils.tools import check_and_build_global_config, get_package_info, get_user_info | ||
from diffpy.utils.tools import ( | ||
check_and_build_global_config, | ||
compute_mu_using_xraydb, | ||
get_package_info, | ||
get_user_info, | ||
) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
|
@@ -160,3 +165,65 @@ def test_get_package_info(monkeypatch, inputs, expected): | |
) | ||
actual_metadata = get_package_info(inputs[0], metadata=inputs[1]) | ||
assert actual_metadata == expected | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"inputs, expected_mu", | ||
[ | ||
# Test whether the function returns the correct mu | ||
sbillinge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
( # C1: No density or packing fraction (only for known material), expect to get mu from database | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "C1 composition and wavelength provided, known material. Expect to get mu for fully dense material" |
||
{ | ||
"sample_composition": "H2O", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. water is probably not a good "illustrative" choice. Maybe use quartz instead? |
||
"energy": 10, | ||
}, | ||
0.5330, | ||
), | ||
( # C2: Packing fraction (=0.5) provided only (only for known material) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reuse my pattern from C1 here. |
||
{ | ||
"sample_composition": "H2O", | ||
"energy": 10, | ||
"packing_fraction": 0.5, | ||
}, | ||
0.2665, | ||
), | ||
( # C3: Density provided only, expect to compute mu based on it | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reuse my pattern above. |
||
# 1. Known material | ||
{ | ||
"sample_composition": "H2O", | ||
"energy": 10, | ||
"density": 0.987, | ||
}, | ||
0.5330, | ||
), | ||
( # 2. Unknown material | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add unknown material for testing |
||
{ | ||
"sample_composition": "ZrO2", | ||
"energy": 17, | ||
"density": 1.009, | ||
}, | ||
1.252, | ||
), | ||
( # C4: Both density and packing fraction are provided, expect to compute mu based on both | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this doesn't make any sense. It will result in two numbers, not one number. We probably want to raise an exception if both are provided. |
||
# 1. Known material | ||
{ | ||
"sample_composition": "H2O", | ||
"energy": 10, | ||
"density": 0.997, | ||
"packing_fraction": 0.5, | ||
}, | ||
0.2665, | ||
), | ||
( # 2. Unknown material | ||
{ | ||
"sample_composition": "ZrO2", | ||
"energy": 17, | ||
"density": 1.009, | ||
"packing_fraction": 0.5, | ||
}, | ||
0.626, | ||
), | ||
], | ||
sbillinge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
def test_compute_mu_using_xraydb(inputs, expected_mu): | ||
actual_mu = compute_mu_using_xraydb(**inputs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is beautiful. thanks! @yucongalicechen |
||
assert actual_mu == pytest.approx(expected_mu, rel=0.01, abs=0.1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this seems a bit too loose? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added packing fraction. does this make sense or should we use None instead? I think if we set the default to 1 the code can be more concise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think setting to None is clearer here. The logic from the perspective of the user is that we either have a packing fraction or we don't. If it is None, you can set it to 1 in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, didn't we discuss to change the name to
sample_mass_density
?