Skip to content

fix: theoretical muD estimation #189

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
10 changes: 3 additions & 7 deletions doc/source/examples/labpdfprocapp-example.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,16 @@ We will now continue using ``zro2_mo.xy`` as the example input throughout the re
labpdfproc zro2_mo.xy --mud 2.5
# Option 2: From a z-scan file
labpdfproc zro2_mo.xy -z zscan.xy
# Option 3: Using sample mass density
labpdfproc zro2_mo.xy -d ZrO2,17.45,1.2
# Option 4: Using packing fraction
labpdfproc zro2_mo.xy -p ZrO2,17.45,0.2
# Option 3: Theoretical estimation
labpdfproc zro2_mo.xy -t ZrO2,17.45,1.2,1.0
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

(Just realized that I forgot to write comments for where I changed, sorry) Here I removed the packing fraction option example


Note that you can only use one method at a time. The following examples are not allowed:

.. code-block:: python

labpdfproc zro2_mo.xy --mud 2.5 -z zscan.xy
labpdfproc zro2_mo.xy --mud 2.5 -d ZrO2,17.45,1.2
labpdfproc zro2_mo.xy --mud 2.5 -t ZrO2,17.45,1.2,1.0

If the packing fraction option is not supported at the moment, you can approximate the sample mass density as:
``mass density = packing fraction * material density``, where the material density can be looked up manually.


5. You can specify the wavelength in two ways:
Expand Down
6 changes: 2 additions & 4 deletions doc/source/examples/tools-example.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ You can do this in one of the following four ways:
args = Namespace(mud=2)
# Option 2: From a z-scan file
args = Namespace(z_scan_file="zscan.xy")
# Option 3: Using sample mass density
args = Namespace(theoretical_from_density="ZrO2,17.45,1.2")
# Option 4: Using packing fraction
args = Namespace(theoretical_from_packing="ZrO2,17.45,0.3")
# Option 3: Theoretical estimation
args = Namespace(theoretical_estimation="ZrO2,17.45,1.2,1.0")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Remove packing fraction

# Set and view the computed mu*D value
args = set_mud(args)
print(args.mud)
Expand Down
23 changes: 23 additions & 0 deletions news/remove-packing-fraction.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* no news added - corrected mu vs muD usage, removed packing fraction option for estimating muD, updated docs

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
40 changes: 13 additions & 27 deletions src/diffpy/labpdfproc/labpdfprocapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@
from diffpy.utils.diffraction_objects import XQUANTITIES, DiffractionObject
from diffpy.utils.parsers.loaddata import loadData

theoretical_mud_hmsg_suffix = (
"in that exact order, "
"separated by commas (e.g., ZrO2,17.45,0.5). "
"If you add whitespaces, "
"enclose it in quotes (e.g., 'ZrO2, 17.45, 0.5'). "
)


def _define_arguments():
args = [
Expand Down Expand Up @@ -163,45 +156,38 @@ def _add_mud_selection_group(p, is_gui=False):
1. Manually enter muD (`--mud`).
2. Estimate from a z-scan file (`-z` or `--z-scan-file`).
3. Estimate theoretically based on sample mass density
(`-d` or `--theoretical-from-density`).
4. Estimate theoretically based on packing fraction
(`-p` or `--theoretical-from-packing`).
(`-t` or `--theoretical-estimation`).
"""
g = p.add_argument_group("Options for setting mu*D value (Required)")
g = p.add_argument_group("Options for setting muD value (Required)")
g = g.add_mutually_exclusive_group(required=True)
g.add_argument(
"--mud",
type=float,
help="Enter the mu*D value manually.",
help="Enter the muD value manually.",
**({"widget": "DecimalField"} if is_gui else {}),
)
g.add_argument(
"-z",
"--z-scan-file",
help=(
"Estimate mu*D experimentally from a z-scan file. "
"Estimate muD experimentally from a z-scan file. "
"Specify the path to the file "
"used to compute the mu*D value."
),
**({"widget": "FileChooser"} if is_gui else {}),
)
g.add_argument(
"-d",
"--theoretical-from-density",
help=(
"Estimate mu*D theoretically using sample mass density. "
"Specify the chemical formula, incident x-ray energy (in keV), "
"and sample mass density (in g/cm^3), "
+ theoretical_mud_hmsg_suffix
),
)
g.add_argument(
"-p",
"--theoretical-from-packing",
"-t",
"--theoretical-estimation",
help=(
"Estimate mu*D theoretically using packing fraction. "
"Estimate muD theoretically. "
"Specify the chemical formula, incident x-ray energy (in keV), "
"and packing fraction (0 to 1), " + theoretical_mud_hmsg_suffix
"sample mass density (in g/cm^3), "
"and capillary diameter (in mm) "
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

add a requirement for specifying capillary diameter

"in that exact order, "
"separated by commas (e.g., ZrO2,17.45,0.5,1.0). "
"If you add whitespaces, "
"enclose it in quotes (e.g., 'ZrO2, 17.45, 0.5, 1.0'). "
),
)
return p
Expand Down
69 changes: 26 additions & 43 deletions src/diffpy/labpdfproc/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,15 @@

# Exclude wavelength to avoid duplication,
# as it's written explicitly by diffpy.utils dump function.
# Exclude "theoretical_from_density" and "theoretical_from_packing"
# as they are only used for theoretical mu*D estimation
# and will be written into separate arguments for clarity.
# Exclude "theoretical_estimation"
# as it will be written into separate arguments for clarity.
METADATA_KEYS_TO_EXCLUDE = [
"output_correction",
"force_overwrite",
"input",
"input_paths",
"wavelength",
"theoretical_from_density",
"theoretical_from_packing",
"theoretical_estimation",
]


Expand Down Expand Up @@ -320,49 +318,37 @@ def _set_mud_from_zscan(args):
def _parse_theoretical_input(input_str):
"""Helper function to parse and validate the input string."""
parts = [part.strip() for part in input_str.split(",")]
if len(parts) != 3:
if len(parts) != 4:
raise ValueError(
f"Invalid mu*D input '{input_str}'. "
f"Invalid muD input '{input_str}'. "
"Expected format is 'sample composition, energy, "
"sample mass density or packing fraction' "
"(e.g., 'ZrO2,17.45,0.5').",
"sample mass density, diameter' "
"(e.g., 'ZrO2,17.45,0.5,1.0').",
)
sample_composition = parts[0]
energy = float(parts[1])
mass_density_or_packing_fraction = float(parts[2])
return sample_composition, energy, mass_density_or_packing_fraction
sample_mass_density = float(parts[2])
diameter = float(parts[3])
return sample_composition, energy, sample_mass_density, diameter
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Again add capillary diameter



def _set_theoretical_mud_from_density(args):
def _set_theoretical_mud(args):
"""Theoretical estimation of mu*D from
sample composition, energy, and sample mass density."""
sample_composition, energy, sample_mass_density = _parse_theoretical_input(
args.theoretical_from_density
sample composition, energy, sample mass density, and capillary diameter"""
sample_composition, energy, sample_mass_density, diameter = (
_parse_theoretical_input(args.theoretical_estimation)
)
args.sample_composition = sample_composition
args.energy = energy
args.sample_mass_density = sample_mass_density
args.mud = compute_mu_using_xraydb(
args.sample_composition,
args.energy,
sample_mass_density=args.sample_mass_density,
)
return args


def _set_theoretical_mud_from_packing(args):
"""Theoretical estimation of mu*D from
sample composition, energy, and packing fraction."""
sample_composition, energy, packing_fraction = _parse_theoretical_input(
args.theoretical_from_packing
)
args.sample_composition = sample_composition
args.energy = energy
args.packing_fraction = packing_fraction
args.mud = compute_mu_using_xraydb(
args.sample_composition,
args.energy,
packing_fraction=args.packing_fraction,
args.diameter = diameter
args.mud = (
compute_mu_using_xraydb(
args.sample_composition,
args.energy,
sample_mass_density=args.sample_mass_density,
)
* args.diameter
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

muD = mu * D

)
return args

Expand All @@ -373,8 +359,7 @@ def set_mud(args):
Options include:
1. Manually entering a value.
2. Estimating from a z-scan file.
3. Estimating theoretically based on sample mass density.
4. Estimating theoretically based on packing fraction.
3. Estimating theoretically based on relevant chemical info.

Parameters
----------
Expand All @@ -384,14 +369,12 @@ def set_mud(args):
Returns
-------
args : argparse.Namespace
The updated arguments with mu*D.
The updated arguments with muD.
"""
if args.z_scan_file:
return _set_mud_from_zscan(args)
elif args.theoretical_from_density:
return _set_theoretical_mud_from_density(args)
elif args.theoretical_from_packing:
return _set_theoretical_mud_from_packing(args)
elif args.theoretical_estimation:
return _set_theoretical_mud(args)
return args


Expand Down
58 changes: 13 additions & 45 deletions tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,14 +461,10 @@ def test_set_xtype_bad():
# C2: user provides a z-scan file, expect to estimate through the file
(["--z-scan-file", "test_dir/testfile.xy"], 3),
# C3: user specifies sample composition, energy,
# and sample mass density,
# sample mass density, and diameter
# both with and without whitespaces, expect to estimate theoretically
(["--theoretical-from-density", "ZrO2,17.45,1.2"], 1.49),
(["--theoretical-from-density", "ZrO2, 17.45, 1.2"], 1.49),
# C4: user specifies sample composition, energy, and packing fraction
# both with and without whitespaces, expect to estimate theoretically
# (["--theoretical-from-packing", "ZrO2,17.45,0.3"], 1.49),
# (["--theoretical-from-packing", "ZrO2, 17.45, 0.3"], 1.49),
(["--theoretical-estimation", "ZrO2,17.45,1.2,1.0"], 1.49),
(["--theoretical-estimation", "ZrO2, 17.45, 1.2, 1.0"], 1.49),
],
)
def test_set_mud(user_filesystem, inputs, expected_mud):
Expand All @@ -492,56 +488,28 @@ def test_set_mud(user_filesystem, inputs, expected_mud):
"Cannot find invalid file. Please specify a valid file path.",
],
),
# C2.1: (sample mass density option)
# user provides fewer than three input values
# expect ValueError with a message indicating the correct format
(
["--theoretical-from-density", "ZrO2,0.5"],
[
ValueError,
"Invalid mu*D input 'ZrO2,0.5'. "
"Expected format is 'sample composition, energy, "
"sample mass density or packing fraction' "
"(e.g., 'ZrO2,17.45,0.5').",
],
),
# C2.2: (packing fraction option)
# user provides fewer than three input values
# expect ValueError with a message indicating the correct format
(
["--theoretical-from-packing", "ZrO2,0.5"],
[
ValueError,
"Invalid mu*D input 'ZrO2,0.5'. "
"Expected format is 'sample composition, energy, "
"sample mass density or packing fraction' "
"(e.g., 'ZrO2,17.45,0.5').",
],
),
# C3.1: (sample mass density option)
# user provides more than 3 input values
# C2: user provides fewer than 4 inputs for theoretical estimation,
# expect ValueError with a message indicating the correct format
(
["--theoretical-from-density", "ZrO2,17.45,1.5,0.5"],
["--theoretical-estimation", "ZrO2,0.5"],
[
ValueError,
"Invalid mu*D input 'ZrO2,17.45,1.5,0.5'. "
"Invalid muD input 'ZrO2,0.5'. "
"Expected format is 'sample composition, energy, "
"sample mass density or packing fraction' "
"(e.g., 'ZrO2,17.45,0.5').",
"sample mass density, diameter' "
"(e.g., 'ZrO2,17.45,0.5,1.0').",
],
),
# C3.2: (packing fraction option)
# user provides more than 3 input values
# C3: user provides more than 4 inputs for theoretical estimation,
# expect ValueError with a message indicating the correct format
(
["--theoretical-from-packing", "ZrO2,17.45,1.5,0.5"],
["--theoretical-estimation", "ZrO2,17.45,1.5,0.5,1.0"],
[
ValueError,
"Invalid mu*D input 'ZrO2,17.45,1.5,0.5'. "
"Invalid muD input 'ZrO2,17.45,1.5,0.5,1.0'. "
"Expected format is 'sample composition, energy, "
"sample mass density or packing fraction' "
"(e.g., 'ZrO2,17.45,0.5').",
"sample mass density, diameter' "
"(e.g., 'ZrO2,17.45,0.5,1.0').",
],
),
],
Expand Down
Loading