From f4dd476571ba623fe531712355f1d77bcd3f8683 Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Wed, 23 Apr 2025 15:20:48 -0400 Subject: [PATCH 1/4] feat: theoretical estimation of muD: functions and gui interface --- news/muD-theoretical.rst | 23 +++++++ src/diffpy/labpdfproc/labpdfprocapp.py | 41 ++++++++++-- src/diffpy/labpdfproc/tools.py | 91 ++++++++++++++++++++------ tests/test_tools.py | 56 +++++++++++++++- 4 files changed, 187 insertions(+), 24 deletions(-) create mode 100644 news/muD-theoretical.rst diff --git a/news/muD-theoretical.rst b/news/muD-theoretical.rst new file mode 100644 index 0000000..4fde53b --- /dev/null +++ b/news/muD-theoretical.rst @@ -0,0 +1,23 @@ +**Added:** + +* Functionalities to estimate mu*D theoretically. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/labpdfproc/labpdfprocapp.py b/src/diffpy/labpdfproc/labpdfprocapp.py index e469514..52b89a2 100644 --- a/src/diffpy/labpdfproc/labpdfprocapp.py +++ b/src/diffpy/labpdfproc/labpdfprocapp.py @@ -152,7 +152,11 @@ def _define_arguments(): def _add_mud_selection_group(p, is_gui=False): """Current Options: 1. Manually enter muD (`--mud`). - 2. Estimate muD from a z-scan file (`-z` or `--z-scan-file`). + 2. Estimate from a z-scan file (`-z` or `--z-scan-file`). + 3. Estimate theoretically based on sample mass density + (`-td` or `--theoretical-from-density`). + 4. Estimate theoretically based on packing fraction + (`-tp` or `--theoretical-from-packing`). """ g = p.add_argument_group("Options for setting mu*D value (Required)") g = g.add_mutually_exclusive_group(required=True) @@ -165,10 +169,39 @@ def _add_mud_selection_group(p, is_gui=False): g.add_argument( "-z", "--z-scan-file", - help="Provide the path to the z-scan file to be loaded " - "to determine the mu*D value.", + help=( + "Estimate mu*D 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( + "-td", + "--theoretical-from-density", + help=( + "Estimate mu*D theoretically using sample mass density. " + "Specify the sample composition (chemical formula), " + "incident x-ray energy in keV, " + "and sample mass density in g/cm^3 " + "in that exact order " + "and separated by commas with no whitespaces " + "(e.g., 'ZrO2,2,1.2')." + ), + ) + g.add_argument( + "-tp", + "--theoretical-from-packing", + help=( + "Estimate mu*D theoretically using packing fraction. " + "Specify the sample composition (chemical formula), " + "incident x-ray energy in keV, " + "and packing fraction (0 to 1) " + "in that exact order " + "and separated by commas with no whitespaces " + "(e.g., 'ZrO2,2,0.5')." + ), + ) return p @@ -186,7 +219,7 @@ def get_args(override_cli_inputs=None): return args -@Gooey(required_cols=1, optional_cols=1, program_name="Labpdfproc GUI") +@Gooey(required_cols=1, optional_cols=2, program_name="labpdfproc GUI") def gooey_parser(): p = GooeyParser() p = _add_mud_selection_group(p, is_gui=True) diff --git a/src/diffpy/labpdfproc/tools.py b/src/diffpy/labpdfproc/tools.py index ea5299d..8fc034f 100644 --- a/src/diffpy/labpdfproc/tools.py +++ b/src/diffpy/labpdfproc/tools.py @@ -9,6 +9,7 @@ from diffpy.utils.tools import ( _load_config, check_and_build_global_config, + compute_mu_using_xraydb, compute_mud, get_package_info, get_user_info, @@ -31,14 +32,19 @@ } known_sources = [key for key in WAVELENGTHS.keys()] -# Exclude wavelength from metadata to prevent duplication, -# as the dump function in diffpy.utils writes it explicitly. +# 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. METADATA_KEYS_TO_EXCLUDE = [ "output_correction", "force_overwrite", "input", "input_paths", "wavelength", + "theoretical_from_density", + "theoretical_from_packing", ] @@ -298,19 +304,8 @@ def set_xtype(args): return args -def _estimate_mud_from_zscan(args): - """Compute mu*D based on the given z-scan file. - - Parameters - ---------- - args : argparse.Namespace - The arguments from the parser. - - Returns - ------- - args : argparse.Namespace - The updated arguments with mu*D. - """ +def _set_mud_from_zscan(args): + """Experimental estimation of mu*D from a z-scan file.""" filepath = Path(args.z_scan_file).resolve() if not filepath.is_file(): raise FileNotFoundError( @@ -322,10 +317,64 @@ def _estimate_mud_from_zscan(args): return args +def _parse_theoretical_input(input_str): + """Helper function to parse and validate the input string.""" + parts = input_str.split(",") + if len(parts) != 3: + raise ValueError( + f"Invalid mu*D input '{input_str}'. " + "Expected format is 'sample composition, energy, " + "sample mass density or packing fraction' " + "with no whitespaces (e.g., 'ZrO2,2,0.8').", + ) + 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 + + +def _set_theoretical_mud_from_density(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 + ) + 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, + ) + return args + + def set_mud(args): - """Compute and set mu*D based on different options. - Current options include manually entering a value, - or estimating from a z-scan file. + """Compute and set mu*D based on the selected method. + + 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. Parameters ---------- @@ -338,7 +387,11 @@ def set_mud(args): The updated arguments with mu*D. """ if args.z_scan_file: - return _estimate_mud_from_zscan(args) + 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) return args diff --git a/tests/test_tools.py b/tests/test_tools.py index 9ccc4b3..831d96d 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -460,6 +460,12 @@ def test_set_xtype_bad(): (["--mud", "2.5"], 2.5), # 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, expect to estimate theoretically + (["--theoretical-from-density", "ZrO2,17.45,1.2"], 1.49), + # C4: user specifies sample composition, energy, and packing fraction + # expect to estimate theoretically + # (["--theoretical-from-packing", "ZrO2,17.45,0.3"], 1.49), ], ) def test_set_mud(user_filesystem, inputs, expected_mud): @@ -483,6 +489,54 @@ def test_set_mud(user_filesystem, inputs, expected_mud): "Cannot find invalid file. Please specify a valid file path.", ], ), + # C2.1: 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' " + "with no whitespaces (e.g., 'ZrO2,2,0.8').", + ], + ), + # C2.1: 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' " + "with no whitespaces (e.g., 'ZrO2,2,0.8').", + ], + ), + # C3.1: user provides more than 3 input values + # expect ValueError with a message indicating the correct format + ( + ["--theoretical-from-density", "ZrO2,1.5,1.5,0.5"], + [ + ValueError, + "Invalid mu*D input 'ZrO2,1.5,1.5,0.5'. " + "Expected format is 'sample composition, energy, " + "sample mass density or packing fraction' " + "with no whitespaces (e.g., 'ZrO2,2,0.8').", + ], + ), + # C3.2: user provides more than 3 input values + # expect ValueError with a message indicating the correct format + ( + ["--theoretical-from-packing", "ZrO2,1.5,1.5,0.5"], + [ + ValueError, + "Invalid mu*D input 'ZrO2,1.5,1.5,0.5'. " + "Expected format is 'sample composition, energy, " + "sample mass density or packing fraction' " + "with no whitespaces (e.g., 'ZrO2,2,0.8').", + ], + ), ], ) def test_set_mud_bad(user_filesystem, inputs, expected): @@ -491,7 +545,7 @@ def test_set_mud_bad(user_filesystem, inputs, expected): os.chdir(cwd) cli_inputs = ["data.xy"] + inputs actual_args = get_args(cli_inputs) - with pytest.raises(expected_error, match=expected_error_msg): + with pytest.raises(expected_error, match=re.escape(expected_error_msg)): actual_args = set_mud(actual_args) From 421c8de96efd70455b3843d217a75c27c31e5b6a Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Fri, 25 Apr 2025 14:31:58 -0400 Subject: [PATCH 2/4] feat: allow whitespace for muD options 3 and 4, slight tweak in help msg --- src/diffpy/labpdfproc/labpdfprocapp.py | 29 +++++++++++++------------- src/diffpy/labpdfproc/tools.py | 4 ++-- tests/test_tools.py | 27 +++++++++++++++--------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/diffpy/labpdfproc/labpdfprocapp.py b/src/diffpy/labpdfproc/labpdfprocapp.py index 52b89a2..0a6ed40 100644 --- a/src/diffpy/labpdfproc/labpdfprocapp.py +++ b/src/diffpy/labpdfproc/labpdfprocapp.py @@ -21,12 +21,13 @@ def _define_arguments(): "The filename(s) or folder(s) of the datafile(s) to load. " "Required.\n" "Supply a space-separated list of files or directories. " + "If a filename contains whitespace, enclose it in quotes. " "Long lists can be supplied, one per line, " "in a file with name file_list.txt. " "If one or more directory is provided, all valid " "data-files in that directory will be processed. " "Examples of valid inputs are 'file.xy', 'data/file.xy', " - "'file.xy, data/file.xy', " + "'file.xy data/file.xy', " "'.' (load everything in the current directory), " "'data' (load everything in the folder ./data), " "'data/file_list.txt' (load the list of files " @@ -177,29 +178,27 @@ def _add_mud_selection_group(p, is_gui=False): **({"widget": "FileChooser"} if is_gui else {}), ) g.add_argument( - "-td", + "-d", "--theoretical-from-density", help=( "Estimate mu*D theoretically using sample mass density. " - "Specify the sample composition (chemical formula), " - "incident x-ray energy in keV, " - "and sample mass density in g/cm^3 " - "in that exact order " - "and separated by commas with no whitespaces " - "(e.g., 'ZrO2,2,1.2')." + "Specify the chemical formula, incident x-ray energy (in keV), " + "and sample mass density (in g/cm^3), in that exact order, " + "separated by commas (e.g., ZrO2,20,1.5). " + "If you add whitespaces, " + "enclose it in quotes (e.g., 'ZrO2, 20, 1.5'). " ), ) g.add_argument( - "-tp", + "-p", "--theoretical-from-packing", help=( "Estimate mu*D theoretically using packing fraction. " - "Specify the sample composition (chemical formula), " - "incident x-ray energy in keV, " - "and packing fraction (0 to 1) " - "in that exact order " - "and separated by commas with no whitespaces " - "(e.g., 'ZrO2,2,0.5')." + "Specify the chemical formula, incident x-ray energy (in keV), " + "and packing fraction (0 to 1), in that exact order, " + "separated by commas (e.g., ZrO2,20,0.5). " + "If you add whitespaces, " + "enclose it in quotes (e.g., 'ZrO2, 20, 0.5'). " ), ) return p diff --git a/src/diffpy/labpdfproc/tools.py b/src/diffpy/labpdfproc/tools.py index 8fc034f..8bcec61 100644 --- a/src/diffpy/labpdfproc/tools.py +++ b/src/diffpy/labpdfproc/tools.py @@ -319,13 +319,13 @@ def _set_mud_from_zscan(args): def _parse_theoretical_input(input_str): """Helper function to parse and validate the input string.""" - parts = input_str.split(",") + parts = [part.strip() for part in input_str.split(",")] if len(parts) != 3: raise ValueError( f"Invalid mu*D input '{input_str}'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "with no whitespaces (e.g., 'ZrO2,2,0.8').", + "(e.g., 'ZrO2,20,0.8').", ) sample_composition = parts[0] energy = float(parts[1]) diff --git a/tests/test_tools.py b/tests/test_tools.py index 831d96d..61e5afa 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -461,11 +461,14 @@ 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, expect to estimate theoretically + # and sample mass density, + # 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 - # expect to estimate theoretically + # 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), ], ) def test_set_mud(user_filesystem, inputs, expected_mud): @@ -489,7 +492,8 @@ def test_set_mud(user_filesystem, inputs, expected_mud): "Cannot find invalid file. Please specify a valid file path.", ], ), - # C2.1: user provides fewer than three input values + # 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"], @@ -498,10 +502,11 @@ def test_set_mud(user_filesystem, inputs, expected_mud): "Invalid mu*D input 'ZrO2,0.5'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "with no whitespaces (e.g., 'ZrO2,2,0.8').", + "(e.g., 'ZrO2,20,0.8').", ], ), - # C2.1: user provides fewer than three input values + # 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"], @@ -510,10 +515,11 @@ def test_set_mud(user_filesystem, inputs, expected_mud): "Invalid mu*D input 'ZrO2,0.5'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "with no whitespaces (e.g., 'ZrO2,2,0.8').", + "(e.g., 'ZrO2,20,0.8').", ], ), - # C3.1: user provides more than 3 input values + # C3.1: (sample mass density option) + # user provides more than 3 input values # expect ValueError with a message indicating the correct format ( ["--theoretical-from-density", "ZrO2,1.5,1.5,0.5"], @@ -522,10 +528,11 @@ def test_set_mud(user_filesystem, inputs, expected_mud): "Invalid mu*D input 'ZrO2,1.5,1.5,0.5'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "with no whitespaces (e.g., 'ZrO2,2,0.8').", + "(e.g., 'ZrO2,20,0.8').", ], ), - # C3.2: user provides more than 3 input values + # C3.2: (packing fraction option) + # user provides more than 3 input values # expect ValueError with a message indicating the correct format ( ["--theoretical-from-packing", "ZrO2,1.5,1.5,0.5"], @@ -534,7 +541,7 @@ def test_set_mud(user_filesystem, inputs, expected_mud): "Invalid mu*D input 'ZrO2,1.5,1.5,0.5'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "with no whitespaces (e.g., 'ZrO2,2,0.8').", + "(e.g., 'ZrO2,20,0.8').", ], ), ], From 66cbc0cf60c876743efd562b768a36acc501ed6b Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Fri, 25 Apr 2025 14:35:54 -0400 Subject: [PATCH 3/4] fix: small fix in muD docstring --- src/diffpy/labpdfproc/labpdfprocapp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffpy/labpdfproc/labpdfprocapp.py b/src/diffpy/labpdfproc/labpdfprocapp.py index 0a6ed40..c9dd92d 100644 --- a/src/diffpy/labpdfproc/labpdfprocapp.py +++ b/src/diffpy/labpdfproc/labpdfprocapp.py @@ -155,9 +155,9 @@ 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 - (`-td` or `--theoretical-from-density`). + (`-d` or `--theoretical-from-density`). 4. Estimate theoretically based on packing fraction - (`-tp` or `--theoretical-from-packing`). + (`-p` or `--theoretical-from-packing`). """ g = p.add_argument_group("Options for setting mu*D value (Required)") g = g.add_mutually_exclusive_group(required=True) From f224f3cc3858c93cbf1859fb113b66cd912a3835 Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Mon, 28 Apr 2025 15:31:15 -0400 Subject: [PATCH 4/4] docs: edit input + mud help messages; replace test example with Mo energy --- src/diffpy/labpdfproc/labpdfprocapp.py | 21 ++++++++++++--------- src/diffpy/labpdfproc/tools.py | 2 +- tests/test_tools.py | 16 ++++++++-------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/diffpy/labpdfproc/labpdfprocapp.py b/src/diffpy/labpdfproc/labpdfprocapp.py index c9dd92d..9acfaaa 100644 --- a/src/diffpy/labpdfproc/labpdfprocapp.py +++ b/src/diffpy/labpdfproc/labpdfprocapp.py @@ -12,6 +12,13 @@ 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 = [ @@ -21,7 +28,8 @@ def _define_arguments(): "The filename(s) or folder(s) of the datafile(s) to load. " "Required.\n" "Supply a space-separated list of files or directories. " - "If a filename contains whitespace, enclose it in quotes. " + "Avoid spaces in filenames when possible; " + "if present, enclose the name in quotes. " "Long lists can be supplied, one per line, " "in a file with name file_list.txt. " "If one or more directory is provided, all valid " @@ -183,10 +191,8 @@ def _add_mud_selection_group(p, is_gui=False): 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), in that exact order, " - "separated by commas (e.g., ZrO2,20,1.5). " - "If you add whitespaces, " - "enclose it in quotes (e.g., 'ZrO2, 20, 1.5'). " + "and sample mass density (in g/cm^3), " + + theoretical_mud_hmsg_suffix ), ) g.add_argument( @@ -195,10 +201,7 @@ def _add_mud_selection_group(p, is_gui=False): help=( "Estimate mu*D theoretically using packing fraction. " "Specify the chemical formula, incident x-ray energy (in keV), " - "and packing fraction (0 to 1), in that exact order, " - "separated by commas (e.g., ZrO2,20,0.5). " - "If you add whitespaces, " - "enclose it in quotes (e.g., 'ZrO2, 20, 0.5'). " + "and packing fraction (0 to 1), " + theoretical_mud_hmsg_suffix ), ) return p diff --git a/src/diffpy/labpdfproc/tools.py b/src/diffpy/labpdfproc/tools.py index 8bcec61..82878b1 100644 --- a/src/diffpy/labpdfproc/tools.py +++ b/src/diffpy/labpdfproc/tools.py @@ -325,7 +325,7 @@ def _parse_theoretical_input(input_str): f"Invalid mu*D input '{input_str}'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "(e.g., 'ZrO2,20,0.8').", + "(e.g., 'ZrO2,17.45,0.5').", ) sample_composition = parts[0] energy = float(parts[1]) diff --git a/tests/test_tools.py b/tests/test_tools.py index 61e5afa..a007e8c 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -502,7 +502,7 @@ def test_set_mud(user_filesystem, inputs, expected_mud): "Invalid mu*D input 'ZrO2,0.5'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "(e.g., 'ZrO2,20,0.8').", + "(e.g., 'ZrO2,17.45,0.5').", ], ), # C2.2: (packing fraction option) @@ -515,33 +515,33 @@ def test_set_mud(user_filesystem, inputs, expected_mud): "Invalid mu*D input 'ZrO2,0.5'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "(e.g., 'ZrO2,20,0.8').", + "(e.g., 'ZrO2,17.45,0.5').", ], ), # C3.1: (sample mass density option) # user provides more than 3 input values # expect ValueError with a message indicating the correct format ( - ["--theoretical-from-density", "ZrO2,1.5,1.5,0.5"], + ["--theoretical-from-density", "ZrO2,17.45,1.5,0.5"], [ ValueError, - "Invalid mu*D input 'ZrO2,1.5,1.5,0.5'. " + "Invalid mu*D input 'ZrO2,17.45,1.5,0.5'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "(e.g., 'ZrO2,20,0.8').", + "(e.g., 'ZrO2,17.45,0.5').", ], ), # C3.2: (packing fraction option) # user provides more than 3 input values # expect ValueError with a message indicating the correct format ( - ["--theoretical-from-packing", "ZrO2,1.5,1.5,0.5"], + ["--theoretical-from-packing", "ZrO2,17.45,1.5,0.5"], [ ValueError, - "Invalid mu*D input 'ZrO2,1.5,1.5,0.5'. " + "Invalid mu*D input 'ZrO2,17.45,1.5,0.5'. " "Expected format is 'sample composition, energy, " "sample mass density or packing fraction' " - "(e.g., 'ZrO2,20,0.8').", + "(e.g., 'ZrO2,17.45,0.5').", ], ), ],