From d2d63710b996b2afaaabb41affccdd8a5a7fda99 Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Wed, 23 Apr 2025 17:12:21 -0400 Subject: [PATCH 1/2] feat: initial commit on getmud module --- news/getmud.rst | 23 ++++++++++ src/diffpy/labpdfproc/getmud.py | 74 +++++++++++++++++++++++++++++++++ tests/test_getmud.py | 59 ++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 news/getmud.rst create mode 100644 src/diffpy/labpdfproc/getmud.py create mode 100644 tests/test_getmud.py diff --git a/news/getmud.rst b/news/getmud.rst new file mode 100644 index 0000000..24ce10b --- /dev/null +++ b/news/getmud.rst @@ -0,0 +1,23 @@ +**Added:** + +* Functionalities to estimate sample mass density or capillary diameter from muD and related chemical info. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/labpdfproc/getmud.py b/src/diffpy/labpdfproc/getmud.py new file mode 100644 index 0000000..76c032f --- /dev/null +++ b/src/diffpy/labpdfproc/getmud.py @@ -0,0 +1,74 @@ +import numpy as np +from scipy.optimize import newton + +from diffpy.utils.tools import compute_mu_using_xraydb + + +def estimate_mass_density(mud, diameter, sample_composition, energy): + """Estimate sample mass density (g/cm^3) from mu*D + using capillary diameter, sample composition, and energy. + + Parameters + ---------- + mud : float + The given product of attenuation coefficient mu + in mm^{-1} and capillary diameter in mm. + diameter : float + The given diameter of the sample capillary in mm. + sample_composition : str + The chemical formula of the material. + energy : float + The energy of the incident x-rays in keV. + + Returns + ------- + estimated_density : float + The estimated mass density of the packed powder/sample in g/cm^3. + """ + mu = mud / diameter + + def residual_density(density): + return np.abs( + compute_mu_using_xraydb( + sample_composition, energy, sample_mass_density=density + ) + - mu + ) + + estimated_density = newton(residual_density, x0=1.0, x1=10.0) + return estimated_density + + +def estimate_diameter( + mud, + sample_composition, + energy, + sample_mass_density=None, + packing_fraction=None, +): + """Estimate capillary diameter (mm) from mu*D and mu. + + Parameters + ---------- + mud : float + The given product of attenuation coefficient mu + in mm^{-1} and capillary diameter in mm. + sample_composition : str + The chemical formula of the material. + energy : float + The energy of the incident x-rays in keV. + sample_mass_density : float + The mass density of the packed powder/sample in g/cm^3. + packing_fraction : float, optional, Default is None + The fraction of sample in the capillary (between 0 and 1). + Specify either sample_mass_density or packing_fraction but not both. + + Returns + ------- + diameter : float + The given diameter of the sample capillary in mm. + """ + mu = compute_mu_using_xraydb( + sample_composition, energy, sample_mass_density, packing_fraction + ) + return mud / mu diff --git a/tests/test_getmud.py b/tests/test_getmud.py new file mode 100644 index 0000000..6a59101 --- /dev/null +++ b/tests/test_getmud.py @@ -0,0 +1,59 @@ +import pytest + +from diffpy.labpdfproc.getmud import estimate_diameter, estimate_mass_density + + +@pytest.mark.parametrize( + "inputs, expected_mass_density", + [ + ( + { + "mud": 2.0, + "diameter": 1.5, + "sample_composition": "ZrO2", + "energy": 20, + }, + 0.25, + ), + ], +) +def test_estimate_mass_density(inputs, expected_mass_density): + actual_mass_density = estimate_mass_density( + inputs["mud"], + inputs["diameter"], + inputs["sample_composition"], + inputs["energy"], + ) + assert actual_mass_density == pytest.approx( + expected_mass_density, rel=0.01, abs=0.1 + ) + + +@pytest.mark.parametrize( + "inputs, expected_diameter", + [ + ( # C1: user specifies a sample mass density + { + "mud": 2.0, + "sample_composition": "ZrO2", + "energy": 20, + "sample_mass_density": 0.25, + }, + 1.5, + ), + # ( # C2: user specifies a packing fraction + # { + # "mud": 2.0, + # "sample_composition": "ZrO2", + # "energy": 20, + # "packing_fraction": 0.3 + # }, + # 1.5 + # ), + ], +) +def test_estimate_diameter(inputs, expected_diameter): + actual_diameter = estimate_diameter(**inputs) + assert actual_diameter == pytest.approx( + expected_diameter, rel=0.01, abs=0.1 + ) From 0b7a0f0c3aa5c4dae7f698c17f8a9b38e3259b2b Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Fri, 2 May 2025 15:11:56 -0400 Subject: [PATCH 2/2] fix: edited docstring and test comments based on UC1-2 --- news/getmud.rst | 2 +- src/diffpy/labpdfproc/getmud.py | 7 ++++--- tests/test_getmud.py | 12 ++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/news/getmud.rst b/news/getmud.rst index 24ce10b..ff5330c 100644 --- a/news/getmud.rst +++ b/news/getmud.rst @@ -1,6 +1,6 @@ **Added:** -* Functionalities to estimate sample mass density or capillary diameter from muD and related chemical info. +* Functionalities to estimate sample mass density or capillary diameter from target muD and related chemical info. **Changed:** diff --git a/src/diffpy/labpdfproc/getmud.py b/src/diffpy/labpdfproc/getmud.py index 76c032f..09956ca 100644 --- a/src/diffpy/labpdfproc/getmud.py +++ b/src/diffpy/labpdfproc/getmud.py @@ -5,8 +5,8 @@ def estimate_mass_density(mud, diameter, sample_composition, energy): - """Estimate sample mass density (g/cm^3) from mu*D - using capillary diameter, sample composition, and energy. + """Estimate sample mass density (g/cm^3) from + muD, capillary diameter, sample composition, and energy. Parameters ---------- @@ -46,7 +46,8 @@ def estimate_diameter( sample_mass_density=None, packing_fraction=None, ): - """Estimate capillary diameter (mm) from mu*D and mu. + """Estimate capillary diameter (mm) from + muD, sample composition, energy, and mass density/packing fraction. Parameters ---------- diff --git a/tests/test_getmud.py b/tests/test_getmud.py index 6a59101..151e725 100644 --- a/tests/test_getmud.py +++ b/tests/test_getmud.py @@ -11,9 +11,9 @@ "mud": 2.0, "diameter": 1.5, "sample_composition": "ZrO2", - "energy": 20, + "energy": 17.45, # Mo K_alpha source }, - 0.25, + 1.0751, ), ], ) @@ -36,16 +36,16 @@ def test_estimate_mass_density(inputs, expected_mass_density): { "mud": 2.0, "sample_composition": "ZrO2", - "energy": 20, - "sample_mass_density": 0.25, + "energy": 17.45, + "sample_mass_density": 1.20, }, - 1.5, + 1.3439, ), # ( # C2: user specifies a packing fraction # { # "mud": 2.0, # "sample_composition": "ZrO2", - # "energy": 20, + # "energy": 17.45, # "packing_fraction": 0.3 # }, # 1.5